== 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;