[SOLVED] Including an existing .res file lazarus / 39-Graphics ---------------------------------------------------------------------- TyneBridges · 2013-04-17 18:30 I'm very confused about how to add icons to my application, even after reading the Wiki http://wiki.freepascal.org/Lazarus_Resources#FPC_resources QuoteStarting from FPC 2.4 you can use standard .rc (resource script) and .res (compiled resource) files in your project to include resources. To turn a .rc script used in the sources into a binary resource (.res file), FPC runs the appropriate external resource compiler (windres or GoRC). Therefore that resource compiler needs to be installed and present in the PATH environment variable. For more details, see: FPC Programmer's guide, chapter 13 "Using Windows resources" To simplify the compiling process, it is possible 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 in Visual Studio), Borland resource compiler (brcc32.exe included in 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. I have an application lclient.lpi (lclient.exe) with the directive {$R *.res} in lclient.lpr. I've used the Borland Image Editor that came with Delphi 5 to add an icon to the file lclient.res and saved this. I can see the .res file increase in size, and its time change, when I do this. However, when I then compile my application, Lazarus overwrites the .res file. This reduces in size again and my icon disappears. Can anyone tell me what I'm doing wrong? Is the image editor too old (I noticed that it seems to support a maximum icon size of 32 x 32) and, if so, can anyone recommend another visual editor that is able to save correctly into .res files? ---------------------------------------------------------------------- BigChimp · 2013-04-17 18:49 Wild guess: there is also an .rc file in that directory and Lazarus for some reason decides to throw it's own (well, windres.exe) resource  compiler at it... No idea if that is how it works though. ---------------------------------------------------------------------- TyneBridges · 2013-04-17 18:54 Quote from: BigChimp on April 17, 2013, 08:49:15 pmWild guess: there is also an .rc file in that directory and Lazarus for some reason decides to throw it's own (well, windres.exe) resource  compiler at it... No idea if that is how it works though. Thanks for the hint, BigChimp but nope - I can't see an .rc file there. (I've managed to load the icons using "LoadFromFile" but find that clumsy and would really like to include them in the .exe.) ---------------------------------------------------------------------- marcov · 2013-04-17 18:58 Don't name the res file the same as the form? That name is resolved for the resources for that form (afaik, also for Delphi) ---------------------------------------------------------------------- TyneBridges · 2013-04-18 10:18 Thanks for the advice, Marcov, but it didn't seem to help. If I create a new resource file and add {$R icons.res} to the form declaration I get an error from the linker, whether I put this line in before or after the word implementation: Error: Duplicate resource: Type = 3, Name = 0, Lang ID = 0000 As far as I can see, nothing is duplicated in my resources - tests have involved only one icon in the application (no other explicitly added resources) and still fail. The only way to get rid of this linker error seems to be to remove the extra declaration. I'm now using a different image editor but Lazarus treats its resource files the same way, and overwrites them during compilation if they have the same name as the project. This didn't happen for me with Delphi 2, 3 or 5. I've checked my old Delphi projects and all of these (including ones that use a trayicon) seem to have a .res file with the same name as the project. (Julien Audo's programme ResEdit doesn't like the .res files automatically created by Lazarus and shows "An error occurred while importing a resource" each time I load one.) ---------------------------------------------------------------------- typo · 2013-04-18 10:25 Check whether the resource itself has the same name (for example, Icon) as the icon which is created by Lazarus for the program. AFAIK Lazarus main icon has the name MAINICON. I am trying to reproduce your problem, but when I write Code: [Select]{$R *.lfm} {$R a1super.res}  // existing resource, a JPG file called a1super.jpg inside a compiled RES file I have no errors. My RC file has this format: Code: [Select]a1super DATA "path\a1super.jpg" and I have compiled it with GoRC.exe. ---------------------------------------------------------------------- BigChimp · 2013-04-18 10:39 Perhaps it's time to upload a demo zip with the faulty program & resource etc. ---------------------------------------------------------------------- TyneBridges · 2013-04-18 10:56 Quote from: typo on April 18, 2013, 12:25:40 pmCheck whether the resource itself has the same name (for example, Icon) as the icon which is created by Lazarus for the program. AFAIK Lazarus main icon has the name MAINICON. I am trying to reproduce your problem, but when I write Code: [Select]{$R *.lfm} {$R a1super.res}  // existing resource, a JPG file called a1super.jpg inside a compiled RES file I have no errors. My RC file has this format: Code: [Select]a1super DATA "path\1super.jpg" I've checked that. My .res file is called icons.res and contains two icons (not one, as I said earlier) -  ICONFULL and THREEQU. However, I haven't touched any .rc files, as I didn't need these in Delphi and I haven't been able to find any step-by-step instruction on how to add an icon or two to a resource file in Lazarus: maybe ignoring the .rc is my mistake? I'm uploading the zip as requested. Thanks to everyone for your help so far. ---------------------------------------------------------------------- typo · 2013-04-18 11:06 My error message is : lclient.lpr(26,1) Error: Error while compiling resources. Compile with -vd for more details. Check for duplicates. GoRC.exe is on your FPC directory. You must provide an RC file with that format. ---------------------------------------------------------------------- BigChimp · 2013-04-18 11:18 In contrast to typo, I don't have that error. I have the same error Chris sees, in both 1.0.8 and trunk x86, Windows: Code: [Select]Error: Duplicate resource: Type = 3, Name = 0, Lang ID = 0000 Looking further, if I run the rstconv.exe tool included with fcp (in the utils dir) to try and convert the .res back to .rc Code: [Select]rstconv -i d:\cop\t\icons.res -o d:\cop\t\iconstest.rc -f rc I get this iconstest.rc: Code: [Select]MESSAGETABLE BEGIN /* :*/ /*  */ 0 "" END So FPC probably sees the .res as a resource without name?!?! (or rstconv lacks features, or I ran it incorrectly) ---------------------------------------------------------------------- typo · 2013-04-18 11:26 I have added an icon called lazarus.ico on your project and it compiles. Check it out (attached). Anyway, I see that ICONS.RES file is much smaller than LAZARUS.RES in size, so it might have less or no data on it. ---------------------------------------------------------------------- TyneBridges · 2013-04-18 11:52 Thanks for the files, Typo. I can see that your version compiles but don't know how to substitute my own resources. In the Wiki http://wiki.freepascal.org/Lazarus_Resources the section "FPC Resources" says "To simplify the compiling process, it is possible to use only the compiled resources in the .res files" (as in Delphi). Obviously that didn't work for me and I still don't understand why. If I do need to use an .rc file, presumably I need to save my icons as separate .ico files. Can someone point me to a simple example of an rc file? Even a Google search didn't seem to bring up anything that showed in a straightforward way how to list a couple of icons. ---------------------------------------------------------------------- typo · 2013-04-18 12:04 RC is a text file on ANSI format with RC extension which has something like that: a1super DATA "C:\lazarus\images\1super.jpg" brown DATA "C:\lazarus\images\icons\brown.ico" each line for a file. The first string is its name, the second is its type and the third is its filename. RC format is a Microsoft standard. ---------------------------------------------------------------------- BigChimp · 2013-04-18 12:36 Quote from: JohnSaltwell on April 18, 2013, 01:52:18 pmIf I do need to use an .rc file, presumably I need to save my icons as separate .ico files. Can someone point me to a simple example of an rc file? Even a Google search didn't seem to bring up anything that showed in a straightforward way how to list a couple of icons. The wiki page has an example of an .rc file as well as a link to the ms documentation on resource data types. Edit: http://wiki.lazarus.freepascal.org/Lazarus_Resources#Adding_resources_ to_your_program This obivously wasn't enough for you, so... please feel free (if you have the time & inclination) to improve that article so others won't face the same trouble... Thanks! ---------------------------------------------------------------------- typo · 2013-04-18 12:57 Of course FPC compiles RC file, no need of GoRC.exe. ---------------------------------------------------------------------- taazz · 2013-04-18 13:15 personally I avoid .rc files and I use the following resource editor on windows http://www.wilsonc.demon.co.uk/d10resourceeditor.htm. It has been a great help over the years. After I rebuild the icons.res with XN Resource Editor you applications compiled with no problems. ---------------------------------------------------------------------- TyneBridges · 2013-04-18 15:50 This does seem to be a very difficult (if not impossible) aspect of Lazarus. Typo's example of an rc file seemed to be just what I was looking for. I initially tried putting my icon files in the same folder as my project, but seemed to run into the Lazarus bug where problems are caused if the application is installed in a path with spaces (mine is in C:\Lazarus but my project name has spaces in it). The linking of the resources failed on the first line with an error about an invalid path, but showing a corrupted path name. I then created a new folder in the root of C:, put the images in there as separate .ico files and created lclient.rc as follows: Code: [Select]iconfull DATA "c:\images\iconfull.ico" threequ DATA "c:\images\threequ.ico" half DATA "c:\images\half.ico" quarter DATA "c:\images\quarter.ico" empty DATA "c:\images\empty.ico" When I changed {$R *.res} to {$R *.rc} in lclient.lpr and attempted to recompile, this gave the error Quotewindres: can't open file `c:\imageshreequ.ico': Invalid argument As you can see, this is not the argument I'm sending to Lazarus (or windres) and I'm baffled as to why it fails on this line when it apparently accepts the previous line, with the same path in the same format. Any ideas? ---------------------------------------------------------------------- TyneBridges · 2013-04-18 15:51 Quote from: taazz on April 18, 2013, 03:15:43 pmpersonally I avoid .rc files and I use the following resource editor on windows http://www.wilsonc.demon.co.uk/d10resourceeditor.htm. It has been a great help over the years. After I rebuild the icons.res with XN Resource Editor you applications compiled with no problems. Thanks for that, taazz. I missed your post earlier but will give that a try. ---------------------------------------------------------------------- typo · 2013-04-18 15:55 Quote from: JohnSaltwell on April 18, 2013, 05:50:33 pmAny ideas? Of course. The thing is easier than it seems to be. {$R *.res} is refering to the project res file, you need to write {$R icons.res} or {$R icons.rc}, which should be also the name of your res or rc file. ---------------------------------------------------------------------- TyneBridges · 2013-04-18 16:07 Quote from: typo on April 18, 2013, 05:55:30 pmQuote from: JohnSaltwell on April 18, 2013, 05:50:33 pmAny ideas? Of course. The thing is easier than it seems to be. {$R *.res} is refering to the project res file, you need to write {$R icons.res} or {$R icons.rc}, which should be also the name of your res or rc file. Afraid not - I've tried renaming the file and changing the line in lclient.lpr to {$R icons.rc} and I still get the same error about an invalid argument on line 2 of the .rc file. ---------------------------------------------------------------------- typo · 2013-04-18 16:12 Your RC file seems to be OK. Check whether the files exist on the path. Your RC file compiles here without any error. GoRC.exe gives a file not found error. ---------------------------------------------------------------------- TyneBridges · 2013-04-18 18:26 Quote from: typo on April 18, 2013, 06:12:27 pmYour RC file seems to be OK. Check whether the files exist on the path. Your RC file compiles here without any error. Thanks for your time. I seem to be having one of those days today. I've checked and the file threequ.ico is definitely there in C:\Images. I've erased images.rc and created it again but still get the error on line 2 with the garbled path. I've also tried renaming the images folder as "lazres" and amending the file and the error then changes to "windres: can't open file `c:\lazreshreequ.ico': Invalid argument"! I've copied the project to my laptop that has a stable/official version of Lazarus 1.0.8 and that gives the same error... As an alternative I've tried XN Resource Editor as recommended by taazz, but that has just crashed for the third time, corrupting my resource file again. I had plenty of hair this morning but may be bald by bedtime... Edit: The error is on the characters "\t"...doesn't that character combination have a special meaning in C based languages? That would suggest a bug somewhere in handling Windows paths. Further edit: removing the path from the rc file altogether and putting the icon files in the project source folder allows the application to compile, but I then get an error on each icon I attempt to load: Code: [Select]TI.Icon.Handle:= LoadIcon(hInstance, MakeIntResource(OurIcon)); If TI.Icon.Handle = 0 then ShowMessage('Error loading icon ' + OurIcon);    It looks to me as if my .rc file is not correct - other applications list icons as "Icon Group", not just "Data". ---------------------------------------------------------------------- taazz · 2013-04-18 23:38 Resource-Definition Statements http://msdn.microsoft.com/en- us/library/windows/desktop/aa381043%28v=vs.85%29.aspx I have never seen xn resource editor crash so I cant be of any help but even if it did crash the original file is backed up before saving so you are safe. You can find a lot of resource editors on the internet just do a search and avoid any .net resource editors. ---------------------------------------------------------------------- TyneBridges · 2013-04-19 08:01 I do seem to be encountering a few bugs in Lazarus or its supporting software. I've found that loading resources from an rc file only works for me if this is in the following form: Quotei1 ICON "i1.ico" i2 ICON "i2.ico" i3 ICON "i3.ico" i4 ICON "i4.ico" i5 ICON "i5.ico" That is, there are no file paths listed (the software seems to corrupt these, taking the characters "\t" as escape characters when they are part of the path) and the resources are in the application source folder. (Incidentally, my code can only find the icons if they are listed as ICON rather than DATA as suggested earlier.) There also appears to be a bug in the trayicon component. I use the following to load several different icons, depending on a value fed to the timer process. Code: [Select]procedure TLCIForm.DrawSTIcon(ProportionRemaining: Byte); Var OurIcon: String; begin     Case ProportionRemaining of           90..100: OurIcon:= 'i1';  // Full           70..89: OurIcon:= 'i2';           50..69: OurIcon:= 'i3';           25..49: OurIcon:= 'i4';           0..24: OurIcon:= 'i5';  // Empty      end; // case      NewIcon:= OurIcon;      If LastIcon <> NewIcon then      begin           ShowMessage('About to change icon to ' + OurIcon);           TI.Icon.Handle:= LoadIcon(hInstance, MakeIntResource(OurIcon));           If TI.Icon.Handle = 0 then ShowMessage('Error loading icon ' + OurIcon);           TI.Hint:= 'Time remaining indicated by black bar (' + IntToStr(ProportionRemaining) + ')';           //TI.PopUpMenu:= MyPopUpMenu;           TI.Show;           //ShowMessage(IntToStr(ProportionRemaining));           LastIcon:= NewIcon;      end; end;  The first two icons are loaded correctly but I get an External: SIGSEGV error on the third. I have debugging switched on, but all I can see is that the error occurs in the following bit of code in icon.inc (TCustomIcon) Code: [Select]procedure TSharedIcon.Clear; var   n: Integer; begin   for n := 0 to FImages.Count - 1 do     TObject(FImages[n]).Free; end;  I've added watches for n and FImages.Count and have debug info switched on but the debugger is not helping - it just shows "No symbol in current context", even when I'm using "Step into" to go through the lines above one by one. I've tried to research whether I need to free resources to allow several different icons to load, but an answer on this link suggests not. http://stackoverflow.com/questions/15556817/is-a-memory-leak-possible- with-loadicon Once again, I'm stumped. Should I start a new thread for the apparent bug in TTrayIcon? ---------------------------------------------------------------------- BigChimp · 2013-04-19 09:47 Perhaps no solutions but some comments: Regarding paths & resources: does the Microsoft specifications actually indicate paths are supported? They may very well not be. (No idea myself, I never use paths with my resources) Regarding ICON or DATA resources, AFAIR, the wiki page has an example of using DATA. I also use it in my Checkride program (see bitbucket link in signature). Regardless, if they're icons, using ICON makes sense Even if they are, you found out the version of windres (or perhaps gorc) included with Lazarus don't like spaces. If I were you, I would just always store my projects in paths without spaces instead of fighting the system. Regarding trayicon stuff: yes please start a new thread. It's a new subject after all.. ---------------------------------------------------------------------- typo · 2013-04-19 11:09 Yes, JohnSaltwell is right. It seems that FPC refuses full path for the files on RC. But GoRC.exe accepts them. ---------------------------------------------------------------------- BigChimp · 2013-04-19 11:19 Quote from: typo on April 19, 2013, 01:09:46 pmIt seems that FPC refuses full path for the files on RC. By FPC, do you mean windres.exe? AFAIU that's the default resource compiler run on Windows. ---------------------------------------------------------------------- ChrisF · 2013-04-19 12:39 Hello, Code: [Select]iconfull DATA c:\images\iconfull.ico threequ DATA c:\images\threequ.ico half DATA c:\images\half.ico quarter DATA c:\images\quarter.ico empty DATA c:\images\empty.ico is compiling fine here (no " characters). And it's really windres which is called. windres is the by default windows resource file compiler, but only for win32 and cross compiling linux->windows. For win64, GorRc is used instead. BTW, don't use the by-default lazarus resource file, if you plan to include your own resources. Create you own one, and add it into your .lpr file. For instance (if I use Main.rc): Code: [Select]{$R *.res} {$IFDEF FPC}   {$R 'Main.rc'} {$ELSE}   {$R 'Main.res' 'Main.rc'} {$ENDIF} Finally, why are using DATA to integrate icons ? I'm not sure you can use LoadIcon for DATA windows resource. Just declare them as ICON type: Code: [Select]iconfull ICON c:\images\iconfull.ico threequ ICON c:\images\threequ.ico half ICON c:\images\half.ico quarter ICON c:\images\quarter.ico empty ICON c:\images\empty.ico It's working fine for me, and I have several icons in some of my programs. Anyway, there is a problem with LoadIcon, LodCursor and LoadBitMap: see http://bugs.freepascal.org/view.php?id=24222. So, you can load them by explicitly casting the windows unit. For instance: Code: [Select]hIcon:=Windows.LoadIcon(MainInstance,'MyICONName01'); ---------------------------------------------------------------------- BigChimp · 2013-04-19 13:02 Given ChrisF's response and as your forum signature indicates you're using x86 FPC/Laz, not x64, I would check that there's no old windres.exe in your path or your fpc/bin directory. Mine (Laz 1.0.: Code: [Select]C:\Lazarus\fpc\2.6.2\bin\i386-win32 02-10-2011  00:04           662.542 windres.exe windres --version GNU windres (GNU Binutils) 2.21.1 Copyright 2011 Free Software Foundation, Inc. [code]