I haven’t the foggiest idea why, but
‘A Tisket a Tasket a resource in a basket’ is echoing through my head.
December is usually a pretty hectic month. The period between Thanksgiving and Christmas leaves little time to do anything more than the bare minimum
a.k.a. only what is absolutely necessary. Over the past week I had the opportunity to delve into resources a bit. Fortunately, I am not talking system resources, rather the additional files that are compiled into executables and libraries. To be more specific, my venture was initiated by cursors. As usual I’ll try to keep this brief, to the point and intuitive.
For those that are unaware, Cursors and Icons are basically the same type of files. The
IconInfo structure contains the information about icons and cursors. The difference between the two is so slight that most of the time you can get away with renaming the .ico to .cur and vice versa. Within
Delphi® you can easily extract an icon or cursor resource from a file and reference it with a TIcon Class.
The TIcon Class has a nice SaveToFile method that will allow you to save your extracted resource as its own file. This works fine, well, most of the time. Occasionally I noticed that I would get a
‘Bitmap is invalid error’. I had
Google’d the newsgroups to see if anyone else had shared this mind numbing experience. I did find a few threads, however I didn’t come across any that discussed a solution or work around.
After pulling what I have left of my hair out I noticed a trend. I would consistently get this error with black and white (monochrome) cursors. Color cursors seemed to save properly. I loaded up and viewed the
IconInfo. hbmMask and
IconInfo. hbmColor bitmaps in a TImage and they looked valid. My next idea was to create a new cursor
IconInfo and fill it with the
IconInfo for the cursor that I had retrieved with the
GetIconInfo function. I then created a TIcon with that information and then saved that to a file. To my pleasure it worked like a charm.
This is the quick function that I had come up with:
var
iconwidth, iconheight : integer;
iconinfo: TIconInfo;
bmpColor,
bmpMask: TBitmap;
TransparentColor: TColor;
tempicon: TIcon;
begin
bmpColor:= TBitmap.Create;
bmpMask:= TBitmap.Create;
tempicon:= TIcon.Create;
try
iconwidth:= GetSystemMetrics(SM_CXICON);
iconheight:= GetSystemMetrics(SM_CYICON);
bmpColor.Width:= iconwidth;
bmpColor.Height:= iconheight;
// DrawIconEx(bmpColor.Canvas.Handle,0,0,icon.Handle,0,0,0,0,DI_IMAGE);
DrawIconEx(bmpColor.Canvas.Handle,0,0,icon.Handle,0,0,0,0,DI_NORMAL);
bmpMask.Width:= iconwidth;
bmpMask.Height:= iconheight;
DrawIconEx(bmpMask.Canvas.Handle,0,0,icon.Handle,0,0,0,0,DI_MASK);
GetIconInfo(icon.Handle, iconinfo);
iconinfo.fIcon:= isIcon;
iconinfo.hbmMask:= bmpMask.MaskHandle;
iconinfo.hbmColor:= bmpColor.Handle;
tempicon.Handle:= CreateIconIndirect(iconinfo);
tempicon.SaveToFile(filename);
DestroyIcon(tempicon.Handle);
DeleteObject(iconinfo.hbmMask);
DeleteObject(iconinfo.hbmColor);
finally
tempicon.Free;
bmpMask.Free;
bmpColor.Free;
end;
end;
Of course, this can be improved (formatting and code wise, does anyone know of a good
Delphi® html formatter? I tend to lose my formatting when I post these); in fact I did something like this in the latest update of
AIconExtract. The latest version includes cursor resources. Who, knows one day I may one day add the ability to edit resources....
Labels: Code, Delphi, WIN32