hiepkhachsg Posted March 10, 2016 Share Posted March 10, 2016 Hi all. I have a ico file with many images inside, how can i load an desire image from it? Pls help! Link to comment Share on other sites More sharing options...
InunoTaishou Posted March 10, 2016 Share Posted March 10, 2016 (edited) What do you mean by "load"? Are you trying to display the icon file in a gui? Are you trying to load the image into memory? Here's a way to load an image into a GDI+ Bitmap object and I commented out the line that would let you convert the GDI+Bitmap to a hBitmap. There are posts all over the forum for converting bitmaps to a binary string. #include <GDIPlus.au3> #include <WinAPI.au3> #include <GUIConstants.au3> Example() Func Example() _GDIPlus_Startup() ; Create a GDI+ Bitmap Local $Bitmap = _GDIPlus_ImageLoadFromFile("your icon file.ico") ; Create a windows HBitmap object, need to use _WinApi_DeleteObject($hBitmap) when you're done with it ;Local $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($Bitmap) Local $iWidth = _GDIPlus_ImageGetWidth($Bitmap) + 20 Local $iHeight = _GDIPlus_ImageGetHeight($Bitmap) + 20 Local $hGUI = GUICreate("", $iWidth, $iHeight) GUISetState(@SW_SHOW, $hGUI) Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) _GDIPlus_GraphicsDrawImage($hGraphic, $Bitmap, 10, 10) While (True) Switch (GUIGetMsg()) Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _GDIPlus_ImageDispose($Bitmap) _GDIPlus_Shutdown() EndFunc Edited March 10, 2016 by InunoTaishou Link to comment Share on other sites More sharing options...
hiepkhachsg Posted March 10, 2016 Author Share Posted March 10, 2016 I mean to display the icon file in a gui. I use GUICtrlSetImage to set, but in my icon file contains mulitple icons and i don't know the iconname of each icon, i try to use the number to index but it don't work. How can i get a desire icon? Link to comment Share on other sites More sharing options...
AutoBert Posted March 10, 2016 Share Posted March 10, 2016 Are you sure you have a valid Iconfile? Here's a example: #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> Example() Func Example() GUICreate("My GUI") ; will create a dialog box that when displayed is centered GUICtrlCreateButton("my picture button", 10, 20, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "shell32.dll", 22) GUISetState(@SW_SHOW) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd EndFunc ;==>Example in line 10: just change name Shell32.dll to yours with complete path to file and try numbers 0..9 instead of 22. Link to comment Share on other sites More sharing options...
hiepkhachsg Posted March 10, 2016 Author Share Posted March 10, 2016 I make my own .ico file, and the number index still not work. Link to comment Share on other sites More sharing options...
hiepkhachsg Posted March 10, 2016 Author Share Posted March 10, 2016 i wonder if it work with .ico file or only work with .dll file? Any one try with .ico file? Link to comment Share on other sites More sharing options...
AutoBert Posted March 10, 2016 Share Posted March 10, 2016 5 hours ago, hiepkhachsg said: I make my own .ico file, and the number index still not work. 6 hours ago, AutoBert said: Are you sure you have a valid Iconfile? So attach your zipped file. Link to comment Share on other sites More sharing options...
InunoTaishou Posted March 10, 2016 Share Posted March 10, 2016 If you have multiple icons in an icon file then you would need to define the area to extract the icon. (I'm assuming that you're working with a .ico file). If you wanted to go down this route then you can use GDI+ to extract the icon from the file and then using GUICtrlSendMessage to set the pic control (Check out this topic to see how to do that. Link to comment Share on other sites More sharing options...
AutoBert Posted March 10, 2016 Share Posted March 10, 2016 Before not seen the file it's like reading tea leaves. Link to comment Share on other sites More sharing options...
hiepkhachsg Posted March 10, 2016 Author Share Posted March 10, 2016 I make a small .ico file contains 6 icons inside and write here a little example to test. How can load or add all icon as i want? #include <GUIConstantsEx.au3> #include <ButtonConstants.au3> #include <Constants.au3> #include <WinAPI.au3> Example() Func Example() GUICreate("", 400, 380, -1, -1) GUICtrlCreateButton("icon image", 10, 20, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "test.ico", -1) GUICtrlCreateButton("icon image", 50, 20, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "test.ico", "-2") GUICtrlCreateButton("icon image", 90, 20, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "test.ico", 3) GUISetState() While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop WEnd EndFunc ;==>Example test.ico Link to comment Share on other sites More sharing options...
InunoTaishou Posted March 10, 2016 Share Posted March 10, 2016 I don't know what it is about your icon file but it will not load the images properly. I think it might not have been saved properly or created properly. The only image it will load correctly is the 6, 1-5 fail completely. Here's the code I used to check this. (Please note, the $BS_ICON or $BS_BITMAP don't matter, as long as one is used. Once it's going to turn into a bitmap either way once it's extracted.) #include <GUIConstantsEx.au3> #include <GuiButton.au3> Local $hGUI = GUICreate("Image List", 116, 84) Local $btnTest[6] For $i = 0 To 2 $btnTest[$i] = GUICtrlCreateButton("", 10 + ($i * 32), 10, 32, 32, $BS_BITMAP) $btnTest[$i + 3] = GUICtrlCreateButton("", 10 + ($i * 32), 42, 32, 32, $BS_BITMAP) ConsoleWrite("Set image for Button " & $i + 1 & " returned: " & _GUICtrlButton_SetImage($btnTest[$i], @ScriptDir & "\test.ico", $i, True) & " | ") ConsoleWrite("Set image for Button " & $i + 1 & " returned: " & _GUICtrlButton_SetImage($btnTest[$i + 3], @ScriptDir & "\test.ico", $i + 3, True) & @LF) Next GUISetState(@SW_SHOW) While (True) Switch (GUIGetMsg()) Case $GUI_EVENT_CLOSe GUIDelete($hGUI) Exit 0 EndSwitch WEnd I also tried to open up your icon file, it will load correctly in photoshop and let me select which image to load. I tried using IcoFX too but it only recognized 1 image, the number 1. Maybe I was doing it wrong, who knows. I tried using _GUIImageList as well but that failed. Try using a dll with your images or just create one png file with all of your images and use GDI+ to extract the image you want. Link to comment Share on other sites More sharing options...
hiepkhachsg Posted March 11, 2016 Author Share Posted March 11, 2016 As Microsoft guide and I learned, the normal image viewer and normal icon software can only view 1 image in multiple icons file, and just only the icon software professional can view all images in multiple icons file. But the problem still is the same when i make a resource dll. Here my .dll, anybody can explain why? #include <GUIConstantsEx.au3> #include <ButtonConstants.au3> #include <Constants.au3> #include <WinAPI.au3> Example() Func Example() GUICreate("", 400, 380, -1, -1) GUICtrlCreateButton("icon", 10, 20, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "test.dll", 1) GUICtrlCreateButton("icon", 50, 20, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "test.dll", 2) GUICtrlCreateButton("icon", 90, 20, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "test.dll", -2) GUICtrlCreateButton("icon", 10, 80, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "test.dll", "2") GUICtrlCreateButton("icon", 50, 80, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "test.dll", "-2") GUICtrlCreateButton("icon", 90, 80, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "test.dll", -1) GUISetState() EndFunc ;==>Example While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop WEnd test.dll Link to comment Share on other sites More sharing options...
UEZ Posted March 11, 2016 Share Posted March 11, 2016 (edited) Here a hack to display all icons from the ICO file. expandcollapse popup;~ #include <Array.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WinAPIFiles.au3> #include <WinAPIRes.au3> ;~ Global Const $sPath = "c:\Program Files (x86)\AutoIt3\Aut2Exe\Icons\AutoIt_Old1.ico" Global $sPath = FileOpenDialog("Select an ICO file", "", "Icon (*.ico)") If @error Then Exit _GDIPlus_Startup() Global $aRes = _EnumIconFile($sPath), $iSumW, $iMaxH, $i, $iDist = 16 Global $aIcons[$aRes[0][0]] For $i = 1 To $aRes[0][0] $iSumW += $aRes[$i][0] $iMaxH = $aRes[$i][1] > $iMaxH ? $aRes[$i][1] : $iMaxH Switch $aRes[$i][3] Case 0 Switch $aRes[$i][2] Case 0 To 8 $aIcons[$i - 1] = _GDIPlus_BitmapCreateFromHICON($aRes[$i][4]) Case Else $aIcons[$i - 1] = _GDIPlus_BitmapCreateFromHICON32($aRes[$i][4]) EndSwitch _WinAPI_DestroyIcon($aRes[$i][4]) Case 1 $aIcons[$i - 1] = $aRes[$i][4] EndSwitch Next Global $hGUI = GUICreate("Test", $iSumW + ($aRes[0][0]) * $iDist, $iMaxH + $iDist) GUISetBkColor(0xFFFFFF) GUISetState() Global $hGfx = _GDIPlus_GraphicsCreateFromHWND($hGUI) $iSumW = 0 For $i = 0 To UBound($aIcons) - 1 $aDim = _GDIPlus_ImageGetDimension($aIcons[$i]) If @error Then ContinueLoop _GDIPlus_GraphicsDrawImageRect($hGfx, $aIcons[$i], $iSumW, 0, $aDim[0], $aDim[1]) $iSumW += $aDim[0] + $iDist Next Do Switch GUIGetMsg() Case $GUI_EVENT_CLOSE For $i = 0 To UBound($aIcons) - 1 _GDIPlus_ImageDispose($aIcons[$i]) Next _GDIPlus_GraphicsDispose($hGfx) _GDIPlus_Shutdown() GUIDelete() Exit 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 Not fully tested! Edited March 11, 2016 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 More sharing options...
hiepkhachsg Posted March 12, 2016 Author Share Posted March 12, 2016 Thanks. It look complicated. Link to comment Share on other sites More sharing options...
hiepkhachsg Posted March 12, 2016 Author Share Posted March 12, 2016 I want to ask 1 more question. Can we add a big icon with the Function "GUICtrlSetImage" or "_GUIImageList_AddIcon" ? Because when i use these function it only can add a max 32x32 px icon, the bigger icon will be auto resize to smaller. So that when display the bigger of 32px icon, the image is broken. Any solution for it? Link to comment Share on other sites More sharing options...
draconem Posted March 12, 2016 Share Posted March 12, 2016 I just checked your .ICO and .DLL files and I really got no idea how you did manage to add the same resolution icons into a same ico file... Use St. Google and search for IMAGE to ICO online converters, theres plenty and free out there. One .ico file is made of 1-n images with specific resolutions and bith depth, none of the resolutions "must" be duplicated. What I think you may want to achieve is to create an icon library (.icl), which is a container for several .ico files. In my experience I use negative numbers for the indexed icons, ie. -1, -2, -3 and so. althought in rare cases like the code below, the 1st icon worked with a positive index number. Download the .icl file and test this code: #include <GUIConstantsEx.au3> #include <ButtonConstants.au3> #include <Constants.au3> #include <WinAPI.au3> Example() Func Example() GUICreate("", 400, 380, -1, -1) GUICtrlCreateButton("icon 1", 10, 20, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "1-6.icl", 1) GUICtrlCreateButton("icon 2", 50, 20, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "1-6.icl", -2) GUICtrlCreateButton("icon 3", 90, 20, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "1-6.icl", -3) GUICtrlCreateButton("icon 4", 10, 80, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "1-6.icl", -4) GUICtrlCreateButton("icon 5", 50, 80, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "1-6.icl", -5) GUICtrlCreateButton("icon 6", 90, 80, 40, 40, $BS_ICON) GUICtrlSetImage(-1, "1-6.icl", -6) GUISetState() EndFunc ;==>Example While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop WEnd 1-6.icl Link to comment Share on other sites More sharing options...
TheSaint Posted March 12, 2016 Share Posted March 12, 2016 I didn't see where you stated how you created your ico file (i.e. what process or program)? An ico file generally only has one icon. To store multiple icons together, you generally use an icon library file (.icl). Or they can be stored in DLL or EXE etc files. To be true icons in a file, they generally have to fit the criteria of appropriate bit depth and sizing (16x16, 32x32, 48x48). You should be able to use negative numbers, as has been previously suggested. Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage) Link to comment Share on other sites More sharing options...
hiepkhachsg Posted March 12, 2016 Author Share Posted March 12, 2016 (edited) Thanks. The number index work correctly with .icl file. But still remain the problem with display size. although the icon size is bigger than 32x32, it seem only display max 32x32 icon size. There are just only 2 choices 16x16, 32x32 to display when i try to display icon on button or toolbar. Are there any way to display bigger icon? Here my little example to test. My .icl file have icon 1-6 in 48x48 and 7-9 in 96x96, but all icons still display 32x32. #include <GUIConstantsEx.au3> #include <ButtonConstants.au3> #include <Constants.au3> #include <WinAPI.au3> Example() Func Example() GUICreate("", 400, 380, -1, -1) GUICtrlCreateButton("icon", 10, 20, 50, 50, $BS_ICON) GUICtrlSetImage(-1, "Test2.icl", 1) GUICtrlCreateButton("icon", 60, 20, 50, 50, $BS_ICON) GUICtrlSetImage(-1, "Test2.icl", 2) GUICtrlCreateButton("icon", 110, 20, 50, 50, $BS_ICON) GUICtrlSetImage(-1, "Test2.icl", 3) GUICtrlCreateButton("icon", 10, 80, 50, 50, $BS_ICON) GUICtrlSetImage(-1, "Test2.icl", 4) GUICtrlCreateButton("icon", 60, 80, 50, 50, $BS_ICON) GUICtrlSetImage(-1, "Test2.icl", 5) 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) GUICtrlCreateButton("icon", 110, 150, 100, 100, $BS_ICON) GUICtrlSetImage(-1, "Test2.icl", 8) GUICtrlCreateButton("icon", 210, 150, 100, 100, $BS_ICON) GUICtrlSetImage(-1, "Test2.icl", 9,1) GUISetState() EndFunc ;==>Example While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop WEnd Test2.icl Edited March 12, 2016 by hiepkhachsg Link to comment Share on other sites More sharing options...
TheSaint Posted March 12, 2016 Share Posted March 12, 2016 Have a look at your Microsoft Windows' settings. I know I can display 48x48 on my Win 7 desktop, but in folders the current maximum is 32x32. I imagine that is either a permanent limitation or a Windows' setting. You can change many Windows' settings from the Display Properties menus. Never come across 96x96. Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage) Link to comment Share on other sites More sharing options...
AutoBert Posted March 12, 2016 Share Posted March 12, 2016 2 hours ago, hiepkhachsg said: Here my little example to test. My .icl file have icon 1-6 in 48x48 and 7-9 in 96x96, but all icons still display 32x32. This is result: win10 x64 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now