Extending the Screen Saver Starter Kit with Microsoft Visual Basic Express
Visual Studio 2005 Express is the most comprehensive and full- featured interactive development environment (IDE) released to date. As part of the product mix, Microsoft has announced a series of Express editions, which make this power available to anyone for almost no investment. In this article, we'll explore the installation of one of the editions—Visual Basic—and then use one of the "Starter Kits" included with each Express edition to build and customise a screen saver.
Installing Visual Basic Express Edition
First, you'll need to install Visual Basic Express Edition (from now on, I'll just refer to it as Visual Basic Express). You can download it from the Visual Basic Express website.
- Run the vbsetup.exe file you downloaded from the Visual Basic Express site. After the installer has copied some setup files to your hard drive, you should see the screen shown in Figure 1. I'd strongly encourage you to check the box that allows the installer
to gather information and send it to Microsoft. This information is used to make the setup process as seamless as possible.
Figure 1: Initial screen for Visual Basic Express Edition Setup
- Click the Next button and you will see the End User License Agreement screen. Accept the agreement and click the Next button again.
- You're now at the screen that allows you to choose which of the optional components (in addition to Visual Basic Express) you want to install. If you've got the disk space (about 1.3 GB for the install process and about 500 MB once the install is complete and all of the temporaray installation files have been removed) spare, I'd encourage you to install both the MSDN Express Library 2005 and SQL Server 2005 Express Edition April CTP. The MSDN Express Library is the documentation (tailored for the Express editions) and SQL Server 2005 Express is the SQL Server engine (with a few limitations).
- Click the Next button and you'll be prompted for the installation path. Either accept the default or browse to choose another.
- Click the Next button and the install will begin. Progress will be displayed for each of the components to be installed as shown in Figure 2.
Figure 2: Setup is progressing
- Along the way, you may well be prompted to restart you machine. If it's not convenient to restart now, you can choose to restart later, but you will have to manually restart the setup process after doing so. If you choose to restart now, the setup process will continue seamlessly after you've logged back in.
- Once you've completed the setup process, you will be greeted with the screen shown in Figure 3. At some stage in the next 30 days you'll need to register your copy of Visual Basic Express and you can do it now by clicking on the link in the dialog or do
it later by choosing Product Activation from the help menu in Visual Basic Express. Either way, registering will give you free access to the online e-book,
Writing Secure Code 2nd ed. by Michael Howard and Davis LeBlanc.
Figure 3: Setup's done its thing. The rest is up to you.
- The final setup step is to start Visual Basic Express. Choose Start, All Programs, Visual Basic 2005 Express Edition.
Building a Screen Saver using the Starter Kit
All of the Visual Studio Express Editions come with one or more Starter Kits—pre-configured applications from which you can learn, and which you can adjust. Visual Basic Express comes with a Movie Database tracking application and a Screen Saver. These applications demonstrate best practices in coding and also showcase a number of the great new features in the language, the framework and the development environment. There are also a number of other starter kits being developed, both by Microsoft and by members of the developer community.
In this article we'll concentrate on the Screen Saver. First we'll explore the functionality that comes with the application as it ships, and then we'll make a couple of adjustments to personalize it and to demonstrate another very powerful feature: calling a web services.
Creating a new project
Click the New Project button on the main toolbar or choose File, New Project from the menu. In the dialog box, choose a name for your project (I've called mine mySS if you're typing along) and a location. Make sure you've selected the Screen Saver starter kit as shown in Figure 4.
Figure 4: Let's start at the very beginning (click image to zoom)
Visual Basic Express goes away and creates a new project based on the Screen Saver Starter Kit and then opens it in the IDE. The file that you see open is the documentation explaining how the application works and what to do to build and install it.
Building the screen saver
Press the F5 key to build and run the Screen Saver application. If you're connected to the Internet, you'll get an image (probably of a chess board) and a list of articles from the MSDN Visual Basic RSS feed. The currently highlighted article will have a description or précis displayed on the right-hand side of the screen.
Installing your creation to your desktop
To install your screen saver, follow the instructions in the documentation, that is:
- If you haven't already done so, load the Starter Kit into Visual Basic.
- On the File menu, click Save All.
- If you are requested to enter a location to save the project, select a directory or accept the default location. Make a note of where the project is saved; by default it will be in a directory under \My Documents\Visual Studio 2005\Projects.
- On the Build menu, click Build Solution. This creates an executable file for the screen saver.
- Open up the directory specified in step 3 containing the saved project.
- Open the bin subdirectory. You will see two files: ssNews.scr and ssNews.scr.config.
- Copy these two files to your Windows directory. If you are using Windows XP, this is \Windows\System32 in your system drive. If you are using Windows 2000, it is \WinNT\System32.
- Open Control Panel, click Appearance and Themes if using the Category View, and open the Display Properties dialog box.
- Click the Screen Saver tab.
- Click the Screen Saver drop-down list, and select News.
- Click the Preview button.
The screen saver launches. Press any key to stop it.
- Click the Settings button to see the screen saver options. Try changing the background image or the RSS feed.
- Click OK.
Make your Screen Saver do what you want it to do
It's all very well having the Screen Saver do what the designer of the Starter Kit wanted it to, but it's much more fun if you get it what you want it to do.
Getting images based on a keyword or at random
I decided that instead of picking up a set of images from a folder on my hard drive, I'd rather the screen saver selected a number of images from the web at random. I looked for a web service that would do this for me in the public directory of Web Services at Web Methods. I found one called getRandomGoogleSearch. This web service takes a single parameter (a string) and returns a URL pointing to an image related to that string. If the string passed is empty, it chooses a random English word and uses that as the seed word.
The other important piece of information (apart form the description of the functionality) in the directory is the URL of the Web Services Description Language (WSDL) for this service. This is the metatdata in XML format that tells an application calling the service all about what information is required and what's returned. In this case, the WSDL is at http://www.ghettodriveby.com/soap/?wsdl.
To get Visual Basic Express to be able to use this web service, right click on the references node in the Project Explorer pane and choose Add Web Reference. In the dialog, enter the WSDL URL and click the Go button. Once the WSDL has been retrieved, either accept the default name for the service or choose a new (possibly shorter) name. I chose GoogleImage.
Clicking the Add Reference button will generate all of the reference code to enable your application to treat the web service as just another component. This will all come together in a little while when I show you the code used to get the image.
Storing information between sessions
One of the things that's got significantly easier with Visual Studio 2005 is the persistence of settings and configuration between sessions of an application. In our case, we want to save the keyword for which images are retrieved and the total number of images we want to load into the screen saver cache.
To set up these settings, expand the Properties node in the Solution Explorer and double-click on the settings.settings file. You will see a grid with all of the settings like the one shown in Figure 5. Add a user-level
string setting called Keyword and leave its value blank. Add a user-level
int setting called
ImageCount and set its default value to 5.
Figure 5: Saving settings is easier than ever before (click image to zoom)
We now need to adjust the mechanism for the user to adjust and save these settings. In the Solution Explorer, double-click on the OptionsForm.vb file to open the options form in the designer. We'll leave the top half of the form alone—we're not changing the RSS reader functionality. Down at the bottom, though, we'll need to change the panel's caption, as well as the caption for the TextBox to reflect its new functionality as a keyword, rather than a path holder. Finally (from a UI point of view), we need to add a control to adjust the image count. The other thing that needs to happen on this form is that we need to get rid of the two controls at the bottom used for selecting a folder.
Let's do this in reverse order. Deleting the folder controls is easy. Click on them to select them and press the delete key. They're gone. Drag a label onto the form below the TextBox and change its
text property to
ImageCount. Below the label, place a numeric UpDown control and change its name to something more meaningful than the default. I chose
ImageCountUpDown. Notice that as you drag controls around, guides appear helping you align controls. Change the text label above the TextBox to Background image keyword. You should end up with something that looks a bit like Figure 6.
Figure 6: UI Changes for the Options Dialog
Now it's time to adjust the code that's used to save the settings. Right-click on the form and choose View Code. The first thing we want to do is rename the textbox that used to be called
backgroundImageFolderTextBox. Locate the line of code in the OptionsForm() constructor that reads:
backgroundImageKeywordTextBox.Text = Settings.[Default].Keyword
and right-click on the name of the TextBox. Choose Refactor, Rename. In the dialog, change the name to
backgroundImageKeywordTextBox. Click OK and then OK again in the preview changes dialog. Changing the name of the control in this way will update all the references to the control including in the auto- generated designer code.
When the form loads, the values that are currently set are used to populate the controls on the form. Change the code in the constructor method (called OptionsForm()) to:
backgroundImageKeywordTextBox.Text = Settings.[Default].Keyword
ImageCountUpDown.Value = Settings.[Default].ImageCount
rssFeedTextBox.Text = Settings.[Default].RssFeedUri
Notice how we can just use the Properties.Settings.Default construct to get at the settings. The type and value of the setting is taken care of automatically for us.
Now update the UpdateApply and ApplyChanges methods to read:
' Update the apply button to be active only if changes
' have been made since apply was last pressed
Private Sub UpdateApply()
If Settings.[Default].Keyword <> backgroundImageKeywordTextBox.Text OrElse _
Settings.[Default].ImageCount <> ImageCountUpDown.Value OrElse _
Settings.[Default].RssFeedUri <> rssFeedTextBox.Text Then
applyButton.Enabled = True
applyButton.Enabled = False
' Apply all the changes since apply button was last pressed
Private Sub ApplyChanges()
Settings.[Default].Keyword = backgroundImageKeywordTextBox.Text
Settings.[Default].ImageCount = CInt(ImageCountUpDown.Value)
Settings.[Default].RssFeedUri = rssFeedTextBox.Text
Note that I had to cast the value from the UpDown control from its native
Decimal to an
int to save it back to the
Finally, we need to add a handler to the ValueChanged event for the UpDown control so we can enable the Apply button when the value changes. Go back to the designer view for the options form and select the UpDown control. In the properties window, click on the Events button (the yellow bolt of lightning) and then doube-click on ValueChanged. All of the wiring will be hooked up to handle the event, you just need to add the call to the UpdateApply method in the event handling method.
Private Sub ImageCountUpDown_ValueChanged(ByVal sender As Object, _
ByVal e As EventArgs) Handles ImageCountUpDown.ValueChanged
That's it: all the heavy lifting has been done by the .NET Framework.
Loading images for each keyword
Now that we've updated the options dialog, it's time to move onto the form that displays the screen saver itself. This form works by loading images into a list when it starts up and cycling through those images while the screen saver is active. We're not going to change the structure of the screen saver very much. We're just going to change the way it loads images so that, instead of getting them from a folder on the local disk, it gets them from the Internet.
In the Solution Explorer, right-click on ScreenSaverForm.vb and choose View Code. Choose LoadBackGroundImage from the drop-down box on the right-hand side of the code window. This will take you to the code for this method. This is the only method we need to change on this form.
Since we're not loading images from folders, I've done away with the code calling the
LoadImagesFromFolder method (as well as the method itself). I then declare a local variable to hold the
imageURL returned from the call to the web service. Next, because calling over the web is fraught with uncertainty, I wrap the next block of code in a
try...catch block to handle any exceptions that might occur.
Creating an instance of the object that will call the web service is very straightforward: just declare a local variable and assign a new GoogleImage.RandomGoogleSearchService object to it. While I'm about it I create a WebClient object that I'll use to go out to the web and grab the image itself (the web service only returns a URL, not the binary data that makes up the image).
Next I loop until I've got as many images loaded as the user has asked for in the settings, and each time I call the web service. Note that the web service actually returns a data object with two properties:
image (the image URL) and
word (the word used to select the image).
If the image URL isn't empty, I try looking it up and retrieving the binary data. If successful, I create an image object from the stream of bits and add that image to the list of background images.
Finally, if, for some reason, no images were loaded, I call the LoadDefaultBackgroundImages method that was pat of the original application. The full code listing for the updated method is shown below.
Private Sub LoadBackgroundImage()
' Initialize the background images.
backgroundImages = New List(Of Image)()
currentImageIndex = 0
Dim imageURL As String
Dim oWS As GoogleImage.RandomGoogleSearchService = _
Dim webClient As System.Net.WebClient = New System.Net.WebClient()
While backgroundImages.Count < Settings.[Default].ImageCount
' call the web service to look up a random image
imageURL = oWS.getRandomGoogleSearch(Settings.[Default].Keyword).image
If imageURL <> String.Empty Then
Using imageStream As Stream = webClient.OpenRead(imageURL)
Dim image As Image = Drawing.Image.FromStream(imageStream)
Catch generatedExceptionName As System.Net.WebException
' probably a 404 (not found error);
Catch generatedExceptionName As Exception
' ignore any other exceptions and get on with the images
' If no images were loaded, load the defaults
If backgroundImages.Count = 0 Then
That's it! We've finished tweaking the screen saver. Press F5 and check that it runs. Follow the instructions in the section above to put it into your list of Windows Screen Savers.
You may have noticed one or two things that could be done better here. Why, for example, have an image count at all; why not just grab an image form the Internet each time you need a new one? The form seems to take a long time to load. Perhaps loading a single image and displaying that while you load the others in the background would be better. Wouldn't it be nice to display the word that was used to retrieve the image at the same time that the image is displayed? I'm sure you can think of some others.
Well, what are you waiting for? Make changes, try stuff, delve into the window paint code. Above all have fun.
The Visual Studio Express Editions put the power of the .NET Framework in to the hands of just about anyone. The starter kits that come with the Express Editions are great place to, well, start. There's a wealth of information both in the product itself and online. There's never been a better time to get into writing powerful and dynamic Windows applications and web sites.