Anatomy of a Resource Block
For every resource, you need to supply three pieces of information: the resource type, the resource ID, and the resource data. This gets a little confusing because each can be specified in various ways.
The resource type can be either a predefined type or a type you define. In the sample you just saw, BITMAP, ICON, CURSOR, and STRINGTABLE are predefined resource types. Both Visual Basic and Windows know about these types and include functions and constants to handle them directly. WAVE and OUR-DATA are custom types for which you must write your own functions.
To access bitmaps, icons, and cursors in Visual Basic, you use the LoadResPicture function. Assume that your resource file has this resource definition:
//$ Const ordAppIcon = 301
#if defined(US)
301 ICON “FLGUSA.ICO”
#elif defined(SW)
301 ICON “FLGSWI.ICO”
#endif
Your Visual Basic source file should define the following constant (or an equivalent Enum):
Public Const ordAppIcon = 301
You can then load the resource as shown here:
Me.Icon = LoadResPicture(ordAppIcon, vbResIcon)
To access string resources, use LoadResString. Assume that your string table in the resource script looks like this:
STRINGTABLE
BEGIN
#if defined(US)
1001 “Test Resources”
1101 “&File”
1102 “&Grunt”
§
You can load a string resource as shown here:
mnuFile.Caption = LoadResString(ordMnuFile)
To access custom data, use LoadResData. Assume that your custom WAVE resource looks like the code shown here.
//$ Const ordWavGrunt = 501
#if defined(US)
501 WAVE “GRUNT.WAV”
#elif defined(SW)
501 WAVE “OINK.WAV”
#endif
You can load this resource into an array of bytes, as shown here:
abWavGrunt = LoadResData(ordWavGrunt, “WAVE”)
Custom data always comes back as an array of bytes, so you’ll need a playwave function that processes bytes. We’ll see one in “Using Sounds” later in this
chapter.
Cursors Eat Mouse Icons for Lunch
Visual Basic calls them mouse icons. Windows calls them cursors (not to be confused with carets, the pointers in text boxes). Visual Basic programmers complained for years (until version 4) about Visual Basic’s inability to set them. Visual Basic now lets you set cursors to your favorite shapes, although this new feature isn’t as obvious as it seems.
You can load either cursors or icons into the MouseIcon property, but there’s a big difference between them. In fact, their relationship is an artificial one, created by Visual Basic for your convenience. Since icons are so easy to come by and are usually the same size as cursors, Visual Basic provides a shortcut: it automatically converts icons to cursors. But you might not like the price.
Most icons in the Visual Basic icon library (or anywhere else) are in color, but you’ll often find that color isn’t appropriate for cursors. Furthermore, most icons are designed as—well, as icons, and they don’t really fit as cursors. In addition, you have no control over the cursor hot spot when you use an icon. If your cursor is shaped like a pencil, you’ll want the hot spot at its point. But if you load a pencil-shaped icon, the hot spot will be in the center. If you click on something small, you might not be selecting what you think you’re selecting.
The moral: use cursors instead of icons. Visual Basic provides many of the standard ones if you request them during setup. You can also create your own cursors with ImagEdit, the graphics editor provided in the \Tools\ImagEdit
directory. ImagEdit lets you create color or monochrome cursors and set their hot spots. If you really want to use an icon, load it into ImagEdit, copy it, paste the image into a new cursor, and set the hot spot wherever you want it.
There’s only one problem with cursors: the Visual Basic IDE doesn’t recognize color cursors, even in 32-bit mode. That’s the fault of the Picture object, which has been jury-rigged to handle cursors in the MouseIcon property even though it wasn’t designed for them. The only way to get a color cursor when running in the environment is to use an icon. You can get color cursors in your 32-bit EXE files, however, if you can live with a little inconvenience during development. Just load your color cursors from resources instead of files. They’ll come out in black and white (often with ugly dithering) in the environment, but they’ll have the right colors when loaded in the EXE. This isn’t so bad, since few customers will ever see your program running in the IDE.
Why do resources work in an EXE but not in the IDE? In an EXE, resources are loaded using the standard Windows resource mechanism that we’ll examine later in this chapter. Color cursors work fine. Visual Basic can’t use this normal mechanism when running in the environment because you aren’t really running your program; you’re running Visual Basic. Instead, Visual Basic has to dig the resource data directly out of the RES file. This results in the same limitation that you’ll encounter with cursors that are placed directly into the MouseIcon property by using the LoadPicture function or the Load Picture dialog box: the colors get lost.
For each resource, you need to assign an ID string or number. The sample resource script uses ID numbers with a constant defined for each. You can also define ID strings. In the resource script, you could write the following definition:
AppBmp BITMAP “MANHEAD.BMP”
On the Visual Basic side, you can load it this way:
imgMascot.Picture = LoadResPicture(“AppBmp”, vbResBitMap)
This technique works for all resources except strings, which can be identified only by ID number. Because ID strings take more data space than ID numbers, you should avoid overusing ID strings for projects that contain many resources.
You can provide the name of a file containing the data on the same line as the ID and the type, or you can provide the actual data in a BEGIN/END block on subsequent lines. Microsoft’s resource script language has its share of quirks, but you get the idea. For resource script arcana, see the MSDN CD provided with Visual Basic.