Jump to content

How to load an image from ico file ?


Recommended Posts

I do not mean displaying icon size on windows destop. I mean the display in Autoit GUI, it also has limit size is 32x32 ? As result of AutoBert on win10 x64, it also display all in 32x32 even if the real size of icon is bigger!

Can Autoit GUI display bigger size? I think that making a toolbar button with size 32x32 is rather small to see & click.

Edited by hiepkhachsg
Link to comment
Share on other sites

Well, you can do it using the "complicated code" I've posted! You will get all icons in GDIp bitmap format and modify the size to display it in a  picture control.

PS: I'm writing about the .ico files only.

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Have you looked in Helpfile for

Quote

GUICtrlSetImage

...

Parameters

...

   
   
   
icontype [optional] To select a specific icon size : 0 = small, 1 = normal (default).
For a TreeViewItem the icon size : 2 = selected, 4 for non-selected item.

when using 0 and 1 the only possible (as not used for TV-Item) then result is: 56e4391edf69f_41_IconTest2.icl.jpg.7b1f0

using a ImageList you are more flexible.   

#include <GuiButton.au3>
#include <GuiImageList.au3>
#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
#include <Constants.au3>
#include <WinAPI.au3>

Example()

Func Example()
GUICreate("Icon Test2.icl ", 400, 380, -1, -1)
 GUICtrlCreateButton("icon", 10, 20, 50, 50, $BS_ICON)
 GUICtrlSetImage(-1, "Test2.icl", 1,0)
 GUICtrlCreateButton("icon", 60, 20, 50, 50, $BS_ICON)
 GUICtrlSetImage(-1, "Test2.icl", 2,1)
 GUICtrlCreateButton("icon", 110, 20, 50, 50, $BS_ICON)
 GUICtrlSetImage(-1, "Test2.icl", 3,0)
 GUICtrlCreateButton("icon", 10, 80, 50, 50, $BS_ICON)
 GUICtrlSetImage(-1, "Test2.icl", 4,1)
 GUICtrlCreateButton("icon", 60, 80, 50, 50, $BS_ICON)
 GUICtrlSetImage(-1, "Test2.icl", 5,1)
 GUICtrlCreateButton("icon", 110, 80, 50, 50, $BS_ICON)
 GUICtrlSetImage(-1, "Test2.icl", 6,1)
 GUICtrlCreateButton("icon", 10, 150, 100, 100, $BS_ICON)
 GUICtrlSetImage(-1, "Test2.icl", 7,0)
 GUICtrlCreateButton("icon", 110, 150, 100, 100, $BS_ICON)
 GUICtrlSetImage(-1, "Test2.icl", 8,1)

$hImage = _GUIImageList_Create(96, 96, 4, 3, 6)
_GUIImageList_AddIcon($hImage, "Test2.icl", 8, True)
 GUICtrlCreateButton("icon", 210, 150, 100, 100, $BS_ICON)
_GUICtrlButton_SetImageList(-1, $hImage)
 GUISetState()

EndFunc   ;==>Example

 While 1
  $msg = GUIGetMsg()
  If $msg = $GUI_EVENT_CLOSE Then ExitLoop
 WEnd

56e43f379212c_42_IconTest2.icl.jpg.01ed7

Link to comment
Share on other sites

Hey AutoBert, I had tried all the ways before you talk. When using GUICtrlSetImage the option icon size : 0 = small is for displaying 16x16 , 1 = normal is displaying for 32x32 only. In Imagelist, when using _GUIImageList_AddIcon to add, the last option $bLarge[optional] Extrat Large Icon but it just only 32x32, and the image store in Imagelist still is 32x32. When use the image in Imagelist, we can display it bigger but the image will be broken. Because icon in my .icl is a number with flat color so you don't see the different of broken. If you don't believe me, you can try with an icon have complicated image you will see the broken when display bigger imagelist.  It is the same of when we view a small image and zoom in too much.

After many try not success, so that i post to ask if there is the different way to display? Finally, now we must agree with the biggest is 32x32, or use complicated way of UEZ.

Thanks everyone for help & discussing.

   
Edited by hiepkhachsg
Link to comment
Share on other sites

8 hours ago, hiepkhachsg said:

After many try not success, so that i post to ask if there is the different way to display? Finally, now we must agree with the biggest is 32x32, or use complicated way of UEZ.

At the first look it looks complicated but you do not need to understand the _EnumIconFile function. Just use the result to create your desired image size.

Example using only the first icon from the ICO file:

#include <ButtonConstants.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WinAPIFiles.au3>
#include <WinAPIRes.au3>

Global $sPath = FileOpenDialog("Select an ICO file", "", "Icon (*.ico)")
If @error Then Exit

_GDIPlus_Startup()
Global $aRes = _EnumIconFile($sPath) ; loads all icons from the ICO file and converts it to icon handles
Global $hBitmap_1st

Switch $aRes[1][2]
    Case 0 To 8 ;color depth of icons from 1 to 8 bit -> 256 colors
        $hBitmap_1st = _GDIPlus_BitmapCreateFromHICON($aRes[1][4]) ;extract the 1st icon only and convert it to a GDIPlus bitmap format
    Case Else ;the rest for high color depth
        $hBitmap_1st = _GDIPlus_BitmapCreateFromHICON32($aRes[1][4]) ;extract the 1st icon only and convert it to a GDIPlus bitmap format
EndSwitch

Global $hBitmap_Pic = _GDIPlus_ImageResize($hBitmap_1st, 128, 128, 7) ;resize the bitmap
Global $hHBitmap_Pic = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Pic) ;convert the GDIPlus bitmap to GDI bitmap format
Global $hBitmap_Btn = _GDIPlus_ImageResize($hBitmap_1st, 92, 92, 7) ;resize the bitmap
Global $hHBitmap_Btn = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Btn) ;convert the GDIPlus bitmap to GDI bitmap format

;clean-up GDIPlus resources which are not needed anymore
_GDIPlus_ImageDispose($hBitmap_Pic)
_GDIPlus_ImageDispose($hBitmap_Btn)
_GDIPlus_ImageDispose($hBitmap_1st)

;create a test GUI
Global Const $STM_SETIMAGE = 0x0172
Global $hGUI = GUICreate("Test", 320, 200)
GUISetBkColor(0xFFFFFF)
Global $iPic = GUICtrlCreatePic("", 10, 10, 128, 128)
Global $iBtn = GUICtrlCreateButton("", 160, 10, 92, 92, $BS_BITMAP)
_WinAPI_DeleteObject(GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap_Pic)) ;copy the GDI bitmap to the picture control
_WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($iBtn), $BM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap_Btn)) ;copy the GDI bitmap to the button control
GUISetState()

Do
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ;release the rest of the resources
            For $i = 0 To UBound($aRes) - 1
                _WinAPI_DestroyIcon($aRes[$i][4])
            Next
            _WinAPI_DeleteObject($hHBitmap_Pic)
            _WinAPI_DeleteObject($hHBitmap_Btn)
            _GDIPlus_Shutdown()
            GUIDelete()
            Exit
        Case $iPic
            MsgBox(0, "", "Pic control was clicked")
        Case $iBtn
            MsgBox(0, "", "Button control was clicked")
    EndSwitch
Until False


; #FUNCTION# ====================================================================================================================
; Name...........: _EnumIconFile
; Description....: Enumerates an icons from the specified .ico file.
; Syntax.........: _EnumIconFile ( $sFile )
; Parameters.....: $sFile  - The path to the .ico file whose icons are to be enumerated.
; Return values..: Success - The 2D array containing the following information:
;
;                            [0][0] - Number of rows in array (n)
;                            [0][i] - Unused
;                            [n][0] - The width of the icon, in pixels.
;                            [n][1] - The heigth of the icon, in pixels.
;                            [n][2] - The color depth of the icon, in bits-per-pixel.
;                            [n][3] - 1 (TRUE) if the icon has a PNG compression (Windows Vista+), or 0 (FALSE) otherwise.
;                            [n][4] - Handle -> either a bitmap will be created if [n][3] = 1 or an Icon
;
;                  Failure - 0 and sets the @error flag to non-zero.
; Author.........: Yashied
; Modified.......: UEZ
; Remarks........: Do not forget to clean-up resources in [n][4] when done
; Related........:
; Link...........:
; Example........:
; ===============================================================================================================================
Func _EnumIconFile($sFile)
    Local $hFile, $tEntry, $tHeader, $tData, $pData, $pIcon, $Bytes, $Count, $Offset, $Enum = 0

    $hFile = _WinAPI_CreateFileEx($sFile, 3, 0x80000000, 0x03)
    If @Error Then
        Return SetError(1, 0, 0)
    EndIf
    Do
        $Bytes = _WinAPI_GetFileSizeEx($hFile)
        If Not $Bytes Then
            ExitLoop
        EndIf
        $tData = DllStructCreate('byte[' & $Bytes & ']')
        $pData = DllStructGetPtr($tData)
        If Not _WinAPI_ReadFile($hFile, $pData, $Bytes, $Bytes) Then
            ExitLoop
        EndIf
        $tHeader = DllStructCreate('ushort;ushort;ushort', $pData)
        $Count = DllStructGetData($tHeader, 3)
        If Not $Count Then
            ExitLoop
        EndIf
        Local $hBitmap
        Dim $Enum[$Count + 1][5] = [[$Count]]
        For $i = 1 To $Count
            $tEntry = DllStructCreate('byte;byte;byte;byte;ushort;ushort;long;long', $pData + 6 + 16 * ($i - 1))
            $Offset = DllStructGetData($tEntry, 8)
            $pIcon = $pData + $Offset
            $Enum[$i][2] = DllStructGetData($tEntry, 6)
            If DllStructGetData(DllStructCreate('byte[8]', $pIcon), 1) = Binary('0x89504E470D0A1A0A') Then
                ; PNG => Retrieve IHDR chunk data (always first chunk, offset = 8)
                $tHeader = DllStructCreate('dword;dword;byte;byte;byte;byte;byte', $pIcon + 16)
                $Enum[$i][0] = _WinAPI_SwapDWord(DllStructGetData($tHeader, 1))
                $Enum[$i][1] = _WinAPI_SwapDWord(DllStructGetData($tHeader, 2))
                $Enum[$i][3] = 1
                $Enum[$i][4] = _GDIPlus_BitmapCreateFromMemory(Binary(DllStructGetData(DllStructCreate("byte[" & DllStructGetData($tEntry, 7) & "]", $pIcon), 1)))
            Else
                ; ICO => Retrieve BITMAPINFOHEADER structure
                $tHeader = DllStructCreate($tagBITMAPINFOHEADER, $pIcon)
                $Enum[$i][0] = DllStructGetData($tHeader, 2)
                $Enum[$i][1] = DllStructGetData($tHeader, 3) / 2
                $Enum[$i][3] = 0
                $Enum[$i][4] = _WinAPI_CreateIconFromResourceEx($pIcon, DllStructGetData($tEntry, 7), True, $Enum[$i][0], $Enum[$i][1])
            EndIf
        Next
    Until 1
    _WinAPI_CloseHandle($hFile)
    If Not IsArray($Enum) Then
        Return SetError(1, 0, 0)
    EndIf
    Return $Enum
EndFunc   ;==>_EnumIconFile

I hope it helps.

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

dont forget to create dll resource for your icon then test this exemple :

#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
#include <Constants.au3>
#include <WinAPI.au3>

Example()

Func Example()
 GUICreate("", 400, 380, -1, -1)
 GUICtrlCreateButton("my picture button", 10, 20, 40, 40, $BS_ICON)
 GUICtrlSetImage(-1, "main.dll", "FINDICO")
 GUICtrlCreateButton("my picture button", 50, 20, 40, 40, $BS_ICON)
 GUICtrlSetImage(-1, "main.dll", "-2")
 GUICtrlCreateButton("my picture button", 90, 20, 40, 40, $BS_ICON)
 GUICtrlSetImage(-1, "main.dll", "-3")
 GUICtrlCreatePic("", 0, 20, 400, 380)
 GUICtrlSetState(-1, $GUI_DISABLE)
 GUICtrlSetImageFromDLL(-1, "DLLTest.dll", "-4")
 GUISetState()

 While 1
  $msg = GUIGetMsg()
  If $msg = $GUI_EVENT_CLOSE Then ExitLoop
 WEnd
EndFunc   ;==>Example

Func GUICtrlSetImageFromDLL($controlID, $filename, $imageIndex)
 Local Const $STM_SETIMAGE = 0x0172
 $hLib = _WinAPI_LoadLibrary($filename)
 $hBmp = _WinAPI_LoadImage($hLib, $imageIndex, $IMAGE_BITMAP, 0, 0, $LR_DEFAULTCOLOR)
 GUICtrlSendMsg($controlID, $STM_SETIMAGE, $IMAGE_BITMAP, $hBmp)
 _WinAPI_FreeLibrary($hLib)
 _WinAPI_DeleteObject($hBmp)
EndFunc   ;==>GUICtrlSetImageFromDLL
Spoiler
Spoiler

 

 

 

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...