Jump to content

Help Displaying Image from ResourcesEx on Buttons


 Share

Recommended Posts

Hello all 👋

I've recently stared using AutoIT as a substitute for Python when creating simplistic GUI applications (I'd rather have an exe that is a few kilobytes in size that does one simple thing rather than a 20MB+ sized exe made with pyinstaller 😂)

I love the syntax of AutoIT since it kinda relates to syntax I'm familiar with; however, I've hit a little bump in the road.

What I am trying to do is make a simple window with two large buttons; the buttons have a bitmap image set to them when the mouse isn't hovering over it. Once the mouse is hovering over a button, that button's image is then changed to a different one, creating a hover effect for the button; and once the mouse moves away from the button, it changes back to the original bitmap.

The following code is a summed up view of the GUI I envision:

#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>

; General Variables
$WINDOWTITLE = "Test Title"

$button1regularBMP = "Graphics\Button1.bmp"
$button1selectedBMP = "Graphics\Button1_selected.bmp"

$button2regularBMP = "Graphics\Button2.bmp"
$button2selectedBMP = "Graphics\Button2_selected.bmp"

; GUI Variables
$WINDOWWIDTH = 500
$WINDOWHEIGHT = 354
$WINDOWICON = ""
$currentlySelectedButton = Null
$currentlySelectedBMP = Null

; GUI Initialization
$Launcher = GUICreate($WINDOWTITLE, $WINDOWWIDTH, $WINDOWHEIGHT)
$button1 = GUICtrlCreateButton("", 0, 0, $WINDOWWIDTH/2, $WINDOWHEIGHT, $BS_BITMAP)
GUICtrlSetImage($button1, $button1regularBMP)
$button2 = GUICtrlCreateButton("", 250, 0, $WINDOWWIDTH/2, $WINDOWHEIGHT, $BS_BITMAP)
GUICtrlSetImage($button2, $button2regularBMP)
GUISetState(@SW_SHOW)

; Main Loop
While 1
    $nMsg = GUIGetMsg()
    $aInfo = GUIGetCursorInfo()
    If Not @error Then $idHover = $aInfo[4]
    If $idHover = $button1 Then
        If $currentlySelectedButton <> $button1 Then
            GUICtrlSetImage($button1, $button1selectedBMP)
            GUICtrlSetImage($currentlySelectedButton, $currentlySelectedBMP)
            $currentlySelectedButton = $button1
            $currentlySelectedBMP = $button1regularBMP
        EndIf
    ElseIf $idHover = $button2 Then
        If $currentlySelectedButton <> $button2 Then
            GUICtrlSetImage($button2, $button2selectedBMP)
            GUICtrlSetImage($currentlySelectedButton, $currentlySelectedBMP)
            $currentlySelectedButton = $button2
            $currentlySelectedBMP = $button2regularBMP
        EndIf
    Else
        If $currentlySelectedButton <> Null Then
            GUICtrlSetImage($currentlySelectedButton, $currentlySelectedBMP)
            ; _Resource_SetBitmapToCtrlID($currentlySelectedButton, $currentlySelectedBMP)
            $currentlySelectedButton = Null
            $currentlySelectedBMP = Null
        EndIf
    EndIf

    Switch $nMSG
        Case $GUI_EVENT_CLOSE
            Exit
        Case $button1
            MsgBox($MB_ICONINFORMATION, "Button Pressed!", "You selected button 1!")
            Exit
        Case $button2
            MsgBox($MB_ICONINFORMATIONINFO, "Button Pressed!", "You selected button 2!")
            Exit
    EndSwitch
WEnd

However, I would like to embed my bitmaps as a resource file using AutoIt3Wrapper, then load them into memory on GUI startup, and then freely use them like I do in the above script.

I have had some luck/interest in using ResourcesEx, such as being able to load the file into memory...but the displaying part of the whole thing isn't working out for me. It will show up with the initial bitmaps displayed, but after waving my cursor over the buttons, the graphics spazz out and ultimately stop showing any sort of hover effect; the buttons themselves are still operational, but the bitmaps refuse to display their hover effects properly.

Here's the code I have using ResourcesEx:

#AutoIt3Wrapper_Res_File_Add=Graphics\Button1.bmp, rt_bitmap, B1_Regular, 0
#AutoIt3Wrapper_Res_File_Add=Graphics\Button1_selected.bmp, rt_bitmap, B1_Selected, 0
#AutoIt3Wrapper_Res_File_Add=Graphics\Button2.bmp, rt_bitmap, B2_Regular, 0
#AutoIt3Wrapper_Res_File_Add=Graphics\Button2_selected.bmp, rt_bitmap, B2_Selected, 0

#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>
#include <ResourcesEx\ResourcesEx.au3>

; General Variables
$WINDOWTITLE = "Test Title"

$button1regularBMP = _Resource_GetAsBitmap("B1_Regular", $RT_BITMAP)
$button1selectedBMP = _Resource_GetAsBitmap("B1_Selected", $RT_BITMAP)

$button2regularBMP = _Resource_GetAsBitmap("B2_Regular", $RT_BITMAP)
$button2selectedBMP = _Resource_GetAsBitmap("B2_Selected", $RT_BITMAP)

; GUI Variables
$WINDOWWIDTH = 500
$WINDOWHEIGHT = 354
$WINDOWICON = ""
$currentlySelectedButton = Null
$currentlySelectedBMP = Null

; GUI Initialization
$Launcher = GUICreate($WINDOWTITLE, $WINDOWWIDTH, $WINDOWHEIGHT)
$button1 = GUICtrlCreateButton("", 0, 0, $WINDOWWIDTH/2, $WINDOWHEIGHT, $BS_BITMAP)
_Resource_SetBitmapToCtrlID($button1, $button1regularBMP)
$button2 = GUICtrlCreateButton("", 250, 0, $WINDOWWIDTH/2, $WINDOWHEIGHT, $BS_BITMAP)
_Resource_SetBitmapToCtrlID($button2, $button2regularBMP)
GUISetState(@SW_SHOW)

; Main Loop
While 1
    $nMsg = GUIGetMsg()
    $aInfo = GUIGetCursorInfo()
    If Not @error Then $idHover = $aInfo[4]
    If $idHover = $button1 Then
        If $currentlySelectedButton <> $button1 Then
            _Resource_SetBitmapToCtrlID($button1, $button1selectedBMP)
            _Resource_SetBitmapToCtrlID($currentlySelectedButton, $currentlySelectedBMP)
            $currentlySelectedButton = $button1
            $currentlySelectedBMP = $button1regularBMP
        EndIf
    ElseIf $idHover = $button2 Then
        If $currentlySelectedButton <> $button2 Then
            _Resource_SetBitmapToCtrlID($button2, $button2selectedBMP)
            _Resource_SetBitmapToCtrlID($currentlySelectedButton, $currentlySelectedBMP)
            $currentlySelectedButton = $button2
            $currentlySelectedBMP = $button2regularBMP
        EndIf
    Else
        If $currentlySelectedButton <> Null Then
            _Resource_SetBitmapToCtrlID($currentlySelectedButton, $currentlySelectedBMP)
            $currentlySelectedButton = Null
            $currentlySelectedBMP = Null
        EndIf
    EndIf

    Switch $nMSG
        Case $GUI_EVENT_CLOSE
            Exit
        Case $button1
            MsgBox($MB_ICONINFORMATION, "Button Pressed!", "You selected button 1!")
            Exit
        Case $button2
            MsgBox($MB_ICONINFORMATION, "Button Pressed!", "You selected button 2!")
            Exit
    EndSwitch
WEnd

I'm guessing I'm just handling it wrong? My Google-Fu skills have been pretty much exhausted over the past day and a half. Once this GUI stuff is done, I believe I'll be set.

I don't necessarily mind if I have to dump the file into a temp directory first before doing what I want to do with it, as I can simply tell the script to delete the temp folder once it exits, but I would appreciate it if there were an alternative that doesn't require me doing that.

Any advice is much appreciated. 😃

I'll also attach the test bitmaps for y'all to mess with so that you won't have to tinker with that part of the code much. The script reads them from a Graphics folder, as can be seen in either script.

Graphics.zip

Link to comment
Share on other sites

The problem is that you are manipulating objects, not file names.  When using _Resource_SetBitmapToCtrlID, it deletes the old object (the one that was displayed before) to ensure that memory is disposed.  Once the object is deleted you do not have access to it anymore.  This is why it works at once and it stops after first change.  So you need to recreate the object after each _Resource_SetBitmapToCtrlID.  Be careful with that type of usage, do not assign existing object to another variable, if you don't dispose object correctly, you will have a massive memory leak.

Link to comment
Share on other sites

Been a while since using the Resources UDF but found an old script I used for button hovering, it appears to still work, hope it helps.

Note: You can also use png files if you want to lower the size of the images

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Res_Description=Graphics Example
#AutoIt3Wrapper_Res_Fileversion=20.3.6.0
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=n
#AutoIt3Wrapper_Res_File_Add=Button1.bmp,10,B1_Regular
#AutoIt3Wrapper_Res_File_Add=Button1_selected.bmp,10,B1_Selected
#AutoIt3Wrapper_Res_File_Add=Button2.bmp,10,B2_Regular
#AutoIt3Wrapper_Res_File_Add=Button2_selected.bmp,10,B2_Selected
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <GUIConstantsEx.au3>
#include <GuiButton.au3>
#include <GuiImageList.au3>
#include <ButtonConstants.au3>
#include <ResourcesEx.au3>

Global $g_hButton1 = _GUIImageList_Create(250, 354, 5)
    _ImageCatalog($g_hButton1, 'B1_Regular')
    _ImageCatalog($g_hButton1, 'B1_Selected')

Global $g_hButton2 = _GUIImageList_Create(250, 354, 5)
    _ImageCatalog($g_hButton2, 'B2_Regular')
    _ImageCatalog($g_hButton2, 'B2_Selected')

; General Variables
Global $g_sWindowTitle = "Test Title"

; GUI Variables
Global $g_iWidth = 500
Global $g_iHeight = 354

; GUI Initialization
GUICreate($g_sWindowTitle, $g_iWidth, $g_iHeight)
Global $g_idButton1 = GUICtrlCreateButton("", 0, 0, $g_iWidth/2, $g_iHeight, $BS_BITMAP)
    _GUICtrlButton_SetImageList($g_idButton1, $g_hButton1)
Global $g_idButton2 = GUICtrlCreateButton("", 250, 0, $g_iWidth/2, $g_iHeight, $BS_BITMAP)
    _GUICtrlButton_SetImageList($g_idButton2, $g_hButton2)
GUISetState()

While 1
    $nMsg = GUIGetMsg()
    Switch $nMSG
        Case $GUI_EVENT_CLOSE
            Exit
        Case $g_idButton1
            MsgBox($MB_ICONINFORMATION, "Button Pressed!", "You selected button 1!")
            Exit
        Case $g_idButton2
            MsgBox($MB_ICONINFORMATION, "Button Pressed!", "You selected button 2!")
            Exit
    EndSwitch
WEnd

; #INTERNAL_USE_ONLY#=================================================================================================
; Name...........: _ImageCatalog
; Description ...: Add Resources to ImageList as Bitmap images
; Syntax ........: _ImageCatalog($_hImageList, $_sImageRes)
; Parameters ....: $_hImageList - Image List Handle
;                : $_sImageRes  - Resource Name
; Requirement(s) :
; Return values .: Success - Adds Resource to Image List
; Author ........: Subz
; Remarks .......:
;=====================================================================================================================
Func _ImageCatalog($_hImageList, $_sImageRes)
    Local $hImageRes = _Resource_GetAsBitmap($_sImageRes, $RT_RCDATA)
    _GUIImageList_Add($_hImageList, $hImageRes)
    _WinAPI_DeleteObject($hImageRes)
    Return 1
EndFunc

 

Link to comment
Share on other sites

@Nine

Thank you for your reply! The explanation was very informative 😁

@Subz

And thank you as well for the test script! If I ever make a GUI that holds a bunch of images, I think this will help me for sure.

Shortly after Nine responded, I sat down and created a function to auto load/auto assign the needed resource to the buttons, which now works like a charm!

Thanks to both of you, my GUI is now fully operational; and I can now continue on with my code refinement/distribution! Hope y'all have a great day!

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...