Sign in to follow this  
Followers 0
qwert

Graphic Elements on GUIs

4 posts in this topic

#1 ·  Posted (edited)

For years, I’ve fashioned scripts that use PNGs or JPGs as elements on a GUI by carefully following examples. Over time, each of my scripts did things a bit different from the others ... sometimes reflecting the changes and advancements in AutoIT and GDI+, I gathered.

Now, I've put together a script that uses parts of the other scripts in an attempt to “bring it all together”. Unfortunately, it doesn’t quite work ... and I’m at a loss to figure which statements are affecting others. The zip file below contains my script and the images.

First and foremost, I’d like someone to confirm (True or False) my basic assumptions:

?AutoIt suports BMPs, GIFs and JPGs as more or less standard image formats ... and supports PNGs and TIFFs as special images that are routed through GDI+ to render them as BMPs.

?The widely-used [bSetupImage function[/b is the best way to display a PNG backdrop that is not a rectangle.

?WM_NCHITTEST() is still the recommended way to enable the backdrop panel to dragged.

?A layered GUI is the only way to approach this style of GUI

I'll mention that my limited knowledge has only come through following dozens of threads and trying out examples. I’ve never found anything that would qualify as an overview of the methods. Is there such a thing?

The two immediate problems that I'd like to solve with my script (there may be others) are:

?The buttons aren’t on the main panel, but, rather, on a draggable grey subpanel.

(BTW, the subpanel floats above the backdrop like a tear-off tool bar ... a nice effect, but not what I need.)

?The bolded text is outlined rather than being black. Why is that?

Beyond those, [bI’d like to upgrade it to use any later methods.[/b Are there any?

For example, does gray.gif still have use, given the advancements in GDI+? I recall it originally had something to do with setting a transparent color.

 

Thanks in advance for any help.

Here's what it should look like:

 

post-29172-0-24585500-1402726964_thumb.p

Panel Test.zip

Edited by Melba23
Resized font

Share this post


Link to post
Share on other sites



For anyone who doesn't have the time to download and run my example, I'm posting the code in hopes that someone will be able to spot the reason the buttons aren't on the main panel.  That's my single biggest issue ... although I'd really like to hear about the other issues I listed.

;
;       Script to test images as buttons on floating PNG backdrop
;
#NoTrayIcon
;
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>

$STM_SETIMAGE = 0x0172
;Global $HBitmap = ""

;=================== create GUI for this process ================
_GDIPlus_Startup()

; Fetch the backdrop image
$backdrop = @ScriptDir & "\Panel.png"
$hImage = _GDIPlus_ImageLoadFromFile($backdrop)
$width = _GDIPlus_ImageGetWidth($hImage)
$height = _GDIPlus_ImageGetHeight($hImage)

; create the main GUI and load with image
Global $GUI = GUICreate("Test",424, 288, -1, -1, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED))
SetBitmap($GUI, $hImage, 255)
GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
GUISetState()

; create child MDI gui window to hold controls
$controlGUI = GUICreate("ControlGUI", $width, $height, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $GUI)
;child window transparency is required to accomplish the full effect??????
GUICtrlCreatePic(@ScriptDir & "\grey.gif", 0, 0, $width, $height)
GUICtrlSetState(-1, $GUI_DISABLE)

; just a text label
GUICtrlCreateLabel("Text on panel", 50, 160, 140, 50)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetColor(-1, 0x000000)
GUICtrlSetFont(-1, 12, 700, "Arial")

; add the exit button
$exit = GUICtrlCreatePic(@ScriptDir & "\exit.bmp", 160, 100, 99, 57, -1, $GUI_WS_EX_PARENTDRAG )
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)

; add the main button
$hPic = GUICtrlCreatePic("", 20, 20, 24, 88, -1, $GUI_WS_EX_PARENTDRAG)
$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\BUTTON.png")
$HBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
_WinAPI_DeleteObject(GUICtrlSendMsg($hPic, $STM_SETIMAGE, $IMAGE_BITMAP, $HBitmap))
GUISetState()

; ============= Run the GUI until the user closes it =============
While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE or $msg = $exit
            _Exit()
        Case $msg = $hPic
            MsgBox(0, "BUTTON", "clicked", 0, $GUI)
    EndSelect
WEnd
;============== functions =============================
Func _Exit()
    _WinAPI_DeleteObject($HBitmap)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
    GUIDelete()
    Exit
EndFunc

Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
    If ($hWnd = $GUI) And ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION
EndFunc   ;==>WM_NCHITTEST

Func SetBitmap($hGUI, $hImage, $iOpacity)
    Local Const $AC_SRC_ALPHA = 1
    Local Const $ULW_ALPHA = 2
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend

    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)

$tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA)

_WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
EndFunc   ;==>SetBitmap

I will appreciate any help.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Try this:

 

;
;       Script to test images as buttons on floating PNG backdrop
;
#NoTrayIcon
;
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>

$STM_SETIMAGE = 0x0172
;Global $HBitmap = ""

;=================== create GUI for this process ================
_GDIPlus_Startup()

; Fetch the backdrop image
$backdrop = @ScriptDir & "\Panel.png"
$hImage = _GDIPlus_ImageLoadFromFile($backdrop)
$width = _GDIPlus_ImageGetWidth($hImage)
$height = _GDIPlus_ImageGetHeight($hImage)
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
$hBitmap_Exit = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\exit.bmp")
$hBitmap_Button = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\BUTTON.png")
_GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap_Exit, 160, 100)
_GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap_Button, 20, 20)

; create the main GUI and load with image
Global $GUI = GUICreate("Test", $width, $height, -1, -1, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED))
$exit = GUICtrlCreateLabel("", 163, 103, 99, 57, -1, $GUI_WS_EX_PARENTDRAG)
$button = GUICtrlCreateLabel("", 23, 23, 142, 73, -1, $GUI_WS_EX_PARENTDRAG)
SetBitmap($GUI, $hImage, 255)
GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
Global $hGUI_Child = GUICreate("", $width, $height, 0, 0, $WS_POPUP, BitOR($WS_EX_MDICHILD, $WS_EX_LAYERED), $GUI)
GUISetBkColor(0xABCDEF, $hGUI_Child)
GUICtrlCreateLabel("Text on panel", 50, 160, 140, 50)
GUICtrlSetFont(-1, 10, 400, 0, "Arial", 5)
_WinAPI_SetLayeredWindowAttributes($hGUI_Child, 0xABCDEF)
GUISetState(@SW_SHOWNA, $GUI)
GUISetState(@SW_SHOW, $hGUI_Child)

; ============= Run the GUI until the user closes it =============
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $exit
            _Exit()
        Case $button
            MsgBox(0, "BUTTON", "clicked", 0, $GUI)
    EndSwitch
WEnd
;============== functions =============================
Func _Exit()
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_BitmapDispose($hBitmap_Exit)
    _GDIPlus_BitmapDispose($hBitmap_Button)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
    GUIDelete()
    Exit
EndFunc

Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
    If ($hWnd = $GUI) And ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION
EndFunc   ;==>WM_NCHITTEST

Func SetBitmap($hGUI, $hImage, $iOpacity)
    Local Const $AC_SRC_ALPHA = 1
    Local Const $ULW_ALPHA = 2
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend

    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)

    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA)

    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
EndFunc   ;==>SetBitmap

Br,

UEZ

Edited by UEZ
1 person likes this

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!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Perfect.

Thanks, UEZ.

For anyone following this topic, here are the changes UEZ made:
>>Bitmaps for all elements are created from their files at the start ... not later.
>>Bitmaps for the multiple graphical elements are disposed of upon exit.
>>The buttons are placed on the main GUI (layered) and not on a child GUI.
>>Only the text is placed on a child GUI and given a background color that is then defined as the transparent color for the layer (which I conclude is to enable “click through” to the main GUI) ... and which cleared the text outline effect.
>>The main loop was changed from Select to Switch ... as a simplification.
>>Grey.gif was removed ... and I would conclude it’s now obsolete for any use.

Other than for _Exit(), the functions did not change. Although left in the statements, $GUI_WS_EX_PARENTDRAG is not needed, since the panel itself is draggable.

Edited by qwert
Resized font

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