Using resource files with Delphi

Post date: Dec 10, 2009 4:01:26 PM

Create the resource file script.

What follows is a step by step instruction for creating resource files.

Resource files can contain text, html documents, sounds, images etc.

Open a simple text editor, e.g. Notepad and enter the files you want to include in your application.

Every line consist of a resource name, a resource type and the resource.

In the example below support is the resource name, HTML is the resource type and "support.html" is the resource.

support HTML "support.html"

content HTML "content.html"

help HTML "help.html"

bg JPG "bg.jpg"

back BMP "back.bmp"

forward BMP "forward.bmp"

home BMP "home.bmp"

next GIF "next.gif"

Save this file with the .rc extension, e.g. myresource.rc.

Compile the resource file.

Now compile myresource.rc with the resource compiler BRCC32.exe which you will find in your Delphi5\bin\ directory.

BRCC32.exe is a command line utility that has the .rc extension associated with it.

Double-click myresource.rc in Windows Explorer and it will be compiled to myresource.res.

Include the resource file in your project.

Enter a statement like {$R .\resources\myresource.res} in your main unit file.

This will look then something like:

implementation

{$R *.DFM}

{$R .\resources\myresource.res}

Assuming that you keep the resource for a project in a subdirectory called resources , (like I always do for clarity).

Loading the resource file

Next you need a procedure to load a named resource into a memorystream

procedure LoadResourceFile(aFile:string; ms:TMemoryStream);

var

HResInfo: HRSRC;

HGlobal: THandle;

Buffer, GoodType : pchar;

I: integer;

Ext:string;

begin

ext:=uppercase(extractfileext(aFile));

ext:=copy(ext,2,length(ext));

if ext='HTM' then ext:='HTML';

Goodtype:=pchar(ext);

aFile:=changefileext(afile,'');

HResInfo := FindResource(HInstance, pchar(aFile), GoodType);

HGlobal := LoadResource(HInstance, HResInfo);

if HGlobal = 0 then

raise EResNotFound.Create('Can''t load resource: '+aFile);

Buffer := LockResource(HGlobal);

ms.clear;

ms.WriteBuffer(Buffer[0], SizeOfResource(HInstance, HResInfo));

ms.Seek(0,0);

UnlockResource(HGlobal);

FreeResource(HGlobal);

end;

The TmemoryStream must be created before you call the routine. If you use a lot of resources in your program you can create the variable ms in the FormCreate event and destroy it in the FormDestroy event.

aFile is the name of a resource file to be loaded, without path information.

Personally I always use the method of giving the resource name the same name as the resource file without the extension. This allows for a generic routine like above.

Using the resource file

Finally we want to use the resource file that is now in the TMemoryStream variable ms.

In Delphi many components have a LoadFromStream method that you can use to load the resource.

Suppose we want to load the resource file support.html into a Tstrings.

procedure LoadStringResource;

begin

List:=TStringList.create;

LoadResourceFile('support.html',ms);

Memo1.Lines.LoadFromStream(ms);

end;

In the above Memo1 is a TMemo.

Alternative method

procedure LoadStringResource2;

var

tmpStream: TResourceStream;

begin

tmpStream := TResourceStream.Create( HInstance, 'support', 'HTML' );

try

memo1.Lines.LoadFromStream( tmpStream );

finally

tmpStream.Free;

end;

end;

Conclusion

Compiling resources into your application is easy. It can be used to include all the html docs and images that together make up the user interface. These could have included these files as external files, but this way I am sure that they are always there when the program needs them.

They can also be used to create custom install packages.