How to Create and Use Resources in Visual Basic 6

woman typing on computer
Public domain

After Visual Basic students learn all about loops and conditional statements and subroutines and so forth, one of the next things that they often ask about is, "How do I add a bitmap, a wav file, a custom cursor or some other special effect?" One answer is resource files. When you add a file using Visual Studio resource files, they're integrated directly into your Visual Basic project for maximum execution speed and minimum hassle packaging and deploying your application.

Resource files are available in both VB 6 and VB.NET, but the way they're used, like everything else, is quite a bit different between the two systems. Keep in mind that this isn't the only way to use files in a VB project, but it has real advantages. For example, you could include a bitmap in a PictureBox control or use the mciSendString Win32 API. "MCI" is a prefix that usually indicates a Multimedia Command String. 

Creating a Resource File in VB 6

You can see the resources in a project in both VB 6 and VB.NET in the Project Explorer window (Solution Explorer in VB.NET - they had to make it just a little bit different). A new project won't have any since resources aren't a default tool in VB 6. So let's add a simple resource to a project and see how that is done.

Step one is to start VB 6 by selecting a Standard EXE project on the New tab in the startup dialog. Now select the Add-Ins option on the menu bar, and then the Add-In Manager....

This will open the Add-In Manager dialog window.

Scroll down the list and find VB 6 Resource Editor. You can just double-click it or you can put a check mark in the Loaded/Unloaded box to add this tool to your VB 6 environment. If you think you're going to use the Resource Editor a lot, then you can also place a check mark in the box Load on Startup and you won't have to go through this step again in the future.

Click "OK" and the Resources Editor pops open. You're ready to start adding resources to your project!

Go to the menu bar and select Project then Add New Resource File or just right-click in the Resource Editor and select "Open" from the context menu that pops up. A window will open, prompting you for the name and location of a resource file. The default location will probably not be what you want, so navigate to your project folder and enter the name of your new resource file into the File name box. In this article, I'll use the name "AboutVB.RES" for this file. You'll have to confirm the creation of the file in a verification window, and the a "AboutVB.RES" file will be created and filled into the Resource Editor.

VB6 Supports

VB6 supports the following:

  • A string table editor
    ("Edit String Tables...")
  • Custom cursors - "CUR" files
    ("Add Cursor...")
  • Custom icons - "ICO" files
    ("Add Icon...")
  • Custom bitmaps - "BMP" files
    ("Add Bitmap...")
  • Programmer defined resources
    ("Add Custom Resource...")

VB 6 provides a simple editor for strings but you have to have a file created in another tool for all of the other choices. For example, you could create a BMP file using the simple Windows Paint program.

Each resource in the resource file is identified to VB 6 by an Id and a name in the Resource Editor.

To make a resource available to your program, you add them in the Resource Editor and then use the Id and the resource "Type" to point to them in your program. Let's add four icons to the resource file and use them in the program.

When you add a resource, the actual file itself is copied into your project. Visual Studio 6 provides a whole collection of icons in the folder ...

C:\Program Files\Microsoft Visual Studio\Common\Graphics\Icons

To go with tradition, we'll select the Greek philosopher Aristotle's four "elements" - Earth, Water, Air, and Fire - from the Elements subdirectory. When you add them, the Id is assigned by Visual Studio (101, 102, 103, and 104) automatically.

To use the icons in a program, we use a VB 6 "Load Resource" function. There are several of these functions to choose from:

  • LoadResPicture(index, format) for bitmaps, icons, and cursors

Use the VB predefined constants vbResBitmap for bitmaps, vbResIcon for icons, and vbResCursor for cursors for the "format" parameter. This function returns a picture that you can use directly. LoadResData (explained below) returns a string containing the actual bits in the file. We'll see how to use that after we demonstrate icons.

  • LoadResString(index) for strings
  • LoadResData(index, format) for anything up to 64K

As noted earlier, this function returns a string with the actual bits in the resource. These are the values that can be used for format parameter here:

  • 1 Cursor resource
    2 Bitmap resource
    3 Icon resource
    4 Menu resource
    5 Dialog box
    6 String resource
    7 Font directory resource
    8 Font resource
    9 Accelerator table
    10 User-defined resource
    12 Group cursor
    14 Group icon

Since we have four icons in our AboutVB.RES resource file, let's use LoadResPicture(index, format) to assign these to the Picture property of a CommandButton in VB 6.

I created an application with four OptionButton components labeled Earth, Water, Air and Fire and four Click events - one for each option. Then I added a CommandButton and changed the Style property to "1 – Graphical". This is necessary to be able to add a custom icon to the CommandButton. The code for each OptionButton (and the Form Load event -- to initialize it) looks like this (with the Id and Caption changed accordingly for the other OptionButton Click events):

 Private Sub Option1_Click()
    Command1.Picture = _
       LoadResPicture(101, vbResIcon)
    Command1.Caption = _
       "Earth"
 End Sub 

Custom Resources

The "big deal" with custom resources is that you normally have to provide a way to process them in your program code. As Microsoft states it, "this usually requires the use of Windows API calls." That's what we'll do.

The example we'll use is a fast way to load an array with a series of constant values. Remember that the resource file is included into your project, so if the values that you need to load change, you'll have to use a more traditional approach such as a sequential file that you open and read.

The Windows API we'll use is the CopyMemory API. CopyMemory copies block of memory to a different block of memory without regard to the data type that is stored there. This technique is well known to VB 6'ers as an ultra fast way to copy data inside a program.

This program is a bit more involved because first we have to create the a resource file containing a series of long values. I simply assigned values to an array:

Dim longs(10) As Long
longs(1) = 123456
longs(2) = 654321

... and so forth.

Then the values can be written to a file called MyLongs.longs using the VB 6 "Put" statement.

 Dim hFile As Long
 hFile = FreeFile()
 Open _
    "C:\your file path\MyLongs.longs" _
    For Binary As #hFile
 Put #hFile, , longs
 Close #hFile 

It's a good idea to remember that the resource file doesn't change unless you delete the old one and add a new one. So, using this technique, you would have to update the program to change the values. To include the file MyLongs.longs into your program as a resource, add it to a resource file using the same steps described above, but click the Add Custom Resource ... instead of Add Icon ... Then select the MyLongs.longs file as the file to add. You also have to change the "Type" of the resource by right clicking that resource, selecting "Properties", and changing the Type to "longs". Note that this is the file type of your MyLongs.longs file.

To use the resource file you have created to create a new array, first declare the Win32 CopyMemory API call:

 Private Declare Sub CopyMemory _
    Lib "kernel32" Alias _
    "RtlMoveMemory" (Destination As Any, _
    Source As Any, ByVal Length As Long) 

Then read the resource file:

 Dim bytes() As Byte
 bytes = LoadResData(101, "longs") 

Next, move the data from the bytes array to an array of long values. Allocate an array for the longs values using the integer value of the length of the string of bytes divided by 4 (that is, 4 bytes per long):

 ReDim longs(1 To (UBound(bytes)) \ 4) As Long
 CopyMemory longs(1), bytes(0), UBound(bytes) - 1 

Now, this may seem like a whole lot of trouble when you could just initialize the array in the Form Load event, but it does demonstrate how to use a custom resource. If you had a large set of constants that you needed to initialize the array with, it would run faster than any other method I can think of and you wouldn't have to have a separate file included with your application to do it.