== 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 Sandbrook((James M Sandbrook, http://www.sandbrooksoftware.com/DPSC/index.shtml))
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 Picture.bmp 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 Picture.bmp. If you do not have a picture already called Picture.bmp, you can rename a different bitmap file so that it is called Picture.bmp)
Type these words into the text file:
**''mybmp.rc''**
ThePicture Bitmap "Picture.bmp"
Then save the text file as mybmp.rc
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;