Jump to content
Bilgus

Button Icons With _WinAPI_ExtractIconEx

Recommended Posts

Bilgus

@TexWiller asked in Help & Support how to use _WinAPI_ExtractIconEx instead of GUICtrlSetImage

This is his reproducer script for displaying his issue I cleaned it up and made it work for _WinAPI_ExtractIconEx

;============================================================================================================
;Program Options
;============================================================================================================
Opt("MustDeclareVars", 1) ;Variables must be pre-declared.
Opt("TrayMenuMode", 3) ;The default tray menu items will not be shown, items are not checked when selected.

;============================================================================================================
;Libraries Inclusions
;============================================================================================================

#include <ColorConstants.au3>
#include <TrayConstants.au3>
#include <WindowsConstants.au3>
#include <FontConstants.au3>
#include <GuiConstantsEx.au3>
#include <Array.au3>
#include <GuiButton.au3>
#include <StaticConstants.au3>


;============================================================================================================
;Global Vars
;============================================================================================================

Global $hMainGUI
Global $nMsg
Global $IdTrayMenuMain
Global $IdTrayMenuExit

Main()

Func Main()
    ;------------------------------------------------------------------------------------------------------------
    ;Create Main Window
    ;------------------------------------------------------------------------------------------------------------
    $hMainGUI = GUICreate("Sample", 1024, 700, 50, 50, BitOR($WS_SYSMENU, $WS_CAPTION, $DS_SETFOREGROUND))
    GUISetFont(8, $FW_NORMAL, $GUI_FONTNORMAL, "Arial", $hMainGUI, $CLEARTYPE_QUALITY)
    GUISetBkColor(0xDDDDDD, $hMainGUI)
    GUISetState(@SW_SHOW, $hMainGUI)
    WinWaitActive($hMainGUI)

    ;============================================================================================================
    ;Create Traymenu
    ;============================================================================================================

    ;Create a Traymenu.
    $IdTrayMenuMain = TrayCreateItem("Sample", -1, 0)

    ;Create a Separator line.
    TrayCreateItem("", -1, -1)

    ;Create a Menuitem.
    $IdTrayMenuExit = TrayCreateItem("Exit", -1, -1)

    ;Show the Traymenu.
    TraySetState($TRAY_ICONSTATE_SHOW)

    ;------------------------------------------------------------------------------------------------------------
    ;Sample
    ;------------------------------------------------------------------------------------------------------------

    Local $aIconButtons[0] ;Array to manage Buttons
    Local $aIconBLabels[0] ;Array to manage Buttons

    Local $iButtonPosLeft = 10 ;Inserting Position X
    Local $iButtonPosTop = 10 ;Inserting Position Y

    Local $iButtonCount
    Local $iIcnPosOffset = 0

    Local $iIconCt = _WinAPI_ExtractIconEx("shell32.dll", -1, 0, 0, 0) ;retrieve count of Icons
    ConsoleWrite("Icons: " & $iIconCt & @CRLF)
    Local $iIconIdx = 0 ;The Icon Index to begin extracting at

    Local $tIconsLg = DllStructCreate("HANDLE[" & $iIconCt & "]")
    Local $pIconsLg = DllStructGetPtr($tIconsLg)

    Local $tIconsSm = DllStructCreate("HANDLE[" & $iIconCt & "]")
    Local $pIconsSm = DllStructGetPtr($tIconsSm)

    $iIconCt = _WinAPI_ExtractIconEx("shell32.dll", $iIconIdx, $pIconsLg, $pIconsSm, $iIconCt) ;Get Large/ Small Icon Handles into arrays
    ConsoleWrite("Icons Extracted: " & $iIconCt & @CRLF) ; ;; PS Don't Forget _WinAPI_DestroyIcon()

    For $iButtonCount = 1 To 200

        If BitAND($iButtonCount, 1) Then
            _ArrayAdd($aIconButtons, GUICtrlCreateButton("", $iButtonPosLeft, $iButtonPosTop, 45, 45, $BS_ICON)) ;Icon Only
        Else
            _ArrayAdd($aIconButtons, GUICtrlCreateButton($iButtonCount, $iButtonPosLeft, $iButtonPosTop, 45, 45)) ;Icon and Text
        EndIf
        _ArrayAdd($aIconBLabels, GUICtrlCreateLabel(1 * ($iButtonCount + $iIcnPosOffset), $iButtonPosLeft, $iButtonPosTop + 45, 45, 15))
        GUICtrlSetStyle($aIconBLabels[$iButtonCount - 1], BitOR($SS_CENTER, $SS_CENTERIMAGE))

        $iButtonPosLeft = $iButtonPosLeft + 50

        If Mod($iButtonCount, 20) = 0 Then
            $iButtonPosTop = $iButtonPosTop + 70
            $iButtonPosLeft = 10
        EndIf

        ;retrieving Icons by positive position
        ;*****************************************************************************************
        ;$MessageTemp = GUICtrlSetImage($aIconButtons[$iButtonCount - 1], "shell32.dll", 1 * ($iButtonCount + $iIcnPosOffset) , 1)
        ;*****************************************************************************************

        If $iButtonCount < $iIconCt Then
            If BitAND($iButtonCount, 1) Then
                GUICtrlSendMsg($aIconButtons[$iButtonCount - 1], $BM_SETIMAGE, $IMAGE_ICON, DllStructGetData($tIconsLg, 1, $iButtonCount))
            Else
                GUICtrlSendMsg($aIconButtons[$iButtonCount - 1], $BM_SETIMAGE, $IMAGE_ICON, DllStructGetData($tIconsSm, 1, $iButtonCount))
            EndIf
        EndIf

    Next

    ;Destroy all the extracted icons
    ConsoleWrite("Destroying Icons" & @CRLF)
    For $i = 1 To $iIconCt
        _WinAPI_DestroyIcon(DllStructGetData($tIconsLg, 1, $i))
        _WinAPI_DestroyIcon(DllStructGetData($tIconsSm, 1, $i))
    Next


    ;============================================================================================================
    ;GUI Loop
    ;============================================================================================================
    While True
        ;------------------------------------------------------------------------------------------------------------
        ;Get GUI-Messages
        ;------------------------------------------------------------------------------------------------------------
        $nMsg = GUIGetMsg()
        If $nMsg = $GUI_EVENT_CLOSE Then ExitLoop
        ;------------------------------------------------------------------------------------------------------------
        ;Get Traymenu Messages
        ;------------------------------------------------------------------------------------------------------------
        Switch TrayGetMsg()
            Case $IdTrayMenuExit ;Exit.
                ExitLoop
        EndSwitch
        ;------------------------------------------------------------------------------------------------------------
    WEnd
EndFunc   ;==>Main

 

Edited by Bilgus

Share this post


Link to post
Share on other sites
Bilgus

Updated Example With Small Icons and Button Captions

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

  • Similar Content

    • odaylton
      By odaylton
      I would like to get a region of the screen but avoiding having to save to a file first.
      I believe it is a lack of knowledge on my part but the GUICtrlSetImage function does not allow you to define an image without being a file.
      How to do this:
      ;.... $Pic3 = GUICtrlCreatePic("", 8, 64, 84, 84, -1, _ $WS_EX_STATICEDGE) ;para ter borda em baixo relevo ;.... _ScreenCapture_Capture(@ScriptDir & "\areatemp.jpg", 10, 10, 200, 200) GUICtrlSetImage($Pic3, @ScriptDir & "\areatemp.jpg") ;....  
    • timmy2
      By timmy2
      To save future readers a little sweat I'm editing my original post to insert the following:
      After trying various suggested scripting approaches, some of which introduced new problems and some which had the same problem described here, I tried my script and a few others on another computer. No white flashes, tears, glitches. So I brought it back to my main box and disabled the Intel GPU that was feeding a 3rd monitor. Down to two monitors connected to a single NVidia GPU the visual glitches disappeared. Who would'a thought?!
      That said, some of the replies that follow provide valuable insights into the various ways to skin this cat using AutoIt.  Some suggested scripts introduced new problems so they might be instructive about approaches to avoid. Ultimately, JohnOne suggested an elegantly simple script that perfectly accomplishes my goal.
      ---------------------
      I want to display a  800x600 picture (i.e., not full-screen) without a border, close-box, title, etc.  I then want to replace that picture with another one -- cleanly. Think of an old-fashioned dual-projector slide show where there's no black-out or other interruption to the image on screen. This way I can start with a background image, then add elements to it seamlessly (once called "a build", i.e., pseudo-animation).  The image format doesn't matter to me.
      I can't use an animated GIF or video because my code is doing things in the background between images, so timing varies.
      I'm having bad luck using an AutoIt form to accomplish this (GUICtrlCreatePic, followed by subsequent GUICtrlSetImage's).  The result is a glitch -- usually a white flash or tear in the picture -- at almost every image change. (see 10/10/13 post entitled "random visual glitch when using GUICtrlSetImage"). So I guess that's out.
      SplashImageOn  blanks out the first image before displaying the next (like a single-projector slide show), so it's not seamless -- plus there's still a tiny border visible.
      $var = Default SplashImageOn("","image1.bmp",$var,$var,$var,$var,1) sleep(2000) SplashImageOn("","image2.bmp",$var,$var,$var,$var,1) sleep(2000) SplashImageOn("","image3.bmp",$var,$var,$var,$var,1) sleep(2000) Any suggestions?
    • timmy2
      By timmy2
      I'm displaying a series of BMP images using AutoIt's GUI capabilities.
      Here's my initial test code. All it does is test my goal of displaying a picture, then allowing some code to accomplish a brief task, followed by the next picture, etc. The problem I'm having is that sometimes there's a brief visual glitch in the picture when GUICtrlSetImage displays the next picture. This doesn't happen every time but it happens enough to make the result look funky.
      Any suggestions about what I can do to prevent the glitch? Could it be the specs of the BMP images I'm creating in Photoshop CS6?  Under BMP Options I'm using 24 Bit depth, no RLE compression -- ie., the defaults. (note that I've tried using jpg's instead of bmp file without improvement)
      $form=GUICreate("PowerStrips",900,530,518,272, BitOR($WS_SYSMENU,$WS_POPUP), 0) $cid=GUICtrlCreatePic(@ScriptDir & "\imagebackground.bmp", 0,0, 900, 530) GuiCtrlSetState($cid,$GUI_DISABLE) ;The initial "button" I want to show $PSimage=GUICtrlCreatePic(@ScriptDir & "\image1.bmp", 0,0,900,530) GUISetState(@SW_SHOW) ;show 1st image MsgBox(0,"","test") GUICtrlSetImage($PSimage, @ScriptDir & "\image2.bmp") ;show 2nd image MsgBox(0,"","test") GUICtrlSetImage($PSimage,@ScriptDir & "\image3.bmp") ;show 3rd image MsgBox(0,"","test") GUICtrlSetImage($PSimage,@ScriptDir & "\image4.bmp") 'show 4th image MsgBox(0,"","test") Exit
    • timmy2
      By timmy2
      In a script I'm using the GuiCtrlSetImage command to display a bmp image created in Illustrator. When exporting to bmp from Illustrator the Basic options include 16 bit, 24 bit, and 32 bit.  (all are RGB, 72ppi, with anti-aliasing = "art optimized" (though I tried "none" and it made no difference to the outcomes shown))
      Following are screen captures of how AutoIt's GuiCtrlSetImage command renders the bmp image.
      32 bit original (note ragged edges)

       
      24 bit original (looks closest to original, but there are some black pixel artifacts in the top left chrome border, so it ain't perfect)

       
      16 bit original (note lots of breakup in chrome border and black pixels around border of white silhouette)

       
      As you see, the 24 bit capture is the only acceptable one. However, I had to compromise on the graphic because originally it had "inner glow" effects in the white areas. Below is a screen capture of what AutoIt did to this 24 bit image.  The only difference between this and the previous 24 bit image is that this one has an inner glow (gray to white gradient along edges of white silhoutte) effect.

       
      Either there's a bug in AutoIt or my bmp files are incompatible in some way.  Can anyone tell me the ideal specs for a bmp image for use with GuiCtrlSetImage?  In case it helps, below are some of Illustrator's Advanced Export-to-bmp options (I used the Basic Modes described at the top). Note also that I brought the image into Photoshop and saved it as a bump there, and I got the same artifacts.
       

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.