Board index » cppbuilder » Assigning Icon from ExtractIconEx without leaks

Assigning Icon from ExtractIconEx without leaks


2008-07-01 08:58:06 PM
cppbuilder79
Hay guys, sorry for posting twice in a row, just having a bit of a nightmare
with this code. My last posts still stands, i.e. can't work out how to load
48x48 icons.
However, I've got another problem which was over looked by a type. I want
to load an icon with ExtractIconEx and assign it to TImage for display
purposes. I'm doing somehting like this:
HICON hIconSmall;
ExtractIconEx(sObject.c_str(), 0, NULL, &hIconSmall, 1);
if (hIconSmall)
{
Image->Picture->Icon->Handle = hIconSmall;
::DestroyIcon(hIconSmall);
}
- however, as soon as i call DestroyIcon - the image is lost.
So i tried using a temporary TIcon object and then using the Canvas Draw
funciton i.e.:
HICON hIconSmall;
ExtractIconEx(sObject.c_str(), 0, NULL, &hIconSmall, 1);
if (hIconSmall)
{
TIcon *icoSmall = new TIcon;
icoSmall->Handle = hIconSmall;
Image->Height = 16;
Image->Width = 16;
Image->Canvas->Draw(0, 0, icoSmall);
delete icoSmall;
::DestroyIcon(hIconSmall);
}
- this works and doesn't seem to have any resource leaks but the image is
not painted transparent - i have a white background displayed. I've tried
setting the Transparent property of the TImage but it doesn't make any
difference.
Can any one suggest a better course of action?
Many thanks, again and again and again :-)
Mike C
 
 

Re:Assigning Icon from ExtractIconEx without leaks

Mike Collins wrote:
Quote
HICON hIconSmall;
ExtractIconEx(sObject.c_str(), 0, NULL, &hIconSmall, 1);
if (hIconSmall)
{
Image->Picture->Icon->Handle = hIconSmall;
::DestroyIcon(hIconSmall);
}
- however, as soon as i call DestroyIcon - the image is lost.
Destroy the Image->Picture->Icon->Handle instead,
when you are through with it.
Quote
if (hIconSmall)
{
TIcon *icoSmall = new TIcon;
icoSmall->Handle = hIconSmall;
Image->Height = 16;
Image->Width = 16;
Image->Canvas->Draw(0, 0, icoSmall);
delete icoSmall;
::DestroyIcon(hIconSmall);
}
- this works and doesn't seem to have any resource leaks but the image is
not painted transparent - i have a white background displayed. I've tried
setting the Transparent property of the TImage but it doesn't make any
difference.
Is that a typo?
TIcon needs the transparent property.
I would think it would be
icoSmall->Transparent = TRUE;
icoSmall->SetSize(16,16);
 

Re:Assigning Icon from ExtractIconEx without leaks

"Mike Collins" <its@TheBottomOfThePost>wrote in message
Quote
- however, as soon as i call DestroyIcon - the image is lost.
Don't call DestroyIcon(). The TIcon inside the TImage is taking ownership
of the HICON handle, but then you are destroying it behind the TIcon's back.
Quote
So i tried using a temporary TIcon object and then using the
Canvas Draw funciton i.e.:
That is not necessary. Simply remove the call to DestroyIcon(). The rest
of the code is fine:
HICON hIconSmall = NULL;
::ExtractIconEx(sObject.c_str(), 0, NULL, &hIconSmall, 1);
if( hIconSmall )
Image->Picture->Icon->Handle = hIconSmall;
Quote
delete icoSmall;
::DestroyIcon(hIconSmall);
That is wrong for the same reason. The temporary TIcon owns the HICON, so
you don't need to call DestroyIcon(). The TIcon destructor will do that
automatically.
Quote
this works and doesn't seem to have any resource leaks but
the image is not painted transparent - i have a white background
displayed.
That is because you are drawing on a TBitmap that has a white background.
Quote
I've tried setting the Transparent property of the TImage but it
doesn't make any difference.
That only applies to TGraphic objects that the TImage itself displays. It
does not apply when drawing onto the TImage manually.
Gambit
 

{smallsort}

Re:Assigning Icon from ExtractIconEx without leaks

"Bob Gonder" < XXXX@XXXXX.COM >wrote in message
Quote
Destroy the Image->Picture->Icon->Handle instead,
when you are through with it.
Setting the Handle property destroys the previous HICON for you.
Gambit
 

Re:Assigning Icon from ExtractIconEx without leaks

"Mike Collins" <its@TheBottomOfThePost>wrote in message
Quote
However, I can't predict, easily, when the icon will no longer
be needed so i don't want to go down the lines of having
to free the icons handle.
You don't have to. TIcon manages that for you.
Gambit
 

Re:Assigning Icon from ExtractIconEx without leaks

Hay Bob, again, thanks for the help.
However, I can't predict, easily, when the icon will no longer be needed so
i don't want to go down the lines of having to free the icons handle.
Also, setting the icon's transparence to true has no effect. What i want to
do is render the icon to the bitmap and then free the icon resource. I can
do this but the bitmap is not painted transparent.
Any other ideas...
Mike
"Bob Gonder" < XXXX@XXXXX.COM >wrote in message
 

Re:Assigning Icon from ExtractIconEx without leaks

"Mike Collins" <its@TheBottomOfThePost>wrote in message
Quote
Once i assign HICON to the TIcon->Handle, i can basically forget
about it - the TIcon takes ownership and will be responcible for freeing
it?
Yes.
Quote
Assuming that this is correct, if i need to call the same code again,
later on in the life-span, of the application, should i call DestroyIcon()
on the TIcon->Handle before i load the new icon?
No. The Handle property's setter method will do that internally for you.
Gambit
 

Re:Assigning Icon from ExtractIconEx without leaks

Many thanks again, you always seem to clear things up.
Can i just confirm two things:
1) Once i assign HICON to the TIcon->Handle, i can basically forget about
it - the TIcon takes ownership and will be responcible for freeing it?
2) Assuming that this is correct, if i need to call the same code again,
later on in the life-span, of the application, should i call DestroyIcon()
on the TIcon->Handle before i load the new icon?
Thanks again
Mike C
"Remy
 

Re:Assigning Icon from ExtractIconEx without leaks

Hay Remy - it's not directly connected but just reply has just prompted me
to look at the system tray balloon tip icon problem that I posted about the
other week.
If you remember, I was having an issue with the balloon tip not being
displayed correctly.
I've just looked over my code for setting the balloon tip icon (which I've
shown below). After I've loaded the required icon, and sent the
Shell_NotifyIcon() notification, i delete the loaded icon using
DestroyIcon(). based on what you have just explained, could this possibly
be the cause of my problem? I've looked over some other examples on the net
and i can't find any code examples where they destroy the icon like i
have...
Any thoughts?
Mike
bool TMainForm::SetBalloonTip(const AnsiString &p_szTitle, const AnsiString
&p_szBody, DWORD p_dwIcon,
UINT p_uTimeout, bool p_bRespondUClick)
{
bool bRtn = false;
if (bTrayIconActive)
{
EnterCriticalSection(&csIPCCallBack);
try
{
HICON hIcon = NULL;
if ((p_dwIcon>= NIIF_NONE) && (p_dwIcon <= NIIF_ERROR))
{
nid.uFlags = NIF_INFO;
nid.dwInfoFlags = p_dwIcon;
}
else
{
nid.uFlags = NIF_INFO | NIF_ICON;
nid.dwInfoFlags = NIIF_USER;
hIcon = (HICON)Utils->RtnIcon(p_dwIcon, 16); //
LR_DEFAULTCOLOR);
nid.hIcon = hIcon;
}
nid.uTimeout = (p_uTimeout * 1000); // convert time to ms
lstrcpyn(nid.szInfoTitle, p_szTitle.c_str(),
MAX_TRAY_BALLOON_TITLE);
lstrcpyn(nid.szInfo, p_szBody.c_str(), MAX_TRAY_BALLOON_BODY);
if (bRtn = (bool)Shell_NotifyIcon(NIM_MODIFY, &nid))
{
lstrcpyn(nid.szInfoTitle, "\0", MAX_TRAY_BALLOON_TITLE);
lstrcpyn(nid.szInfo, "\0", MAX_TRAY_BALLOON_BODY);
}
if (hIcon)
::DestroyIcon(hIcon);
}
__finally
{
LeaveCriticalSection(&csIPCCallBack);
}
}
return bRtn;
}
 

Re:Assigning Icon from ExtractIconEx without leaks

"Mike Collins" <its@TheBottomOfThePost>wrote in message
Quote
After I've loaded the required icon, and sent the Shell_NotifyIcon()
notification, i delete the loaded icon using DestroyIcon(). based on
what you have just explained, could this possibly be the cause of
my problem?
I doubt it, since Shell_NotifyIcon() makes a copy of the specified HICON,
which the system then takes ownership of, leaving your original HICON
untouched.
What I usually do, however, is store my system tray HICON in a TIcon that
stays alive for the lifetime of the tray icon. When I want to display a new
HICON, I update the TIcon before then issuing the NIM_MODIFY request.
Gambit