Sign in to follow this  
Followers 0

Icons UDF

69 posts in this topic

Posted (edited) · Report post

LAST VERSION - 1.8

02-Nov-09

Deprecated.

The library contains three basic functions. I always use these functions and decided to share them with the community. I hope that to some of you they will be useful. To understand why this is done, please look at my examples.

Icons.png

History

1.8

  • Updated the reducing flicker algorithm - _Icons_Control_Update(), now the upper windows will be redrawn.
  • Improved performance for all main functions.
  • Added one new example to benchmark the reducing flicker algorithm.
  • Fixed few minor bugs.
1.7
  • Completely rewritten the internal code of the library.
  • ]$fErase parameter replaced to $hOverlap that makes the opposite effect. (See description)
  • All the internal functions have been renamed.
  • Added some internal functions. (See expamples 5 and 6)
  • Function _Icons_Icon_Merge() (formerly _Icons_CombineIcon()) now works with icon handles.
  • Improved performance for the _SetCombineBkIcon() function.
  • Added two new examples.
1.6
  • Added compatibility with the MrCreatoR's GUICtrlSetOnHover UDF library. (See GUICtrlSetOnHover & Icons UDFs Demonstration below)
  • Added mode to reduce flickering when changing images in the controls.
  • Added parameter $fErase for all functions. Because the reduce flickering mode is enabled by default, but in some cases it must be disabled. (See example 4)
  • Fixed bug consists in the wrong determinates the size of controls after cleaning their by using _SetImage($hWnd, "") or _SetHImage($hWnd, 0) functions.
  • Fixed bug consists in the wrong determinates the background color of the icons in _SetCombineBkIcon() function if the window is invisible.
  • Internal _Icons_SetImage() function is completely rewritten and improved.
  • Slightly improved performance.
1.5
  • Added resizing image, depending on the size of control. (Thanks wraithdu, Post #19)
  • Added some new opportunities for _SetCombineBkIcon() function. (See description inside the library)
  • Now you can use the one handle for the few controls. _SetHIcon() and _SetHImage() function makes a copy of HIcon and HBitmap handles.
  • Added the ability to automatically determine the background color of the window for the _SetCombineBkIcon() function.
  • Fixed bug consists in the wrong value of the $SS_BITMAP constant. (Thanks wraithdu, Post #17)
  • Fixed bug consists in memory leaks when using _SetImage() and _SetHImage() functions. (Thanks wraithdu, Post #28)
  • Fixed bug consists in unnecessary to convert the values for the style.
  • The code was completely rewritten and improved.
  • Added four new examples.

Available functions

Basic

_SetCombineBkIcon

_SetIcon

_SetImage

Additional

_SetHIcon

_SetHImage

Not documented (Internal)

_Icons_Bitmap_Crop

_Icons_Bitmap_CreateFromIcon

_Icons_Bitmap_CreateSolidBitmap

_Icons_Bitmap_Duplicate

_Icons_Bitmap_GetSize

_Icons_Bitmap_IsAlpha

_Icons_Bitmap_IsHBitmap

_Icons_Bitmap_Load

_Icons_Bitmap_Resize

_Icons_Control_CheckHandle

_Icons_Control_CheckSize

_Icons_Control_Enum

_Icons_Control_FitTo

_Icons_Control_GetRect

_Icons_Control_GetSize

_Icons_Control_Invalidate

_Icons_Control_SetImage

_Icons_Control_Update

_Icons_Icon_Duplicate

_Icons_Icon_Extract

_Icons_Icon_CreateFromBitmap

_Icons_Icon_GetSize

_Icons_Icon_Merge

_Icons_System_GetColor

_Icons_System_SwitchColor

Icons UDF Library v1.8

Previous downloads: 1268

Icons.au3

Example

#Include <GUIConstantsEx.au3>
#Include <Icons.au3>

Global Const $sPng = RegRead('HKLM\SOFTWARE\AutoIt v3\AutoIt', 'InstallDir') & '\Examples\GUI\Advanced\Images\Torus.png'
Global Const $sJpg = @TempDir & '\~wallpaper.jpg'
Global Const $sGreen = @TempDir & '\~green.png'
Global Const $sRed = @TempDir & '\~red.png'
Global Const $sLogo = @TempDir & '\~logo.png'

Example1()
Example2()
Example3()
Example4()
Example5()
Example6()
Example7()

Func Example1()

	GUICreate('Example1', 204, 108)
	$Icon1 = GUICtrlCreateIcon('', 0, 30, 38, 32, 32)
	$Icon2 = GUICtrlCreateIcon('', 0, 88, 38, 32, 32)
	$Icon3 = GUICtrlCreateIcon('', 0, 146, 38, 32, 32)
	GUISetState()

	_SetCombineBkIcon($Icon1, -1, @SystemDir & '\shell32.dll', 70, 32, 32, @SystemDir & '\shell32.dll', 22, 24, 24, 0, 8)
	_SetCombineBkIcon($Icon2, -1, @SystemDir & '\shell32.dll', 3, 32, 32, @SystemDir & '\shell32.dll', 28, 32, 32)
	_SetCombineBkIcon($Icon3, -1, @SystemDir & '\shell32.dll', 220, 32, 32, @SystemDir & '\shell32.dll', 29, 32, 32)

	Do
	Until GUIGetMsg() = $GUI_EVENT_CLOSE

	GUIDelete()

EndFunc   ;==>Example1

Func Example2()

	GUICreate('Example2', 216, 128)
	$Icon = GUICtrlCreateIcon('', 0, 40, 40, 48, 48)
	GUICtrlCreateIcon(@WindowsDir & '\explorer.exe', 0, 128, 40, 48, 48)
	GUISetState()

	_SetIcon($Icon, @WindowsDir & '\explorer.exe', 0, 48, 48)

	Do
	Until GUIGetMsg() = $GUI_EVENT_CLOSE

	GUIDelete()

EndFunc   ;==>Example2

Func Example3()

	GUICreate('Example3', 715, 388)
	$Pic1 = GUICtrlCreatePic('', 10, 10, 386, 368)
	$Pic2 = GUICtrlCreatePic('', 406, 10, 193, 184)
	$Pic3 = GUICtrlCreatePic('', 609, 10, 96, 92)
	GUISetState()

	_SetImage($Pic1, $sPng)
	_SetImage($Pic2, $sPng)
	_SetImage($Pic3, $sPng)

	Do
	Until GUIGetMsg() = $GUI_EVENT_CLOSE

	GUIDelete()

EndFunc   ;==>Example3

Func Example4()

	GUICreate('Example4', 253, 244)
	$Pic1 = GUICtrlCreatePic('', 10, 10, 193, 184)
	$Pic2 = GUICtrlCreatePic('', 60, 60, 193, 184)
	GUISetState()

	_SetImage($Pic2, $sPng)
	_SetImage($Pic1, $sPng)

	Do
	Until GUIGetMsg() = $GUI_EVENT_CLOSE

	GUIDelete()

EndFunc   ;==>Example4

Func Example5()

	Local $aIndex[10] = [4, 13, 23, 31, 86, 104, 130, 150, 168, 170]

	GUICreate('Example5', 600, 400)
	$Pic = GUICtrlCreatePic('', 0, 0, 600, 400)
	For $i = 1 To UBound($aIndex)
		GUICtrlCreatePic('', Random(0, 600 - 48, 1), Random(0, 400 - 48, 1), 48, 48)
		$hIcon = _Icons_Icon_Extract(@SystemDir & '\shell32.dll', $aIndex[$i - 1], 48, 48)
		$hBitmap = _Icons_Bitmap_CreateFromIcon($hIcon)
		_SetHImage($Pic + $i, $hBitmap)
		_WinAPI_DeleteObject($hBitmap)
		_WinAPI_DestroyIcon($hIcon)
	Next
	GUISetState()

	InetGet('http://dota.ru/3d/big/p324_42.jpg', $sJpg)
	$hBitmap = _Icons_Bitmap_Load($sJpg)
	$hArea = _Icons_Bitmap_Crop($hBitmap, 420, 320, 600, 400)
	_SetHImage($Pic, $hArea)
	_WinAPI_DeleteObject($hBitmap)
	_WinAPI_DeleteObject($hArea)
	FileDelete($sJpg)

	Do
	Until GUIGetMsg() = $GUI_EVENT_CLOSE

	GUIDelete()

EndFunc   ;==>Example5

Func Example6()

	GUICreate('Example6', 800, 500)
	$Background = GUICtrlCreatePic('', 0, 0, 800, 500)
	GUICtrlSetState(-1, $GUI_DISABLE)
	$Button = GUICtrlCreateButton('Test', 355, 460, 90, 23)
	$Pic1 = GUICtrlCreatePic('', 102, 122, 256, 256)
	$Pic2 = GUICtrlCreatePic('', 442, 122, 256, 256)
	GUISetState()

	InetGet('http://autoit.rv.ua/files/Pictures/icons_ex_back.jpg', $sJpg)
	InetGet('http://autoit.rv.ua/files/Pictures/icons_ex_green.png', $sGreen)
	InetGet('http://autoit.rv.ua/files/Pictures/icons_ex_red.png', $sRed)
	_SetImage($Background, $sJpg)
	$hGreen = _Icons_Bitmap_Load($sGreen)
	$hRed = _Icons_Bitmap_Load($sRed)
	_SetHImage($Pic1, $hRed)
	_SetHImage($Pic2, $hRed)
	FileDelete($sJpg)
	FileDelete($sGreen)
	FileDelete($sRed)

	$pCtrlID = 0

	While 1
		$Cursor = GUIGetCursorInfo()
		If @error Then
			ContinueLoop
		EndIf
		$nCtrlID = $Cursor[4]
		If $nCtrlID <> $pCtrlID Then
			Switch $pCtrlID
				Case $Pic1
					_SetHImage($Pic1, $hRed)
				Case $Pic2
					_SetHImage($Pic2, $hRed, -1)
			EndSwitch
			Switch $nCtrlID
				Case $Pic1
					_SetHImage($Pic1, $hGreen)
				Case $Pic2
					_SetHImage($Pic2, $hGreen, -1)
			EndSwitch
			$pCtrlID = $nCtrlID
		EndIf
		$Msg = GUIGetMsg()
		Switch $Msg
			Case $GUI_EVENT_CLOSE
				ExitLoop
			Case $Button
				GUICtrlSetState($Button, $GUI_DISABLE)
				For $i = 1 To 50
					GUIGetMsg()
					_SetHImage($Pic1, $hGreen)
					_SetHImage($Pic2, $hGreen, -1)
					Sleep(50)
					_SetHImage($Pic1, $hRed)
					_SetHImage($Pic2, $hRed, -1)
					Sleep(50)
				Next
				GUICtrlSetState($Button, $GUI_ENABLE)
		EndSwitch
	WEnd

	GUIDelete()

EndFunc   ;==>Example6

Func Example7()

	GUICreate('Example7', 400, 93)
	$Pic = GUICtrlCreatePic('', 0, 0, 400, 93)
	$hIcon = _Icons_Icon_Extract(@SystemDir & '\shell32.dll', 86, 24, 24)
	$hBitmap = _Icons_Bitmap_CreateFromIcon($hIcon)
	For $i = 1 To 5
		GUICtrlCreatePic('', 258 + ($i - 1) * 28, 12, 24, 24)
		_SetHImage($Pic + $i, $hBitmap)
	Next
	_WinAPI_DeleteObject($hBitmap)
	_WinAPI_DestroyIcon($hIcon)
	GUISetState()

	InetGet('http://www.autoitscript.com/forum/public/style_images/autoit/logo.png', $sLogo)
	$hBitmap = _Icons_Bitmap_Load($sLogo)
	$hArea = _Icons_Bitmap_Crop($hBitmap, 0, 7, 400, 93)
	_SetHImage($Pic, $hArea)
	_WinAPI_DeleteObject($hBitmap)
	_WinAPI_DeleteObject($hArea)
	FileDelete($sLogo)

	Do
	Until GUIGetMsg() = $GUI_EVENT_CLOSE

	GUIDelete()

EndFunc   ;==>Example7

GUICtrlSetOnHover & Icons UDFs Demonstration

Icons_Hover_small.png

Icons_Hover.zip

Edited by Yashied
Wiliat87 likes this

Share this post


Link to post
Share on other sites



Posted · Report post

I haven't tried it but what is the use of Example 2 when we can just use

GUICtrlSetImage($Icon, @WindowsDir & '\explorer.exe', 0)

Share this post


Link to post
Share on other sites

Posted · Report post

I haven't tried it but what is the use of Example 2 when we can just use

GUICtrlSetImage($Icon, @WindowsDir & '\explorer.exe', 0)

Try and see the result.

Share this post


Link to post
Share on other sites

Posted · Report post

Try and see the result.

This is one of those things that I have no use for right now and don't remember when I would have used it. Of course it's also one of those threads that I will be searching for someday.

Share this post


Link to post
Share on other sites

Posted (edited) · Report post

This is one of those things that I have no use for right now and don't remember when I would have used it. Of course it's also one of those threads that I will be searching for someday.

Screenshort Edited by Yashied

Share this post


Link to post
Share on other sites

Posted (edited) · Report post

i find this very interesting and maybe this can answer a long asked question of mine.

ico files use to consist of several icons in different resolutions/sizes and color palettes. sometimes they bear even completely different images.

is there a way to determine all the included specifications and hence display exactly one specific bitmap in the ico file ?

guictrlsetimage only differenciates between large and small, for _WinAPI_PrivateExtractIcon you need to specify the size.

j.

Edited by jennico

Share this post


Link to post
Share on other sites

Posted · Report post

This library has been updated.

Share this post


Link to post
Share on other sites

Posted · Report post

This library has been updated.

This is an excellent udf Yashied and it solves a problem many people have had with icons, especially the transparency, or lack of it, when using gifs with the standard AutoIt function.

Share this post


Link to post
Share on other sites

Posted · Report post

Nice/handy UDF Yashied!!

Five stars from me.

Share this post


Link to post
Share on other sites

Posted · Report post

Very useful! Thanks for the great UDF!

Share this post


Link to post
Share on other sites

Posted · Report post

jennico, martin, Zedna, JamesBrooks,

All thanks.

Share this post


Link to post
Share on other sites

Posted · Report post

Thanks

Does it's job really good

Best regards,

Emiel

Share this post


Link to post
Share on other sites

Posted · Report post

,hi..

why I have this error ?

\AutoIt3\Include\Icons.au3 (107) : ==> "Func" statement has no matching "EndFunc".:

Share this post


Link to post
Share on other sites

Posted · Report post

What version of AutoIt are you running GameIDevelp?

Share this post


Link to post
Share on other sites

Posted · Report post

,hi..

why I have this error ?

\AutoIt3\Include\Icons.au3 (107) : ==> "Func" statement has no matching "EndFunc".:

Did you download the file or just Copy/Paste from the first post? If the latter make sure you got it all.

Share this post


Link to post
Share on other sites

Posted · Report post

Hi nice job

Share this post


Link to post
Share on other sites

Posted · Report post

I noticed in several places you do something like

BitOR($Style, Hex($SS_ICON))

There's no reason for the Hex() conversion, especially since it returns a string. Definitely not something you want to use in a BitOR().

Other than that, a really nice UDF. It would be nice to be able to resize images in your _SetImage() / _SetHImage() functions.

Share this post


Link to post
Share on other sites

Posted · Report post

autoit version 1.71 ,, stil get error at line 107 .

Share this post


Link to post
Share on other sites

Posted · Report post

Here's the _SetImage() function that allows resizing. Fortunately, the GdipGetImageThumbnail function preserves image transparency :D I've not tried this for increasing the size of an image, as far as quality goes.

I also found an AutoIt error. The value for SS_BITMAP should be 14, while it is defined as 15 in StaticConstants.au3. When you fix my above notation about Hex($SS_BITMAP), the _SetImage() function will stop working until your fix this error in the AutoIt include file.

func _SetImage($hWnd, $sImage, $iW = -1, $iH = -1)

	const $STM_SETIMAGE = 0x0172

	local $hImage, $hBitmap, $Style, $Error = false

	if not IsHWnd($hWnd) then
		$hWnd = GUICtrlGetHandle($hWnd)
		if $hWnd = 0 then
			return SetError(1, 0, 0)
		endif
	endif

	_GDIPlus_Startup()

	$hImage = _GDIPlus_BitmapCreateFromFile($sImage)
	If $iW > 0 And $iH > 0 Then
		; resize
		Local $aResult = DllCall($ghGDIPDll, "int", "GdipGetImageThumbnail", _
										"hwnd", $hImage, _
										"int", $iW, _
										"int", $iH, _
										"int*", 0, _
										"ptr", 0, _
										"ptr", 0)
		$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($aResult[4])
		_GDIPlus_ImageDispose($aResult[4])
	Else
		$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
	EndIf

	if $hBitmap = 0 then
		return SetError(1, 0, 0)
	endif

	$Style = _WinAPI_GetWindowLong($hWnd, $GWL_STYLE)
	if @error then
		$Error = 1
	else
		_WinAPI_SetWindowLong($hWnd, $GWL_STYLE, BitOR($Style, $SS_BITMAP))
		if @error then
			$Error = 1
		else
			_WinAPI_DeleteObject(_SendMessage($hWnd, $STM_SETIMAGE, $IMAGE_BITMAP, 0))
			_SendMessage($hWnd, $STM_SETIMAGE, $IMAGE_BITMAP, $hBitmap)
			if @error then
				$Error = 1
			endif
		endif
	endif

	_WinAPI_DeleteObject($hBitmap)
	_GDIPlus_BitmapDispose($hImage)
	_GDIPlus_Shutdown()

	return SetError($Error, 0, not $Error)
endfunc; _SetImage

Share this post


Link to post
Share on other sites

Posted · Report post

The library has been updated.

Share this post


Link to post
Share on other sites

Posted (edited) · Report post

Nice update!

Edited by wraithdu

Share this post


Link to post
Share on other sites

Posted · Report post

Thanks, wraithdu.

You call _GDIPlus_Startup() and _GDIPlus_Shutdown() in a couple functions. You probably shouldn't do that and leave it up to the user to do it once in the beginning and end of script.

I'm so written it in the description of functions. But if I remove _GDIPlus_Startup() from the code, it will not work. This is not good, in my opinion. How many times do not call _GDIPlus_Startup() function, DLL is loaded only once, the user may call once _GDIPlus_Startup() at the beginning of its code. But if the user wants to display the image only once (eg when creating a GUI), then encumber its challenges _GDIPlus_Startup() and _GDIPlus_Shutdown() does not need it.

You should also return the handles of any resources that you don't dispose of in the functions, so the user can dispose of them if they need to do so (always updating a GUI with different images for example, would lead to a memory leak).

All resources (I hope I have nothing not missed) are disposed. Objects that are in control, are disposed if you delete this control or window. Or I did not understand you?

Share this post


Link to post
Share on other sites

Posted (edited) · Report post

*snip*

Edited by wraithdu

Share this post


Link to post
Share on other sites

Posted (edited) · Report post

1) It's not so much a problem that you call _GDIPlus_Startup(), but that you call _GDIPlus_Shutdown(). What if a user is actually using GDI+ in their script, then calls your function, and then GDI+ gets shutdown? I think it would be better to document that GDI+ is used and it's the user's responsibility to initialize / close it.

Another option (although not one I really endorse) is to check the state of the global variable $ghGDIPDll. If it is 0, then GDI+ hasn't been started. If it is >0, then GDI+ is already started. You could use this as a flag of sorts in your functions - if it is not started already then your are free to startup / shutdown GDI+, if it IS already started, then don't startup / shutdown to preserve the user's state.

2) Suppose a user creates a pic control, then uses _SetImage() to set an image to the pic control. Now if he just wants to update the image (not totally deleting the control) then the memory for the first image resource is lost since there is no handle to free the resource. Suppose this pic control is changed many times as part of a looping GUI update...you can see the problem. Besides, I am not positive an image resource like this would be disposed of by deleting the control with GuiCtrlDelete() anyway.

You are right about the first, but not second. Return of STM_SETIMAGE is the old handle that is deleted btw.

edit:

I would go with custom GdiplusStartup/GdiplusShutdown functions.

Edited by trancexx

Share this post


Link to post
Share on other sites

Posted (edited) · Report post

@wraithdu, trancexx

Func _GDIPlus_Shutdown()
	If $ghGDIPDll = 0 Then Return SetError(-1, -1, False)

	$giGDIPRef -= 1
	If $giGDIPRef = 0 Then
		DllCall($ghGDIPDll, "none", "GdiplusShutdown", "ptr", $giGDIPToken)
		DllClose($ghGDIPDll)
		$ghGDIPDll = 0
	EndIf
	Return True
EndFunc   ;==>_GDIPlus_Shutdown
Edited by Yashied

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Recently Browsing   0 members

    No registered users viewing this page.