Il 26/12/2009 20:43, Paul Ishenin ha scritto:
Show quoted text 17 lines
Giulio Bernardi wrote:
> I have no fpc available at the moment. However, you can build yourself
> the fcl-res documentation (run makehtml.sh) in xml directory, inside
> fcl-res
> directory. There are examples for groupiconresource too.
Yes, examples are about creating an icon resource from an ico file.
> In general, if you need to use resources at runtime you should check
> Microsoft
> documentation about resources. If you need to manipulate resources
> (e.g. read
> a .ico file in a series of resources, or the other way around) use
> fcl-res.
Can't find how to do this other way around using fcl-res. I have a
resource handle and need an ico stream. At moment I implemented this
myself in Lazarus but I would like to switch to fcl-res code if it is
available (to reduce code duplication).
fcl-res is not meant to work with resources at runtime: it is a framework designed to be used by resource compilers or developer tools (e.g. Lazarus could use it to directly generate .res files, instead writing .rc files and relying on windres, that AFAIK is also not endian-safe and produces garbage on big endian machines).
I think it could be possible to write a "runtime reader" that doesn't read resources from a file but uses LoadResource and friends. However maybe this could bloat lcl and slow things down.
I quickly looked at commit 23290. A couple of things: use makeintresource instead of doing pchar(resid), since this might change in the future, and pay attention to the endianess: all data structures are little endian.
Now, I have some doubts: rebuilding an .ico stream seems an overkill to me. I've not been using GUI stuff like lazarus or delphi since some times, so I might be wrong in the following lines.
Isn't TIcon supposed to contain a single icon, and not a whole set of icons as defined in a .ico file or in a RT_GROUP_ICON resource? This is because googling I found some example code that does things like this:
icon.handle:=LoadIcon(hInstance,'MYICON');
Now, LoadIcon (or LoadImage) loads a single icon from the set (it loads the "best" icon).
Looking at MS documentation about LoadImage, it seems that things work like this: with loadimage you specify a desired size for the icon, and the system tries to load the icon with that size. If you don't specify it, it will load the best one according to system metrics (so probably loadicon calls loadimage in this way), or the first one if you don't use LR_DEFAULTSIZE flag.
I suppose that TIcon.LoadFromStream loads the first icon in the .ico stream. Can you confirm it?
Now, what does delphi do with LoadFromResourceName and LoadFromResourceID? Because I think that instead of calling LoadFromStream, the thing to do would be self.handle := LoadImage(blah blah blah);
This could be accomplished in lazarus by writing a LoadImage function that scans the RT_GROUP_ICON resource to find the desired icon, and then returns the handle of the desired RT_ICON, which can be loaded as a bitmap (plus the mask) or as a PNG (from vista onwards afaik).
Note: I think windows returns an HICON, I don't know if it's the same thing of an RT_ICON handle or not.
Another possibility is that LoadFromStream doesn't work with RT_(GROUP_)ICONs but it expects a standard .ico/.bmp/.png/whatever stream instead (e.g. stored as RT_RCDATA) but it seems a bit strange to me.
I looked at those methods' documentation on embarcadero website but it's not so clear.
Giulio