Under WINDOWS, you can include resources in your executable or library using the {$R filename} directive. These resources can then be accessed through the standard windows API calls.
When the compiler encounters a resource directive, it just creates an entry in the unit .ppu file; it doesn't link the resource. Only when it creates a library or executable, it looks for all the resource files for which it encountered a directive, and tries to link them in.
The default extension for resource files is .res. When the filename has as the first character an asterix (*), the compiler will replace the asterix with the name of the current unit, library or program.
Remark: This means that the asterix may only be used after a unit, library or program clause.
The Free Pascal compiler itself doesn't create any resource files; it just compiles them into the executable. To create resource files, you can use some GUI tools as the Borland resource workshop; but it is also possible to use a windows resource compiler like GNU windres. windres comes with the GNU binutils, but the Free Pascal distribution also contains a version which you can use.
The usage of windres is straightforward; it reads an input file describing the resources to create and outputs a resource file.
A typical invocation of windres would be
windres -i mystrings.rc -o mystrings.resthis will read the mystrings.rc file and output a mystrings.res resource file.
A complete overview of the windres tools is outside the scope of this document, but here are some things you can use it for:
Some of these will be described below.
A string table looks as follows:
STRINGTABLE { 1, "hello World !" 2, "hello world again !" 3, "last hello world !" }You can compile this (we assume the file is called tests.rc) as follows:
windres -i tests.rc -o tests.resAnd this is the way to retrieve the strings from your program:
program tests; {$mode objfpc} Uses Windows; {$R *.res} Function LoadResourceString (Index : longint): Shortstring; begin SetLength(Result,LoadString(FindResource(0,Nil,RT_STRING),Index,@Result[1],SizeOf(Result))) end; Var I: longint; begin For i:=1 to 3 do Writeln (Loadresourcestring(I)); end.The call to FindResource searches for the stringtable in the compiled-in resources. The LoadString function then reads the string with index i out of the table, and puts it in a buffer, which can then be used. Both calls are in the windows unit.
The win32 API allows to store version information in your binaries. This information can be made visible with the WINDOWS Explorer, by right-clicking on the executable or library, and selecting the 'Properties' menu. In the tab 'Version' the version information will be displayed.
Here is how to insert version information in your binary:
1 VERSIONINFO FILEVERSION 4, 0, 3, 17 PRODUCTVERSION 3, 0, 0, 0 FILEFLAGSMASK 0 FILEOS 0x40000 FILETYPE 1 { BLOCK "StringFileInfo" { BLOCK "040904E4" { VALUE "CompanyName", "Free Pascal" VALUE "FileDescription", "Free Pascal version information extractor" VALUE "FileVersion", "1.0" VALUE "InternalName", "Showver" VALUE "LegalCopyright", "GNU Public License" VALUE "OriginalFilename", "showver.pp" VALUE "ProductName", "Free Pascal" VALUE "ProductVersion", "1.0" } } }As you can see, you can insert various kinds of information in the version info block. The keyword VERSIONINFO marks the beginning of the version information resource block. The keywords FILEVERSION, PRODUCTVERSION give the actual file version, while the block StringFileInfo gives other information that is displayed in the explorer.
The Free Component Library comes with a unit (fileinfo) that allows to extract and view version information in a straightforward and easy manner; the demo program that comes with it (showver) shows version information for an arbitrary executable or DLL.
When WINDOWS shows an executable in the Explorer, it looks for an icon in the executable to show in front of the filename, the application icon.
Inserting an application icon is very easy and can be done as follows
AppIcon ICON "filename.ico"This will read the file filename.ico and insert it in the resource file.
Sometimes you want to use symbolic names in your resource file, and use the same names in your program to access the resources. To accomplish this, there exists a preprocessor for windres that understands pascal syntax: fprcp. This preprocessor is shipped with the Free Pascal distribution.
The idea is that the preprocessor reads a pascal unit that has some symbolic constants defined in it, and replaces symbolic names in the resource file by the values of the constants in the unit:
As an example: consider the follwoing unit:
unit myunit; interface Const First = 1; Second = 2: Third = 3; Implementation end.And the following resource file:
#include "myunit.pp" STRINGTABLE { First, "hello World !" Second, "hello world again !" Third, "last hello world !" }if you invoke windres with the -preprocessor option:
windres --preprocessor fprcp -i myunit.rc -o myunit.resThen the preprocessor will replace the symbolic names 'first', 'second' and 'third' with their actual values.
In your program, you can then refer to the strings by their symbolic names (the constants) instead of using a numeric index.