In the previous post, Exploring the GrabAPicture Application (Part 9), I discussed the command line interface for the GrabAPicture application. This week we begin looking at the GUI controls for frmMain, which is the first form the user sees. Here’s how this form appears when you’re using it.
It’s important to analyze the functionality of this interface. You can divide the tasks that it performs into the following areas:
- Dialog Box Management (dialog box configuration and Close button)
- Direct Wallpaper Access (Wallpaper Location text box, radio buttons in the Style Selection group, and Set Value button)
- Wallpaper Database Access (Random Sources button)
- Command Line Interface Configuration (Use Random Local Sources and Use Random Remote Sources check boxes)
It’s helpful to perform such an analysis of any interface you design. Doing so makes it possible to look for ways to make the application more efficient (by reducing the number of controls when possible) and easier to use (by placing some controls on another form). Theoretically, you could make this application more efficient by making the Command Line Interface Configuration part of the command line interface. Likewise, you could make it easier to use by placing the Direct Wallpaper Access controls on a separate form. However, the form is relatively simple as is and most people won’t have trouble using it. This post discusses all four areas in the order shown.
Dialog Box Management
Part of the dialog box management task is to configure the form when you first start the application. This application, like most applications out there, uses the Load event to perform the task. In this case, it means using the frmMain_Load() handler shown here.
The code begins by creating a global GrabAPictureSettings object, CurrentSettings, that contains the content of the user’s wallpaper database. Normally, I prefer not to use global variables because they’re prone to all sorts of problems, especially when the code your working with could be multithreaded (reentrancy problems are extremely tough to debug). However, using the global variable in this case shouldn’t be a problem.
The frmMain_Load() method begins by creating creating a WinWallpaper object, Wallpaper. The reason you must create this variable every time you need it is because external applications can indeed change the wallpaper. If you didn’t create these variable every time, the user could end up using old information. Admittedly, this wouldn’t be much of a problem when it comes to wallpaper, but it’s good practice to follow in every application where an external application could affect your application’s data. The code then uses Wallpaper to set the Wallpaper Location and Style Selection settings of the application.
At this point, the code instantiates CurrentSettings. You know from the Exploring the GrabAPicture Application (Part 8) post that the LoadSettings() method returns Nothing when the user hasn’t saved any settings before, which is always the case when the user starts the application for the first time. This code checks whether CurrentSettings is Nothing after the LoadSettings() call. If so, the application creates an entirely new GrabAPictureSettings object. Otherwise, it uses the existing settings to configure the Use Random Local Sources and Use Random Remote Sources check boxes.
The configuration process is complete. The only remaining task is to provide a means of ending the application. Clicking Close, which is btnCancel, performs this task. Here is the code used to accomplish this task.
Notice that this application doesn’t simply close the form. Instead, it calls Environment.Exit() with an ending value of DialogResult.Cancel. The purpose for this approach is that GrabAPicture is designed for use in a batch file. Any batch file you create can rely on the ErrorLevel value to detect how the application exited (see my Understanding the Connection Between Application Output and ErrorLevel post for details), so you must provide a value to detect. It’s good practice not to simply close the form anyway—you should always provide some sort of exit value.
Direct Wallpaper Access
This application provides the means for the user to simply type the full path to a piece of wallpaper, set the style, and then click Set Value to use it. In short, the user could decide not to use any of the random option at all. There is a command line interface feature to allow the user to work this way as well. Here is the code used to provide direct wallpaper access.
Each of the check box event handlers performs essentially the same task. They set the Wallpaper.Style property to the appropriate Wallpaper.Styles value. A possible enhancement to these event handlers would be to force them to make the change automatically. The user still has to click Set Value to make the change. After testing this example out with a few willing volunteers, I found it was less confusing if the application waited for the user to click Set Value, rather than have the change occur automatically. The strategy you pursue will likely depend on your users and the complexity of the application you create.
Clicking Set Value calls the btnOK_Click() event handler. In this case, the code performs a conversion of the text the user types into Wallpaper Location to a Uri object. This is the first potential source of an exception. If the text doesn’t form a useful URI, then the application generates a UriFormatException. The assignment could possibly generate other exceptions, so the code adds a general exception handler as well. The act of making the assignment changes the Desktop wallpaper.
This example used to close the dialog box automatically after the user clicked Set Value. A few testers complained about this practice—preferring to experiment with the wallpaper. Consequently, the current version of the example has this piece of code commented out. If you choose to enable the old method of doing things, you’ll want to note that the application will exit with a value of DialogResult.OK in this case, which you can easily trap using the ErrorLevel value in a batch file.
Wallpaper Database Access
Wallpaper database configuration is performed using a combination of frmConfigure (to display the database content) and frmAddEdit (to make changes). When the user clicks Random Sources, the application calls btnConfigure_Click(). This event handler displays frmConfigure so that the user can see the list of configured wallpapers and make changes to the list. The following code shows how to perform this task.
The first part of this code looks like any dialog box display code you’ve used in the past. The example creates a frmConfigure object, Config. It then calls the Config.ShowDialog() method to display the dialog box with the current dialog box as the parent. A lot of developers create subordinate dialog boxes without the proper parent, which makes the application behave incorrectly. Always assign a parent to a subordinate dialog box when the subordinate should be dismissed before going back to the parent.
On return, the user has supposedly made changes to the wallpaper database. With this in mind, the application updates CurrentSettings to match the new wallpaper list. In addition, the wallpaper itself may have changed, so the application updates the wallpaper settings as well. The last bit of code may seem confusing at first, but think about it for a minute. The user might have deleted the last wallpaper entry from the list. If this is the case, the application needs to set CurrentSettings to a new instance of GrabAPictureSettings.
Command Line Interface Configuration
The final task for frmMain is at hand. The application needs some method of configuring the command line interface to use the correct random settings. The Use Random Local Settings and Use Random Remote Settings check boxes perform the task. Here is the code for the associated event handlers.
As you can see, the application sets the correct CurrentSettings property, and then calls GrabAPictureSettings.SaveSettings() with the CurrentSettings object as an argument to save the settings to disk. The result is a change to the user’s disk-based XML settings. A side effect of this process is that the user’s wallpaper list is also saved to disk. The SaveSettings() method saves all of the settings at one time.
Well, that’s it for frmMain. The next post will look at frmConfigure. Until that time, please let me know if you have any questions at John@JohnMuellerBooks.com. You can find the next post in this series at Exploring the GrabAPicture Application (Part 11).