Extending the Screen Saver Starter Kit with Microsoft Visual Basic Express
- Posted: Nov 07, 2006 at 3:54 AM
- 508 Views
- 4 Comments
Loading User Information from Channel 9
Something went wrong getting user information from Channel 9
Loading User Information from MSDN
Something went wrong getting user information from MSDN
Loading Visual Studio Achievements
Something went wrong getting the Visual Studio Achievements
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.
Figure 1: Initial screen for Visual Basic Express Edition Setup
Figure 2: Setup is progressing
Figure 3: Setup's done its thing. The rest is up to you.
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:
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.