Information on Delphi Resources

Windows allows applications to store certain information as resources. This includes - Cursors, Icons, Bitmaps, Strings, Dialog Boxes (Forms), Menus, RCData, and more. Resources even allow the application to support multiple languages in a single file (Windows NT and above, not 95 or 98).

Resource scripts are *.rc text files. Compiled resources are stored in *.res files and linked to executables. Delphi provides *.dcr files to hold *.res data which is available only at design time.

Delphi provides several commands to read bitmap resources. For example

To work with cursors, you will need the Windows API function LoadCursor or LoadImage. For icons, use LoadIcon or LoadImage.

Warning: All resource editors I've found contain fatal design errors. Be careful. If you follow my notes, resources will work for you.

Instead of using their pre-defined resource keys, Delphi programs save Forms (Dialogs), Menus, and Accelerators in *.dfm files which are stored in RCData.

As of 2014, I was no longer satisfied with the available options to create ico files. There are several free options on the web, but they have various drawbacks. Therefore, I have added a section on using Gimp to create ico files.

Tools to view/edit Resources - Resource Hacker - *.bpl Files | Image Editor | Resource Explorer | Borland C++ | Resource Workshop | Visual C++ | Gimp

Resources - Application Icons | Cursors | Bitmaps | Component Toolbar Buttons | Form Descriptions | Strings

References


Resource Hacker

Resource Hacker - Version 3.4.0 - FREEWARE utility to view, modify, add and delete resources in Win32 executables. (Compiled using Delphi ver 3.02.)

Once you install it, just right click any *.exe, *.dll, *.ocx. or *.cpl file and select Resource Hacker. (Some files with these extensions may be in a different format and can not be read.) (The right click capability was in version 3.2.4, but omitted in version 3.4. If you want, you can manually add this capability to the registry. See the section on *.bpl files below.) Use this program to explore your system - you will learn a lot. For instance, try

You should recognize most of the dialog boxes. The help provides step by step instructions on how to add your icons to one of these. (Please be careful, you could hose your system.)

Notice that it will open an *.res file, but not an *.dcr file. However, if you simply rename the *.dcr file to *.res, then it will open it.


*.bpl Files

In addition to the listed files, the Resource Hacker will read *.bpl (Borland package library) files (these are actually dll's that can be called at run time) - just use File / Open. You will find most of the *.bpl files in 3 places

This registry hack will make viewing their resources easier - with it, you can just right click an *.bpl file and select Open using Resource Hacker. Simply add and configure HKCR\.bpl and HKCR\bplfile (these already exist if Depends is installed).

If necessary, add

Under HKCR\bplfile, add For versions 3.2.4, use the following path Notes: I have a "working" *.reg file - however, be cautious, the directory I used is probably not the same one you used. To use this file, remove the ".txt" extension and double click it.

As of 2014, the version I have (3.4) no longer "installs" itself. Therefore, I have an alternate registry file that includes exe and dll files .. and a different path. (Be careful.)

As of 2014, the current version is 3.6.0.


Image Editor

This is available from the Delphi 5 menu via Tools / Image Editor. It allows you to create and/or edit two types of resource files It allows you to Add, Delete, and Edit only 3 types of resources - Bitmaps, Icons, and Cursors.

Personally, I use it to create the images used on the component tool bar (bitmaps).

Notes:


Design Error

Experiments to create application icons failed - I was not able to control which icon was displayed. A thorough search with the Image Editor revealed no problems. However, the Resource Hacker revealed the source of the problem - in *.exe, MAINICON (the icon for your application) was pointing to an icon resource which actually contained two separate icons. Further analysis revealed that my *.res files contained icons which Image Editor did not show.

Basically, Image Editor contains a major design error - if you create 2 (or more) icons and then delete all but one, all the "deleted" icons are still in the *.res file. Resource Hacker can see them, but Image Editor simply hides them from you. So far, this is not a big deal. Unfortunately, if your application contains more than one *.res file, and one of those files contains a "deleted" icon, then the problem described above occurs - when the resource files were linked, the "deleted" icon was added to one of the existing icons.


Resource Explorer

This program comes with Delphi 5 ... with full source code. Just compile and run it. It shows only one section for icons and one section for cursors. (Resource Hacker shows 2 sections for each.) The form definition is in hex, Resource Hacker shows it as text.


Borland C++

On my system, when you double click an *.res file, Borland C++ opens. This is a much more powerful resource editor than Image Editor. For instance, it allows a cursor group to have more than one cursor and it allows each cursor to be 2, 16, or 256 colors. Image Editor only permits one cursor per group and it allows only 2 colors. With 2 cursors in a group, Image Editor was only able to show me one of them, not both.

This program has several important design errors - see discussions below. Basically, when you delete a cursor or icon resource, it lies to you and then you get very weird problems with your application. The only solution is to create a new *.res file.


Resource Workshop

Warning: Do Not use this program

Similar to using Borland C++ to edit *.res files. To add additional images per cursor

For icons, it supports 16x16, 32x32, and 64x64 - the Delphi 5 Image Editor does not support 64x64. Use Images / New image... to add additional icons.

Resource Script Language help is installed with the workshop. Unfortunately, it is not quite complete.

Resource Workshop is on the Delphi 5 CD.

This is old code - 1995 (Delphi 5 is 1999). The readme says to clean boot to dos before installing, but I had no problem installing under Windows XP with lots of stuff open.

Warning: Do Not use this program - I created 2 ico files using this. The program was able to see the directory entries - but no other Windows XP program could see them. I assume that the program directly manipulated the directory file assuming that it was FAT. In fact, it was an NT partition!!! As a result, this program created 2 invisible files that can never be removed.


Visual C++

Visual C++ includes a great resource script (*.rc) editor - create one using File / New / Resource Script. Unfortunately, the *.rc files include c-type headers (ie, Delphi can't use these). When these are compiled into *.res files, the resource names are changed to numbers. The numbers are defined in resource.h which is automatically generated.

I tried using one of these in Delphi 5 (with all the C stuff removed) and got a "Unsupported 16-bit resource" error. If you also create a matching *.res file, the following syntax does not produce errors. However, it also does not include the cursor and icon resources in the *.rc file in the *.exe file.

On the other hand, each cursor and icon is saved in a separate file (*.cur and *.ico respectively).


Gimp

The free gimp image editor is able to generate icon (ico) files.

This is pretty straight forward

There are, of course, many videos.

Note that each layer must be the same size as the icon it holds. If you just resize the image, this won't work.

Some applications will want a 48x48 icon.

For more details, see my help on using gimp to create icons.



Resources


Application Icons

All projects have a default resource file - ProjectName.res - which is included via the *.dpr (Delphi project) file via The project's icon (the icon shown in Windows Explorer and in the project's title bar) is saved as MAINICON, a 32x32 16-color icon. (Various editors support other sizes and color depths. Windows picks which one to display.)

Under the covers (as revealed using Resource Hacker), MAINICON is actually just a pointer to a numbered icon (normally to icon number one). If a component, or another resource file, contains a partially deleted icon (such as an icon "deleted" using Image Editor), then you have a problem - when the resources are linked, the "deleted" icons may be combined with the one MAINICON points to. If that happens, then you no longer have control over which icon is displayed for your application. In my case, my application's icon was actually the one I "deleted".

Note: Delphi caches ProjectName.res. Modifications made to this file are not included in the ProjectName.exe file until you close (File / Close All) and reopen the project. I discovered this by modifying the application icon - MAINICON - in ProjectName.res and then checking ProjectName.exe with Resource Hacker. The unmodified default icon was present, not the modified icon that Resource Hacker showed in ProjectName.res. After closing and reopening the project, the new icon appeared.

If you set the application's icon via Project / Options... / Application / Load Icon, then the new icon is immediately available.

Icons are used

Using Tools / Image Editor, create an *.ico file. In it, include 2 icons, one as 16x16 and the other as 32x32. They should both be 16 colors. The small icon is displayed in Windows Explorer, in the application's title bar, and in the task bar at the bottom of the screen - the large icon is displayed when you alt-tab to another application. For additional information, and to create and use larger icons, see


Component Toolbar Buttons

Component icons (displayed in the tool palette) are 25x25 bitmaps with the same name as the class.

Note: In the resource file, use Bitmap, not Icon, to create these.

Since these are identified by name, you have a good chance of avoiding conflicts.


Cursors

You can store mouse cursors as resources. If you use Image Editor, then be sure to change the names - the default names do not work. (It only took me 5 days of working on nothing else to discover this trick.)

According to the Delphi 5 help (see TScreen.Cursors), this is how to use a cursor located in a resource file.

(The resource name is not case sensitive.)

The Delphi components use numbers instead of strings (see Delphi5\Lib\controls.res).

Notice that in Image Editor, "1234" is a string, but in the command above, it is an integer (it also appears to be an integer in the *.res file). (Of course, you must make sure to select a number between 0 and 32K that no one else has ever used ... and that no one else WILL ever use. Yeah, right!)

Strangely, this code also works

(Casting an integer as a null terminated string is definitely weird. The Resource Workshop Reference provided with Borland C++ 5.02 specifically says that "You must either typecast the integer into a long pointer to char or use [the MAKEINTRESOURCE] macro.")

For additional information, see


Unique Identifiers

Though numbers produce faster code, I do not suggest doing this - strings allow you to generate unique identifiers. (IDC_ is a standard meaning a Resource of type Cursor. It is not required.)

The Screen.Cursors array presents another problem - its "index" must be a number. (The Screen.Cursors "array" is actually a linked list and the "indices" are node ID's. If you try to read a non-existent node, Screen.Cursors returns the handle for node zero.) The Delphi predefined cursors won't be a problem since they are all negative integers. However, other components may have already defined a cursor or two. This code will find the next unused positive index.


Editor Quirks

Each resource editor has its own quirks - be careful.
Image Editor Must re-name cursors or you can't see them in Delphi. Resource Hacker has no problem if they are not re-named.

Shows only one Cursor section even though there are actually two.

Allows only one color depth and only one size.

Borland C++ Select Edit as Text to set the name of the cursor.

Cursors already named with numbers using Image Editor will no longer work in Delphi.


Resource Error

Using Image Editor, cursors are associated with a single section. However, Resource Hacker shows that there are actually two sections

Using Image Editor to delete one of the cursors only removes the pointer to the cursor. According to Resource Hacker, the cursor is still in the *.res and *.exe files. (The Cursor Group was removed, but Cursor was still present.)

Apparently, when several resource files are included in the same *.exe, the cursor numbers are re-assigned so that there are no conflicts. However, if a cursor is not associated with a group, then it gets associated with an existing cursor and there are problems.


Bitmaps

Borland TI1081D - Loading Bitmaps and Cursors from RES Files - contains special code to maintain the colors. You can simply use LoadBitmap if the image has only the standard 16 vga colors.


Form Descriptions

This is interesting, the complete contents of your *.dfm file(s) is stored under RCData / formname. This can be seen using the Resource Hacker. This means that anyone can read or edit this information.


Strings

Normally, Delphi only places error messages and the like in the resources.

However, if you want to include your string constants in the executable's resources, use resourcestring instead of const.


Grammar Note

I have elected to use the article "an" before all file references which start with an asterisk (*). My assumption is that "an *.exe file" would be read as "an asterisk dot E X E file", and that "an *.txt file" would be read as "an asterisk dot text file" but not as "a text file" (which is also a correct reading).

I realize that some people will not agree with this.


References

Resource Script Files - this is a short file, but the links at the bottom of the page are also good

Microsoft's Resource Compiler page - slow and wordy, but at least there is some data


Author: Robert Clemenzi
URL: http:// mc-computing.com / Languages / Delphi / Resources.html