Working with Icons in Visual Basicby Ron Petrusha
The presence of icons to represent either running or launchable applications is one of the features that differentiates a graphical operating system from a nongraphical one. It's also a feature that users come to value: The effective use of icons makes it easier to find an application on the desktop, to identify a minimized application on the status bar, and to locate an application on the Start menu. In this article, we'll look at the ways Visual Basic allows you to work with icons.
Icons in Windows
Windows icons can be of two types. One is a simple icon of a standard size and a particular number of colors. The varieties are 16 by 16 pixels and 16 colors, 32 by 32 pixels and 16 colors, and 48 by 48 pixels and 256 colors. The second icon type defines a single icon in multiple formats (sizes and colors), which allows the operating system to extract the icon in the appropriate size. When an icon is available in multiple formats, the operating system decides which format most closely meets its needs. It then loads that icon and reduces or enlarges it as needed.
The operating system itself is capable of using an icon in four different general formats:
The icon displayed on the window's caption bar. Its size can be controlled by modifying the size of the window title bar in the Appearances tab of the Display Properties dialog box.
The icon displayed in the system's Alt-Tab dialog box that lists the icons of running applications. It is also used by applications. Its size is defined by the video driver and cannot be altered.
The icon displayed in Explorer windows, common dialog boxes like File Open and File Save, the Applications tab of Windows Task Manager, and possibly the Start menu. Currently, Windows is configured to use the System Small icon as the Shell Small icon.
The icon displayed on the desktop and possibly on the Start menu. Its size is defined by the Shell Icon Size value of the HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics Registry key.
Icons can exist in stand-alone icon files, which typically have a file extension of .ico. VB and Visual Studio come with a large number of icon files, which are found in the Common\Graphics\Icons subdirectory of the directory in which Visual Studio (or Visual Basic) is installed. Icons are also included as resources in executable files and dynamic link libraries. For more details, see the Extracting Windows Icons section.
Assigning an .ico File
The most straightforward way to give your application an icon is to assign an icon (.ico) file to the Icon property of one of its forms at design time. If you assign icons to multiple forms, you can designate the form that contains the application icon by selecting it in the Make tab of the Project Properties dialog box.
When you assign an icon to the Icon property, Visual Basic generates an .frx file, which contains data about binary properties of the form and its controls. The icon that is assigned to the form's Icon property is then assigned a label and stored inside the .frx file. This is apparent if we examine Figure 1, which shows FRX Split, a shareware .frx file analysis and extraction utility.
Figure 1. A view of an .frx file from FRX Split
Once this happens, Visual Basic no longer needs your icon file. Instead, when it needs to retrieve the icon, it extracts it from the icon file rather than loading the file itself. When you compile, the .frx file is used to generate the executable, rather than the icon file. And as Figure 2 shows, the icon file is not included with the other project files as part of the setup routine.
Figure 2. Files included by the Package and Deployment Wizard
The ability to assign an icon at design time is useful if we know in advance what icon we want to assign to a form and to our application as a whole. But what if we don't know this information at design time? Or what if we want our icon to represent the state of the application as well as the application itself? The Recycle Bin, for instance, uses a wastebasket icon to represent the application. But when the Recycle Bin holds one or more deleted files, an overflowing wastebasket icon is used. When it is empty, an empty wastebasket icon is used. The icon conveys not only the application, but also its state. It would seem that we should be able to do this at runtime with code like the following:
Private Sub Form_Load() Me.Icon = "icon02.ico" End Sub
However, this code generates a type mismatch. The reason is that a form's
Icon property is of type
IPictureDisp rather than
String; Visual Basic expects the property to be assigned an image, not the name of an icon file. Instead, we can use the
LoadPicture function to load our icon dynamically. If we test the following code in the design-time environment, we find that it works as expected:
Private Sub Form_Load() Dim strPath As String strPath = App.Path & "\icon02.ico" Me.Icon = LoadPicture(strPath) End Sub
Because we're assigning an icon at runtime, Visual Basic does not generate a binary form (.frx) file. If we compile the application and run it in the same directory, it works just fine. However, if we move the application to a different directory but fail to move our icon file, the application generates a File Not Found error. Similarly, if we build an installation routine using the Package and Deployment Wizard, we have to add the icon file, icon02.ico, to the set of installation files, or a runtime error results.
As long as you actually remember to do it, the need to include separate icon files is just a minor annoyance. The possibility that a user of your application might inadvertently delete the file, thereby causing the application to crash, is a more serious issue. Rather than providing stand-alone icon files, it's clearly preferable to include icons either in the executable itself or in DLLs.