0% found this document useful (0 votes)
543 views

Creating A Resource File in VB 6

The document discusses creating and using resources in VB 6 projects. It describes adding a resource editor add-in, creating a resource file, and adding different types of resources like icons and strings. It then provides examples of using the LoadResPicture function to load icon resources and display them on a command button. Finally, it discusses using custom resources to load array data from a file included as a resource.
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
543 views

Creating A Resource File in VB 6

The document discusses creating and using resources in VB 6 projects. It describes adding a resource editor add-in, creating a resource file, and adding different types of resources like icons and strings. It then provides examples of using the LoadResPicture function to load icon resources and display them on a command button. Finally, it discusses using custom resources to load array data from a file included as a resource.
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 9

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.

• 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

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.

Resources
Bitmaps, icons, cursors, string tables... Every Windows program uses resources. Resources are
those elements of a program that support the program but are not executable code. In this
article, we will walk through some examples of the use of bitmaps, icons and cursors from
resources.
Placing resources in the .exe file has two main advantages:
- The resources can be accessed more quickly because it takes less time to locate a resource in
the executable file than it does to load it from a disk file.
- The program file and resources can be contained in a single unit (the .exe file) without the need
for a lot of supporting files.

The Image Editor


First off all, we need to create a resource file. Default extension for resource files is .RES.
Resource files can be created with Delphi's Image Editor. Read in Help files on working with the
Image Editor.

You can name the resource file anything you want, as long as it has the extension ".RES" and the
filename without the extension is not the same as any unit or project filename. This is important,
because by default, each Delphi project that compiles into an application has a resource file with
the same name as the project file, but with the extension .RES. It's best to save the file to the
same directory as your project file.

Including resources in applications


In order to access our own resource file we have to tell Delphi to link our resource file in with our
application. This is accomplished by adding a compiler directive to the source code. This directive
needs to immediately follow the form directive, like the following:

{$R *.DFM}

{$R DPABOUT.RES}

Do not accidentally erase {$R *.DFM} part, as this is the line of code that tells Delphi to link in
the form's visual part. When you choose bitmaps for speed buttons, Image components or Button
components, Delphi includes the bitmap file you chose as part of the form's resource. Delphi
isolates your user interface elements into the .DFM file.

To actually use the resource, you must make a few Windows API calls. Bitmaps, cursors and icons
stored in RES files can be retrieved by using the API functions LoadBitmap, LoadCursor and
LoadIcon respectively.

Pictures in resources
The first example shows how to load a bitmap stored as a resource and display it in a TImage
component.
procedure TfrMain.btnCanvasPic(Sender: TObject);

var bBitmap : TBitmap;

begin

bBitmap := TBitmap.Create;

try

bBitmap.Handle := LoadBitmap(hInstance, 'ATHENA');

Image1.Width := bBitmap.Width;

Image1.Height := bBitmap.Height;

Image1.Canvas.Draw(0,0,bBitmap);

finally

bBitmap.Free;

end;

end;

Note: If the bitmap that is to be loaded is not in the resource file, the program will still run, it just
won't display the bitmap. This situation can be avoided by testing to see if the bBitmap.Handle is
zero after a call to LoadBitmap() and taking the appropriate steps. The try/finally part in the
previous code doesn't solve this problem, it is just here to make sure that the bBitmap is
destroyed and its associated memory is freed.

Another way we can use to display a bitmap from resource is as follows:

procedure TfrMain.btnLoadPicClick(Sender: TObject);

begin

Image1.Picture.Bitmap.

LoadFromResourceName(hInstance,'EARTH');

end;

Cursors in resources
As discussed in the previous article Screen.Cursors[] is an array of cursors supplied by Delphi. By
using resource files, we can add custom cursor to the Cursors property. Unless we wish to replace
any of the defaults, the best strategy is to use cursor numbers starting from 1.

procedure TfrMain.btnUseCursorClick(Sender: TObject);


const NewCursor = 1;

begin

Screen.Cursors[NewCursor] :=

LoadCursor(hInstance,'CURHAND');

Image1.Cursor := NewCursor;

end;

Icons in Resources
If we look at Delphi's Project-Options-Application settings, we can find that Delphi supplies the
default icon for a project. This icon represents the application in the Windows Explorer and when
the application is minimized. We can easily change this by clicking the 'Load Icon' button.

If we want, for example, to animate the program's icon when the program is minimized than the
following code will do the job.
For the animation, we need a TTimer component on a form. The code loads two icons from
resource file into an array of TIcon objects; this array needs to be declared in the public part of
the main form. We'll also need NrIco, that is an Integer type variable, declared in the public part.
The NrIco is used to keep track of the next icon to show.

public

nrIco : Integer;

MinIcon : array[0..1] of TIcon;

...

procedure TfrMain.FormCreate(Sender: TObject);

begin

MinIcon[0]:=TIcon.Create;

MinIcon[1]:=TIcon.Create;

MinIcon[0].Handle:=LoadIcon(hInstance,'ICOOK');

MinIcon[1].Handle:=LoadIcon(hInstance,'ICOFOLD');

NrIco:=0;

Timer1.Interval:=200;

end;

...
procedure TfrMain.Timer1Timer(Sender: TObject);

begin

if IsIconic(Application.Handle) then begin

NrIco:=(NrIco+1) mod 2;

Application.Icon:=MinIcon[NrIco];

end;

end;

...

procedure TfrMain.FormDestroy(Sender: TObject);

begin

MinIcon[0].Free;

MinIcon[1].Free;

end;

In the Timer1.OnTimer event handler, IsMinimized function is used to see whether we need to
animate our main icon or not. Better way of accomplishing this would be to capture the
maximize/minimize buttons and than act.

Final words
We can place anything (well, not everything) in resource files. This article has shown you how to
use resources to use/display bitmap, cursor or an icon in your Delphi application. If you are
interested in what else can be placed inside one resource file try the links at the bottom of the
article.

Note: When we save a Delphi project to the disk, Delphi automatically creates one .RES file that
has the same name as the project (if nothing else, the main icon of the project is inside).
Although we can alter this resource file, this is not advisable.

Don't forget to download this project and try to play with it.
A Globalizing Trick For VB 6
Tuesday October 11, 2005

The recent article about globalizing in VB.NET demonstrates how a number can be formatted
there, but what about VB 6?

Veteran VB 6'er (and frequent co-author) Peter Zilahy Ingerman (Getting Your System Out,
Calculating a Contrasting Color Code, and Symbolic Logic) read my article and passed along a
trick that works for him.

First, note that VB 6 can automatically format a number according to the "Regional Option" set in
Windows fairly easily. For example, if I set my system to "Slovenian" I can format a number using
the Format function in VB 6 ...

Format(123456.78, "###,##0.00")

I then get

123.456,78

... in proper Slovenian form.

Peter said he often had a slightly different problem. "The issue arises in the context where ... I
allow the user to *enter* numbers in a locale-specific way, so I have to parse them into my
internal standard form." In other words, how do you figure out if the user entered, "123.456,78"
or "123,456.78".

You can do this in VB 6 using API calls. The code,

Private Declare Function GetUserDefaultLCID% Lib "kernel32" ()


Private Sub Command1_Click()
Dim LCID As Long
'get the user's Locale ID
LCID = GetUserDefaultLCID()
End Sub

... will return an LCID value of 1060 for Slovenian and 1033 for United States English. You can
then plug this into the GetNumberFormat Win32 API and get a value in a NUMBERFMT
structure that can be interrogated to determine what the local number formatting culture is. No
less an authority than Dan Appleman states in his landmark book, A Guide to the Win32 API, "This
structure is tricky to use from Visual Basic." (And he doesn't give an example.)

Or ... you can use a simple two line code snippet in VB 6 that Peter suggests.

LocaleDecimal = Mid$(CStr(11 / 10), 2, 1)


LocaleComma = Chr$(90 - Asc(LocaleDecimal))

The variables LocaleDecimal and LocaleComma will contain the appropriate symbol according to
the Windows setting after this code executes. The key to making this happen is to get Windows to
give you a string with the appropriate formatting. If you have the region set to Slovenian (or any
other area where comma is the decimal symbol), CStr(10 / 11) returns the string "1,1". In my
testing, CStr(1.1) does too, but Peter felt that a division avoids a "circular definition" in the code.

The second line works because the ASCII value of a comma plus a decimal equal 90 in any
culture. So if you subtract one, you get the other.

Cultural Values are great!

You might also like