HOME, PRODUCTS, ARTICLESCONTACT

C++BUILDER AND DELPHI FEEDBACK

COMPILING RESOURCE (.RES) FILES FROM RESOURCE COMPILER (.RC) TEXT FILE PRESCRIPTIONS

Resource (.res) files are an intermediate container for resources such as bitmaps or text, which may later be compiled into applications, components, or DLLs. This article documents how and when to compile resource (.res) files from .rc text file prescriptions.

ADVANTAGES OF DIRECT RELIANCE ON THE RESOURCE COMPILER

Visual GUIs are not always the "easy," most efficient, or most reliable way to get a job done. "Manual" compilation of resource (.res) files from .rc text file prescriptions overcomes the limitations of visual resource editors, and substantially automates your work:

  • A simple .rc text file prescription prescribes run time resource names and associated source files.
    • Building a .rc text prescription is equivalent to merely providing the nomenclature required by a visual editor.
    • Usual visual processes such as opening source files, selecting and copying content, and pasting it into graphic containers of the visual editor, are eliminated.
  • A shortcut runs the Borland Resource Compiler, which reads the prescription and generates the same .res file you would build far more laboriously with a visual resource editor.
  • Direct reliance on the resource compiler digests any processable resource, and frees your work from any limitations of visual resource editors.
    • This allows you to use more appropriate applications to pre-process output such as graphics. If you want to use a favorite PhotoShop plug-in to pull off a drop shadow, your image won't be mangled into a cobby 8-bit result.

The following techniques allow application developers to compile or re-compile resources with a single click.

WHEN TO UTILIZE COMPILED .RES FILES

Resource (.res) files should be routinely compiled into distributables for the following reasons:

  1. To reduce the size of executable files and the time necessary to load executables.
    • A single embedded resource instance can be loaded into many runtime instances.
  2. To gain the speed advantages of LoadFromResourceName.
    • Because LoadFromResourceName directly accesses memory, LoadFromResourceName is substantially faster than the I/O intensive LoadFromFile method.
  3. To eliminate the need to distribute separate files containing resources.
    • Distribute one integrated file, instead of many.

THE RESOURCE COMPILER (.RC) FILE — A PRESCRIPTION FOR THE COMPILED RESOURCES

Resource Compiler (.rc) files are built with generic text editors, and are simply text file prescriptions which declare on each line, the run time reference names and source files of resources to be compiled into a .res file.

THE RESOURCE (.RES) FILE — INTERMEDIATE CONTAINER FOR RESOURCES

Resource (.res) files are generated by the resource compiler, and ultimately are compiled into applications, components, or dynamic link libraries by your regular application compiler, which heeds linking instructions indicating the .res resources which thus are internalized into your project.

ORGANIZATION GUIDELINE

  • For each resource file, keep source files such as bitmaps, the .rc file, batch files, and the generated .res file in a dedicated subdirectory of your project.
  • Keep shortcuts to batch files in project toolbar directories installed to the Windows™ QuickLaunch™ toolbar while working on the principal project.
  • After compiling the .res file from a shortcut, copy it to the project directory with a further shortcut running a batch file.

Two clicks generate the .res file (1/2) and copy it to the project directory (2/2).

CONVENTIONS — UPPERCASE NAMES WITH UNDERSCORE CHARACTERS

To avoid undocumented problems (or rules), we use uppercase alpha-numeric resource and file names with underscore characters.

WRITING THE .RC FILE

Each line of the .rc text file prescribes:

  1. A unique resource name.
    • The code of your application eventually refers to the resource by this unique name.
    • Usual naming rules apply.
  2. A user-defined category name.
    • The category name is ignored by the resource compiler, but visual resource editors may utilize this parameter for whatever purposes.
  3. The original source file name.
    • The source file name must be placed in double quotes.
    • The file must be located in the same directory as the .rc prescription, unless you are willing to express complete paths.

In the following example .rc prescription statement,

  1. MT_FIRST declares the unique run time resource name.
  2. UPCBMP24 declares an irrelevant, user-definable category name.
  3. "MT_FIRST.BMP" is the source file.

Because our source file is identified by the resource name, we can simply copy source file names into the .rc prescription.

EXAMPLE .RC PRESCRIPTION STATEMENT

Copy code to clipboard (JavaScript/IE).

QUICKLY WRITING ERROR FREE .RC FILE PRESCRIPTIONS

To quickly build a prescription, copy a template block into enough lines for the .rc file you need to build. You require 1 line per resource.

EXAMPLE REPLACEMENT TOKEN STATEMENTS (10 ONLY)

Copy code to clipboard (JavaScript/IE).

Now open Windows Explorer to your source directory so that you can select file names to paste into your .rc prescription. Because our source files are identified by the intended run time resource names, we can quickly build each line of the .rc prescription file by,

  1. Copying the file identifier into the zzzzz replacement token.
  2. Pressing the HOME key.
  3. Pasting the file identifier again at the beginning of each line.

EXAMPLE AISUPC.RC FILE CONTENT

Copy code to clipboard (JavaScript/IE).

INVOKING THE RESOURCE COMPILER WITH A BATCH FILE RUN BY A SHORTCUT

Here, we use an AISUPC.BAT batch file to run the Borland RC Compiler, BRCC32.EXE, with the switch -r, passing AISUPC.RC as the .rc file argument.

  • The -r switch and AISUPC.RC arguments automatically name the output, AISUPC.RES.
  • Keep the batch file in your dedicated resource subdirectory, and invoke the batch file with a shortcut.

EXAMPLE AISUPC.BAT COMPILER FILE CONTENT

Copy code to clipboard (JavaScript/IE).

ERRORS AND OUTPUT

  • Compiling overwrites the previous .res file.
  • Compile time errors simply result in no .res file or overwrite.
    • The author of the .rc file is responsible for the integrity of the prescription.
    • Possible errors are rudimentary and obvious, including duplicate resource names or missing source files.
    • Should a compile fail, this will be evident in a lacking last modified timestamp of the .res file.
      • The error should be obvious in the .rc prescription or environment (available source files).

COPYING THE COMPILED .RES FILE TO YOUR PROJECT DIRECTORY WITH A BATCH FILE RUN BY A SHORTCUT

Because the output .res file lands in the same directory, now we will want to copy the .res file to destination directories which may compile it into executables. This process too can be automated into a single click. A batch file invoked by another shortcut copies our .res output file to destination directories:

AISUPC_COPY_RES_TO_DESTINATION.BAT

Copy code to clipboard (JavaScript/IE).

REVISING YOUR RESOURCE FILE

  • Whenever we need to include further content or otherwise modify our resource file, we revise our .rc prescription.
  • To re-compile our resource file, we click our AISUPC.BAT shortcut.
  • To copy output to destination directories, we click our AISUPC_COPY_RES_TO_DESTINATION shortcut.
    • Why do we perform the copy from a second batch file and shortcut? Because if the copy were integrated with the compile instruction (not having any power to wait for the compile to be completed), the copy could be initiated while output is still compiling.

Now we can use our resource file.

LINKING THE .RES FILE FROM APPROPRIATE DELPHI OR C++BUILDER UNITS

Linking causes the .res file to be built into your application, component or DLL during regular project compiles.

To link your .res file into a Delphi project, place a $R ("Resource") compiler directive and resource filename statement under the implementation keyword of the bottom-most unit referring to the resources. If UnitC uses UnitB which uses UnitA, and if all of these units might rely on any of the embedded resources, link to the .res file from UnitA.

EXAMPLE RESOURCE COMPILER DIRECTIVE

Copy code to clipboard (JavaScript/IE).

LINKING RESOURCES INTO A DELPHI DLL

One way to bundle compiled resources with distributables is to compile your resource file into a DLL. To build compiled resources into a Delphi DLL, all you have to do is add the $R directive to the project skeleton generated by the IDE:

  1. Click File->New->Other->DLL.
  2. Add a resource directive statement to the generated skeleton project.
  3. Save the DLL project to your resource compiling directory.
  4. Compile.
  5. Copy the DLL to your application directory, and bundle it with your distributable.

DELPHI EXAMPLE — A COMPLETE RESOURCE DLL

Copy code to clipboard (JavaScript/IE).

LINKING A RESOURCE FILE INTO A C++BUILDER PROJECT OR DLL

The equivalent C++ Builder™ DLL wizard generates all of the following code but the necessary #pragma resource statement:

C++ EXAMPLE — A COMPLETE RESOURCE DLL

Copy code to clipboard (JavaScript/IE).

USING LoadFromResourceName

We must call LoadFromResourceName() to assign resources to Delphi and C++Builder objects.

PACKAGED COMPONENTS — DYNAMICALLY LOADING IMAGES WITH LoadFromResourceName

The following examples assign a MT_CLONE image resource to the Glyph property of MySpeedbutton:

DELPHI EXAMPLE

Copy code to clipboard (JavaScript/IE).

C++ EXAMPLE

Copy code to clipboard (JavaScript/IE).

APPLICATIONS — DYNAMICALLY LOADING IMAGES FROM DLLs WITH LoadFromResourceName

To load images from DLLs, we need to declare a THandle (Delphi) or HANDLE (C++):

DELPHI EXAMPLE

Copy code to clipboard (JavaScript/IE).

C++ EXAMPLE

Copy code to clipboard (JavaScript/IE).

ADDING .RC FILES TO PROJECTS?

The Delphi and C++Builder development environments allow developers to add RC files to projects. In our experience however, this feature does not necessarily link the .res file to the appropriate unit; nor is it useful to recompile resources every time the project is compiled.

CAVEATS — BROKEN PRODUCTS

Why are developers embedding resources into DLLs, instead of directly into their executables?

C++ debug sessions show that there are problems casting HInstance to an unsigned integer. The compiler asks for an unsigned integer, but the value of the necessary HANDLE is incorrectly cast to unsigned int:

LONG EXISTING C++Builder AND DELPHI BUG?

Copy code to clipboard (JavaScript/IE).

RECOMMENDED REFERENCES

Calvert provides excellent teaching of .res and .rc topics in his "Delphi Unleashed" series.

© Copyright 1995-2007, by ADVANCE Information Systems, Inc. ALL RIGHTS RESERVED.Copyright 1995-2007, by ADVANCE Information Systems, Inc. ALL RIGHTS RESERVED.

Firefox™.Best viewed in Mozilla Firefox™.