Creating and Using Resource-Only DLLs
Creating Resource-Only DLLs

1. Create a Resource file with the following contents:

Resource Script splashres.rc

BMPAUDINA        BITMAP "splash-audina.bmp"
BMPTRANSEAR      BITMAP "splash-transear.bmp"
JPEG_SAMPLE_LOGO RCDATA "samplelogo.jpg"

Other possible resource types:

MyPhoto         RCDATA  "images/logo.jpg"
MyImage         BITMAP  "images/logo.bmp"
MyEmbeddedExe   RCDATA  "bin/mybinfile.exe"
MyMailBeep      WAVE    "c:\windows\media\newmail.wav"
MyCoolVideo     AVI     "cool.avi"
MyIntroMusic    RCDATA  "introsong.mp3"
MyCursor        CURSOR  "MyCursor.cur"
STRINGTABLE
{
  1,  "&Yes"
  2,  "&No"
  17, "&Si"
  18, "&No"
  33, "&Ja"
  34, "&Nej"
}

2. Create a DLL project, with the following contents:

Project File splash.dpr (which generates splash.DLL)

library splash;       
 
{$R 'splashres.res' 'splashres.rc'}  // this includes the resources, in this case, all the splash images
 
uses
   SysUtils,
   Classes;
 
{$R *.res}  
 
begin
end.

3. Add the resource file splashrec.rc to the DLL project, so that it will contain and compile the splashres.res and splashres.rc files.

4. In Application, create a call to DLL with the resource you need to load. Use one of the available functions such as LoadBitmapFromResourceName(), LoadBitmap(), LoadIcon(), TResourceStream():

Code snippet from Form1.pas

procedure TForm1.Button1Click(Sender: TObject);
var
   h : THandle;
begin
   h := LoadLibrary('Splash.DLL');
 
   try
     Image1.Picture.Bitmap.LoadFromResourceName(H, 'BMPAUDINA');
   finally
     FreeLibrary(h);
   end;
end;
 
//-------------------------------------------------------
procedure TForm1.Button2Click(Sender: TObject);
const
  resGIF = 'aboutlogo';
var
  h:   THandle;
  gif: TGifImage;
  r:   TRect;
begin
  h := LoadLibrary('Splash.DLL');
  try
    if h <> 0 then begin
      gif := TGIFImage.Create;
      try
        gif.LoadFromResourceName(h,resGIF);
        gif.Paint(Canvas, Form1.ClientRect, [goDirectDraw]);
      finally
        gif.Free;
      end;
    end else begin
      ShowMessage('Load Resource DLL FAILED!');
    end;
  finally
    FreeLibrary(h);
  end;
end;
Inserting a JPEG Image (.jpg file) Into an Executable (.exe file)

Include the JPEG images in the resource script: MyLibRes.rc

JPEG_RedFlower  RCDATA "redflower.jpg"
JPEG_BlueFlower RCDATA "blueflower.jpg"

Recompile the resource DLL to generate the .res file (such as MyLibRes.res). Alternatively, compile file .RC to .RES with command:

C:\> BRCC32 MyLibRes.RC

Create a routine to load the JPEG resource from the Resource DLL

//------------------------------------------------------------------------------
// description: Routine to load the specified resource from the specified
//              DLL library into the specified image. It will dynamically load
//              the library and then unload it to free memory.
// parameters : [in]  LibName: string;   DLL Library name to load
//              [in]  ResName: string;   Resource name to load into image.
//              [out] img: TImage;       Image where to load resource.
// return     : None
//------------------------------------------------------------------------------
procedure TfrmMain.LoadResToImage(LibName, ResName: string; var img: TImage);
var
  H: THandle;
  MyRS: TResourceStream;
  JpegImg: TJPEGImage;
begin
 
  if FileExists(LibName) then begin
    H := LoadLibrary(PAnsiChar(LibName));  // load DLL library
    try
      // read and load resource into memory
      try
        MyRS := TResourceStream.Create(H, ResName, RT_RCDATA);      // load raw data (such as .jpg file)
        //MyRS := TResourceStream.Create(H, 'ResName', RT_BITMAP);  // load bitmap (.bmp file)
      except
        MyRS := nil;  // resource cannot be loaded or not found
      end;
 
      // load resource into TImage control
      try
        if MyRS <> nil then begin
          JpegImg := TJPEGImage.Create;       // Creation of JPEG image object
          JpegImg.LoadFromStream(MyRS);       // Loading JPEG from stream
          img.Picture.Bitmap.Assign(JPEGImg); // Assign JPEG to bitmap
          JpegImg.Destroy;                    // free memory (avoid memory leaks)
        end else begin
          img.Picture.Bitmap := nil;          // no resource, clear the bitmap
        end;
      finally
        MyRS.Free;
      end;
 
    finally
       FreeLibrary(h);   //  unload DLL library
    end;
  end;
end;

Call the LoadResToImage() function from anywhere in the application:

procedure TfrmMain.Btn2Click(Sender: TComponent);
begin
  LoadResToImage('MyLib.DLL', 'JPEG_RedFlower', Image1);
end;
Inserting a Bitmap Image (.bmp file) Into an Executable (.exe file)

Source: James Sandbrook1)

This is helpful if you do not want to have a bitmap file in the directory of the program you distribute.

One problem with inserting a bitmap file into your .exe is that it makes your programs .exe larger, so it is a good idea if your program uses small bitmap files. The Delphi example below will work on any version of Delphi above Delphi 2.

First open an editor like Notepad.exe, for this example we will use a bitmap file called <tt>Picture.bmp</tt> and this is the bitmap file we will insert into our programs .exe (Make sure that there is a picture in your folder/directory named <tt>Picture.bmp</tt>. If you do not have a picture already called <tt>Picture.bmp</tt>, you can rename a different bitmap file so that it is called <tt>Picture.bmp</tt>)

Type these words into the text file: mybmp.rc

ThePicture Bitmap "Picture.bmp"

Then save the text file as <tt>mybmp.rc</tt>

We will use BRCC32.exe that comes with Delphi and it should be in Delphi's Bin directory, to compile the file. In order to use BRCC32.exe you have to use a DOS window, using DOS is not hard at all. To run a DOS window, go to your TaskBar, click Start|Programs|MS-DOS Prompt. Whenever you use DOS, all you have to do to get back to Windows (your desktop) is type the word Exit, then press the < Enter > key.

You should have your bitmap files and your .rc file in the same folder/directory.

So we will type this sentence in the DOS window:

C:\> CD C:\Program Files\Borland\Delphi7\Bin\
C:\> Brcc32.exe C:\proj\test\mpsMyBmp.rc

The above paths may have to be changed to the place where you have Delphi installed and to the folder/directory where you have saved your files for this example.

If this does not work or you get an error, you may not have Delphi in your computers path. A way around this is for you to copy the BRCC32.exe and RW32CORE.DLL into your folder/directory that you are using, then try again. (The above files, BRCC32.exe and RW32CORE.DLL, may be different for different versions of Delphi)

Use Explorer or another File Manager and have a look in your directory, you should find that you have an extra file called mybmp.RES.

Start Delphi, then start a new project (Application).

Look for {$R *.DFM} in Unit1 and add {$R MYBMP.RES} next to it.

Add a TImage component to your form and make its AutoSize property True. Next drop a Button onto your Form, double-click on the Button and add this code:

Image1.Picture.Bitmap.LoadFromResourceName(hInstance, 'ThePicture');

Note we use 'ThePicture' to call the bitmap file. Run the program and then click on the Button, you should see the image that you put into the resource file. If you have to save the project before you can run it, save in in the same folder/directory where you have the resource (*.RES) file.

Your complete unit should look like this: Unit1.pas

unit Unit1;
 
interface
 
uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;
 
type
   TForm1 = class(TForm)
         Button1: TButton;
         Image1: TImage;
         procedure Button1Click(Sender: TObject);
     private
         { Private declarations }
     public
         { Public declarations }
   end;
 
var
    Form1: TForm1;
 
implementation
 
{$R *.DFM} {$R MYBMP.RES}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
    Image1.Picture.Bitmap.LoadFromResourceName(hInstance, 'THEPICTURE');
end;
 
end.
Extract Icons from a DLL

Use this code to extract all the icons from Shell32.dll and save them in a folder.

procedure ExtractIconsFromShell32(SavetoFolder: string);
var
  Icon: TIcon;
  ExtrFileName: string;
  NumberOfIcons, i: Integer;
begin
   ExtrFileName := IncludeTrailingBackSlash(GetSystemDir) + 'Shell32.dll'; 
   Icon := TIcon.Create;
   try
       NumberOfIcons := ExtractIcon(0, PChar(ExtrFileName), UINT(-1));
       for i := 0 to NumberOfIcons - 1 do begin
         Icon.Handle := ExtractIcon(0, PChar(ExtrFileName), i);
         Icon.Transparent := true;
         Icon.SaveToFile(IncludeTrailingBackSlash(SavetoFolder) + 'Shell32 Extracted - '+ IntToStr(i)+'.ico');
       end;
   finally
       icon.Free;
   end;
end;
 
 
 
Procedure ExtractIcon;
var
  pszFileName: Pointer;
  nIconIndex: DWORD;
begin
   if Win32Platform = VER_PLATFORM_WIN32_NT then  begin
       GetMem(pszFileName, MAX_PATH*SizeOf(WideChar));
       StringToWideChar('', pszFileName, MAX_PATH+1);
   end else begin
       GetMem(pszFileName, MAX_PATH*SizeOf(AnsiChar));
       StrPCopy(pszFileName, '');
   end;
   nIconIndex := 0;
   SHPickIcon(Handle, pszFileName, MAX_PATH, nIconIndex);
   FreeMem(pszFileName);
end;