Sign in to follow this  
Followers 0
ALTIN

[SOLVED] How can I get GDI image handler??

8 posts in this topic

#1 ·  Posted (edited)

I want to use PNG images in my program because of their background transparency.

I read help file and im trying to use the example for the GDI+ library.

I need to know when the image is clicked so I must haved an image handler for that.

Is it possible to get the handler of the image created with GDI+ functions? (since even WindowInfo tool does not show any info of the image, I suppose we cant get it)!

However if yes, what should I add in the script below?

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>

_Main()
Func _Main()
    Local $hGUI, $hBMP, $hBitmap, $hGraphic, $hImage, $iX, $iY, $hClone, $t
    Local $pngFile = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _
    & "\Examples\GUI\Advanced\Images\Button.png"
    
    ; Create GUI
    $hGUI = GUICreate("GDI+", 400, 300)
    GUISetState()

    ; Initialize GDI+ library
    _GDIPlus_Startup ()

    ; Draw bitmap to GUI
    $hBitmap = _GDIPlus_ImageLoadFromFile ($pngFile)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
    _GDIPlus_GraphicsDrawImage ($hGraphic, $hBitmap, 0, 0)

    ; Clean up resources
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_BitmapDispose ($hBitmap)

    ; Shut down GDI+ library
    _GDIPlus_ShutDown ()

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc ;==>_Main

Any idea around this?

Edited by ALTIN

Share this post


Link to post
Share on other sites



This is a method of creating clickable image "hotspots".

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>

Opt("MouseCoordMode", 2) ;1=absolute, 0=relative, 2=client

Global $hGUI, $hGraphicGUI, $hBMPBuff

_Main()
Func _Main()
    Local $hBMP, $hBitmap, $hGraphic, $hImage, $iX, $iY, $hClone, $t, $aMPos
    Local $GuiSizeX = 400, $GuiSizeY = 300
    Local $pngFile = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _
             & "\Examples\GUI\Advanced\Images\Button.png"

    ; Create GUI
    $hGUI = GUICreate("GDI+", $GuiSizeX, $GuiSizeY)
    ;GUISetBkColor(0xFFFFEF)
    GUISetState()

    _GDIPlus_Startup()

    $hBitmap = _GDIPlus_ImageLoadFromFile($pngFile)
    $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)

    _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 0, 0)
    GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3)
    GUIRegisterMsg(0x85, "MY_PAINT") ; $WM_NCPAINT = 0x0085 (WindowsConstants.au3)Restore after Minimize.
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)

    Do
        $aMPos = MouseGetPos()
        If ispressed("01") Then
            Select
                Case _WinAPI_PtInRectEx($aMPos[0], $aMPos[1], 5, 5, 112, 56)
                    MsgBox(0, "", " Top button clicked", 1)
                Case _PointInEllipse($aMPos[0], $aMPos[1], 122, 100, 132, 45)
                    MsgBox(0, "", "Middle elliptic button clicked", 1)
                Case _WinAPI_PtInRectEx($aMPos[0], $aMPos[1], 5, 192, 112, 243)
                    MsgBox(0, "", "Lowest button clicked", 1)
            EndSelect
        EndIf
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ; Clean up resources
    _GDIPlus_GraphicsDispose($hGraphicGUI)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_BitmapDispose($hBMPBuff)
    _GDIPlus_Shutdown()

EndFunc ;==>_Main


; ($xPt, $yPt) - x, y position of the point to check
; $xTL, $yTL, Top left x Pos, top left Y position of the rectangle encompassing the ellipse.
; $w, $h - The width an height of ellipse
; http://www.autoitscript.com/forum/index.php?showtopic=89034&view=findpost&p=639786
;
Func _PointInEllipse($xPt, $yPt, $xTL, $yTL, $w, $h)
    Local $bInside = False, $a = $w / 2, $b = $h / 2
    Local $c1X, $c2X, $dist, $xc = $xTL + $a, $yc = $yTL + $b
    $c1X = $xc - ($a ^ 2 - $b ^ 2) ^ (1 / 2); 1st focal point x position
    $c2X = $xc + ($a ^ 2 - $b ^ 2) ^ (1 / 2); 2nd focal point x position
    $dist = (($xPt - $c1X) ^ 2 + ($yPt - $yc) ^ 2) ^ 0.5 + (($xPt - $c2X) ^ 2 + ($yPt - $yc) ^ 2) ^ 0.5
    If $dist <= $w Then $bInside = Not $bInside
    Return $bInside
EndFunc ;==>_PointInEllipse

; ($iX, $iY)    - x, y position of the point to check
; ($iLeft, $iTop)   - x, y position of the top left corner of rectangle
; ($iRight, $iBottom) - x, y position of the bottom right corner of rectangle
; http://www.autoitscript.com/forum/index.php?showtopic=89034&view=findpost&p=639786
;
Func _WinAPI_PtInRectEx($iX, $iY, $iLeft, $iTop, $iRight, $iBottom)
    Local $aResult
    Local $tRect = DllStructCreate($tagRECT)
    DllStructSetData($tRect, "Left", $iLeft)
    DllStructSetData($tRect, "Top", $iTop)
    DllStructSetData($tRect, "Right", $iRight)
    DllStructSetData($tRect, "Bottom", $iBottom)
    $aResult = DllCall("User32.dll", "int", "PtInRect", "ptr", DllStructGetPtr($tRect), "int", $iX, "int", $iY)
    If @error Then Return SetError(@error, 0, False)
    Return $aResult[0] <> 0
EndFunc ;==>_WinAPI_PtInRectEx

; Copied from ...\Include\Misc.au3 File
Func IsPressed($sHexKey)
    Local $a_R = DllCall('user32.dll', "int", "GetAsyncKeyState", "int", '0x' & $sHexKey)
    If Not @error And BitAND($a_R[0], 0x8000) = 0x8000 Then Return 1
    Return 0
EndFunc ;==>IsPressed

;Func to redraw on PAINT MSG
Func MY_PAINT($hWnd, $msg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    _WinAPI_RedrawWindow($hGUI, "", "", BitOR($RDW_INVALIDATE, $RDW_FRAME, $RDW_ALLCHILDREN)) ;
    Return $GUI_RUNDEFMSG
EndFunc ;==>MY_PAINT

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Hi,

Other way is to use picture controls and use GUICtrlSendMsg() to set the picture to the control.

This way you can still use GUIGetMsg() or OnEventMode to catch the clicks.

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>

_Main()

Func _Main()
    Local $hGUI, $iPicButton, $hGraphic, $hImage, $hBitmap1, $hGraphic1, $hBMP1, $iMsg
    Local $pngFile = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _
             & "\Examples\GUI\Advanced\Images\Button.png"

    $hGUI = GUICreate("GDI+", 400, 300)
    GUISetBkColor(0x000000, $hGUI)
    $iPicButton = GUICtrlCreatePic("", 10, 10, 82, 36)
    GUISetState()

    _GDIPlus_Startup()

    $hImage = _GDIPlus_ImageLoadFromFile($pngFile)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    $hBitmap1 = _GDIPlus_BitmapCreateFromGraphics(82, 36, $hGraphic)
    $hGraphic1 = _GDIPlus_ImageGetGraphicsContext($hBitmap1)
    _GDIPlus_GraphicsDrawImageRectRect($hGraphic1, $hImage, 11, 145, 82, 36, 0, 0, 82, 36)
    $hBMP1 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap1)

    _GDIPlus_GraphicsDispose($hGraphic1)
    _GDIPlus_BitmapDispose($hBitmap1)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()

    _WinAPI_DeleteObject(GUICtrlSendMsg($iPicButton, 0x0172, 0, $hBMP1))

    While 1
        $iMsg = GUIGetMsg()
        Switch $iMsg
            Case $GUI_EVENT_CLOSE
                _WinAPI_DeleteObject($hBMP1)
                ExitLoop
            Case $iPicButton
                MsgBox(64, "Picture Clicked", "Yep picture has been clicked")
        EndSwitch
    WEnd
EndFunc   ;==>_Main

Cheers

Edited by smashly

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Hey Malkey and Smashly thanks very much you both. Both of your examples work great but I think Im going

to use smashly's method just because my head starts spinning when I have to do with DllStructure thing :) and

it looks simplier to me.

I admit i had thought about doing something similar to smashly's example but that's better anyway.

Thanks you both guys, your help is much appreciated ;)

Edited by ALTIN

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Call me lazy, but I just use a label (without any text). It is invisible but catch mouse-clicks.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>

_Main()
Func _Main()
    Local $hGUI, $hBMP, $hBitmap, $hGraphic, $hImage, $iX, $iY, $hClone, $t
    Local $pngFile = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _
    & "\Examples\GUI\Torus.png"

    ; Create GUI
    $hGUI = GUICreate("GDI+", 400, 300)
    $Button = GUICtrlCreateLabel("", 0, 0, 193, 184)
    GUISetState()

    ; Initialize GDI+ library
    _GDIPlus_Startup ()

    ; Draw bitmap to GUI
    $hBitmap = _GDIPlus_ImageLoadFromFile ($pngFile)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, 193, 184) ;The size came out wrong with _GDIPlus_GraphicsDrawImage for some reason :S

    ; Clean up resources
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_BitmapDispose ($hBitmap)

    ; Shut down GDI+ library
    _GDIPlus_ShutDown ()

    ; Loop until user exits
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Exit
            Case $Button
                MsgBox(0, "Some Title", "Some Text")
        EndSwitch
    WEnd
EndFunc ;==>_Main

Edit: rewording

Edited by AdmiralAlkex

Share this post


Link to post
Share on other sites

Call me lazy, but I just use a label (without any text). It is invisible but catch mouse-clicks.

Lol, lazy ;) by the way, in your example when I move the msgbox over the window, it erases the image... how can I prevent this?

Share this post


Link to post
Share on other sites

Something like this:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>

Global $hBitmap, $hGraphic, $hBrush

_Main()
Func _Main()
    Local $hGUI
    Local $pngFile = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _
    & "\Examples\GUI\Torus.png"

    ; Create GUI
    $hGUI = GUICreate("GDI+", 400, 300)
    $Button = GUICtrlCreateLabel("", 0, 0, 193, 184)
    GUISetState()

    GUIRegisterMsg(0x000F, "_SomeFunction") ;0x000F = $WM_PAINT

    ; Initialize GDI+ library
    _GDIPlus_Startup ()

    ; Draw bitmap to GUI
    $hBitmap = _GDIPlus_ImageLoadFromFile ($pngFile)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
    $hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
    _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, 193, 184, $hBrush)
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, 193, 184) ;The size came out wrong with _GDIPlus_GraphicsDrawImage for some reason :S

    ; Loop until user exits
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ; Clean up resources
                _GDIPlus_BrushDispose($hBrush)
                _GDIPlus_GraphicsDispose ($hGraphic)
                _GDIPlus_BitmapDispose ($hBitmap)

                ; Shut down GDI+ library
                _GDIPlus_ShutDown ()
                Exit
            Case $Button
                MsgBox(0, "Some Title", "Some Text")
        EndSwitch
    WEnd
EndFunc ;==>_Main

Func _SomeFunction()
    Sleep(10) ;looks weird without sleep at my machine (win7)
    _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, 193, 184, $hBrush)
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, 193, 184)
EndFunc

;)

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

;)

:);):shocked:

Edited by ALTIN

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