Opened 14 years ago

Closed 14 years ago

Last modified 14 years ago

#1655 closed Bug (No Bug)

GUICtrlSetImage issue on static controls

Reported by: trancexx Owned by:
Milestone: Component: AutoIt
Version: Severity: None
Keywords: Cc:


This function causes a memory leak (GDI objects) in combination with STM_SETIMAGE or STM_SETICON messages send directly to the control.
Seems this function destroys images assigned only by a previous call to itself (or those set when creating the control).
If some image is set with GUICtrlSendMsg it won't be destroyed.
I guess there is nothing wrong with that logic except it's, in described situation, setting new image without destroying the old one, therefore incrementing overall GDI Objects count only because it's not aware of the already assigned image.
More proper would be to destroy previously assigned image regardless of how it's set.

This can be concluded by carefully(!) examining the effects of e.g. this code:

#include <WinAPI.au3>
#include <GUIConstantsEx.au3>
Opt('MustDeclareVars', 1)
Opt("GUIOnEventMode", 1)

Global $hIconNew, $hIconOld

Global $hGUI = GUICreate("GUICtrlCreateIcon")

GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")
Global $hIcoControl = GUICtrlCreateIcon("", "", 20, 75, 32, 32) ; no icon

While 1

	$hIconNew = _GetIcon("shell32.dll", 8, 32)
	ConsoleWrite("$hIconNew = " & $hIconNew & @CRLF)
	;GUICtrlSendMsg($hIco, 368, $hIcon, 0) ; STM_SETICON version, or:
	$hIconOld = GUICtrlSendMsg($hIcoControl, 370, 1, $hIconNew) ; STM_SETIMAGE
	ConsoleWrite("$hOld = " & Ptr($hIconOld) & @CRLF)
	; _WinAPI_DestroyIcon($hIconOld) ; I can omit this because GUICtrlSetImage will do it for me on the next call


	;_WinAPI_DestroyIcon(GUICtrlSendMsg($hIcoControl, 369, 0, 0)) ; STM_GETICON. Ommiting this on the other hand causes a leak
	; Btw, that's the same as:

	ConsoleWrite("Assigned icon before GUICtrlSetImage = " & Ptr(GUICtrlSendMsg($hIcoControl, 369, 0, 0)) & @CRLF) ; STM_GETICON
	ConsoleWrite("GUICtrlSetImage returns " & GUICtrlSetImage($hIcoControl, "shell32.dll", 5) & @CRLF)
	ConsoleWrite("Assigned icon after GUICtrlSetImage = " & Ptr(GUICtrlSendMsg($hIcoControl, 369, 0, 0)) & @CRLF) ; STM_GETICON




Func _GetIcon($sModule, $iName, $iSize) ; for loaded modules
	Local $hModule = _WinAPI_GetModuleHandle($sModule)
	If @error Then Return SetError(1, 0, 0)
	Local $hIcon = _WinAPI_LoadImage($hModule, $iName, 1, $iSize, $iSize, 0) ; IMAGE_ICON, LR_DEFAULTCOLOR
	If @error Then Return SetError(2, 0, 0)
	Return $hIcon
EndFunc   ;==>_GetIcon

Func _Quit()
EndFunc   ;==>_Quit

GDI Objects count can be monitored with task manager.

Attachments (0)

Change History (2)

comment:1 Changed 14 years ago by Jpm

  • Resolution set to No Bug
  • Status changed from new to closed

If you do something behind the Builtin function GUICtrlSetImage() on something created with GuiCtrlCreateIcon() or GuiCtrlCreatePic() you get the behavior you describe which is you responsability to manage. The GUICtrlSendMsg is sending the message without any relation with GUICtrlSetImage so you are creating the leak.

Mixing Builtin GUI...() with UDF _...() is not fully supported. Some mixing works some does not.

comment:2 Changed 14 years ago by trancexx

Ok, thanks for the response.

Still, that doesn't mean it's right to assign the new image to the control without destroying what's found there. If it is then you wouldn't be destroying at all with GUICtrlSetImage().

Guidelines for posting comments:

  • You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
  • In-depth discussions should take place on the forum.

For more information see the full version of the ticket guidelines here.

Add Comment

Modify Ticket

as closed The ticket will remain with no owner.

E-mail address and user name can be saved in the Preferences.

Note: See TracTickets for help on using tickets.