Difference between revisions of "Lazarus Resources"
m (→FPC resources) |
(category) |
||
Line 15: | Line 15: | ||
Example: | Example: | ||
− | < | + | <delphi>procedure exampleproc; |
var | var | ||
Image: TImage | Image: TImage | ||
Line 24: | Line 24: | ||
initialization | initialization | ||
− | {$I mylazarusresource.lrs} | + | {$I mylazarusresource.lrs}</delphi> |
− | </ | + | |
This code includes the file mylazarusresource.lrs into the project. In the procedure exampleproc an icon object is created and loaded from the object "image" out of the resource. The file which was compiled into the resource was probably named image.jpg. | This code includes the file mylazarusresource.lrs into the project. In the procedure exampleproc an icon object is created and loaded from the object "image" out of the resource. The file which was compiled into the resource was probably named image.jpg. | ||
Line 44: | Line 44: | ||
You can retrieve the data of the resource with: | You can retrieve the data of the resource with: | ||
− | <Delphi> | + | <Delphi>uses ...LResources...; |
− | uses ...LResources...; | ||
... | ... | ||
Line 57: | Line 56: | ||
Data:=r.Value; | Data:=r.Value; | ||
...do something with the data... | ...do something with the data... | ||
− | end; | + | end;</Delphi> |
− | </Delphi> | ||
== FPC resources == | == FPC resources == | ||
Line 79: | Line 77: | ||
Res file is ready. Let's include it into your project: | Res file is ready. Let's include it into your project: | ||
− | <delphi> | + | <delphi>program mydata; |
− | program mydata; | ||
{$R mydata.res} | {$R mydata.res} | ||
begin | begin | ||
− | end. | + | end.</delphi> |
− | </delphi> | ||
Now let's extract the stored resource into the mydata.dat file: | Now let's extract the stored resource into the mydata.dat file: | ||
− | <delphi> | + | <delphi>program mydata; |
− | program mydata; | ||
uses | uses | ||
SysUtils; | SysUtils; | ||
Line 97: | Line 92: | ||
F: TFileStream; | F: TFileStream; | ||
begin | begin | ||
− | S := TResourceStream.Create(HInstance, 'MYDATA', RT_RCDATA); | + | // create a resource stream which points to our resource |
+ | S := TResourceStream.Create(HInstance, 'MYDATA', RT_RCDATA); | ||
try | try | ||
− | F := TFileStream.Create(ExtractFilePath(ParamStr(0)) + 'mydata.dat', fmCreate); | + | // create a file mydata.dat in the application directory |
+ | F := TFileStream.Create(ExtractFilePath(ParamStr(0)) + 'mydata.dat', fmCreate); | ||
try | try | ||
F.CopyFrom(S, S.Size); // copy data from the resource stream to file stream | F.CopyFrom(S, S.Size); // copy data from the resource stream to file stream | ||
Line 108: | Line 105: | ||
S.Free; // destroy the resource stream | S.Free; // destroy the resource stream | ||
end; | end; | ||
− | end. | + | end.</delphi> |
− | </delphi> | ||
− | + | [[Category:Tutorials]] | |
− | [[ | ||
− |
Revision as of 16:24, 25 December 2010
│
Deutsch (de) │
English (en) │
español (es) │
français (fr) │
한국어 (ko) │
русский (ru) │
Every win32 developer should know about resource files. They contain data which should be compiled into the exe file. That data could consist of images, string tables, version info, ... even an XP manifest and forms.
Before FPC 2.4 it was not possible to use "normal" resource files (*.res) in Lazarus because they were win32 specific. In order to use your, you had to recreate them with lazres. Lazres can be found in the "Tools" directory (C:\Lazarus\Tools\ - You have to compile the lazres.lpi first)of your Lazarus installation folder (maybe you will first have to compile it).
Then you can compile Lazarus resource files (*.lrs) via command line. The syntax for lazres is:
lazres <filename of resource file> <files to include (file1 file2 file3 ...)>
Example:
lazres mylazarusresource.lrs image.jpg
To use a lazarus resource file in your projects include the file with the $I compiler directive in the initialization section of your unit.
You can access the data in the resources directly or with the LoadFromLazarusResource method of the variables which will hold the file contents afterwards. LoadFromLazarusResource requires one string parameter which indicades which object should be loaded from the resource file.
Example: <delphi>procedure exampleproc; var
Image: TImage
begin
Image := TImage.Create; Image.Picture.LoadFromLazarusResource('image'); // note that there is no need for the extension
end;
initialization
{$I mylazarusresource.lrs}</delphi>
This code includes the file mylazarusresource.lrs into the project. In the procedure exampleproc an icon object is created and loaded from the object "image" out of the resource. The file which was compiled into the resource was probably named image.jpg.
Every class that is derived from TGraphic contains the LoadFromLazarusResource procedure.
Lazarus Resource Form File
Lazarus generate .LRS file from .LFM Form files.
When a LRS form file is missing, FPC reports the following error: ERROR: unit1.pas(193,4) Fatal: Can't open include file "unit1.lrs"
To solve it you must use lazres: c:\lazarus\tools\lazres.exe unit1.lrs unit1.lfm
The easiest way to recreate a .lrs file to make a trivial change in the form design, revert it and save the form, no need to use lazres. Vincent 09:47, 6 January 2009 (CET)
Getting the raw data of a lrs resource
You can retrieve the data of the resource with:
<Delphi>uses ...LResources...;
... procedure TForm1.FormCreate(Sender: TObject); var
r: TLResource; Data: String;
begin
r:=LazarusResources.Find('datafile1'); if r=nil then raise Exception.Create('resource datafile1 is missing'); Data:=r.Value; ...do something with the data...
end;</Delphi>
FPC resources
Starting from FPC 2.4 you can use regular .rc and .res files in your project to include resources. FPC runs the appropriate external resource compiler (windres or GoRC) when .rc file is used in the sources and therefore it is required to have that resource compiler to be installed and present in the PATH environment variable. To simplify the compiling process better to use only the compiled resources in the .res files. You can precompile the resources by any available resource compiler - windres (available both on unixes and windows), GoRC (windows only), Microsoft resource compiler (rc.exe included into Visual Studio), Borland resource compiler (brcc32.exe included into Delphi, C++ Builder or Rad Studio products) or any other.
Use {$R filename.rc} or {$R filename.res} directive to include a resource file into the executable. FPC RTL provides both low-level functions as well as high-level classes to access resources.
The low-level functions are: EnumResourceTypes, EnumResourceNames, EnumResourceLanguages, FindResource, FindResourceEx, LoadResource, SizeofResource, LockResource, UnlockResource, FreeResource. They are compatible to the windows api functions: http://msdn.microsoft.com/en-us/library/ff468902(VS.85).aspx
The main class to work with resources is TResourceStream. LCL uses it to load embedded bitmaps, icons and form streams. Look at TGraphic.LoadFromResourceID or TIcon.LoadFromResourceHandle to see how it is used inside LCL.
Let's review the situation when you need to store some data inside your executable and during the program run you want to extract this data from it.
We need to create the .res file. We can first prepare a .rc and then compile it. mydata.rc file:
MYDATA RCDATA "mydata.dat"
Where MYDATA is the resource name, RCDATA is the type of resource (look here http://msdn.microsoft.com/en-us/library/ms648009(VS.85).aspx for types exaplanation) and "mydata.dat" is a your data file. Let's compile it using the borland resource compiler:
brcc32 mydata.rc
Res file is ready. Let's include it into your project: <delphi>program mydata;
{$R mydata.res} begin end.</delphi>
Now let's extract the stored resource into the mydata.dat file: <delphi>program mydata; uses
SysUtils;
{$R mydata.res} var
S: TResourceStream; F: TFileStream;
begin
// create a resource stream which points to our resource S := TResourceStream.Create(HInstance, 'MYDATA', RT_RCDATA); try // create a file mydata.dat in the application directory F := TFileStream.Create(ExtractFilePath(ParamStr(0)) + 'mydata.dat', fmCreate); try F.CopyFrom(S, S.Size); // copy data from the resource stream to file stream finally F.Free; // destroy the file stream end; finally S.Free; // destroy the resource stream end;
end.</delphi>