Jump to content

GDIPlus Graphics object resized


Recommended Posts

Hi,

What the best way to resize a graphics (from _GDIPlus_GraphicsCreateFromHWND) when the Gui is resized ?

I just call $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) again in WM_SIZE Message function, is it ok ?

 

Thanks for your time.

 

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPISysWin.au3>
#include <WinAPIGdi.au3>
#include <WinAPI.au3>



Local $hDLL = DllOpen("user32.dll")
AutoItSetOption("MouseCoordMode", 2)

;Register callback
$hKey_Proc = DllCallbackRegister("_Mouse_Proc", "int", "int;ptr;ptr")
$hM_Module = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
$hM_Hook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", $WH_MOUSE_LL, "ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hM_Module[0], "dword", 0)

Global Const $MSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo"

Global $currentEvent[2]
Global $iLBUTTONDOWN = 0
Global $iRBUTTONDOWN = 0
Global $iMBUTTONDOWN = 0
Global $LRClickStatus = 0
Global $RLClickStatus = 0
Global $LRDrag = 0
Global $RLDrag = 0
Global $LMDrag = 0
Global $RMDrag = 0
Global $doubleClickTime = 400
Global $tPoint


Local $hGUI, $hGraphics, $hBackbuffer, $hBitmap
Local Const $width = Int(@DesktopWidth * 0.5), $height = Int(@DesktopHeight * 0.5)

Global $max_width = 1900
Global $max_height = 1000


; Initialize GDI+
_GDIPlus_Startup()

Local $GUI_title = "GDI+"
$hGUI = GUICreate($GUI_title, $width, $height, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_THICKFRAME,$WS_TABSTOP))
GUISetState()


Dim $tab[1][2]


Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($max_width, $max_height, $hGraphics)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
_GDIPlus_GraphicsClear($hBackbuffer, 0xFFF0F0F0)


$hPen = _GDIPlus_PenCreate(0xFF000000, 2)

$cadre_x = 100
$cadre_y = 100
$cadre_largeur = 200
$cadre_hauteur = 200

_GDIPlus_GraphicsDrawRect($hBackbuffer, $cadre_x, $cadre_y, $cadre_largeur, $cadre_hauteur, $hPen) ; cadre
_GDIPlus_GraphicsDrawRect($hBackbuffer, $cadre_x, $cadre_y + 15, $cadre_largeur, 15, $hPen) ; titre
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $max_width, $max_height)

$tab[0][0] = $cadre_x
$tab[0][1] = $cadre_y

Global $decalageX, $decalageY
Global $deplacement_en_cours = False
Global $index_stack


GUIRegisterMsg($WM_PAINT, "WM_PAINT")
GUIRegisterMsg($WM_SIZE, "WM_SIZE")

While 1
    $msg = GUIGetMsg()

    Switch $msg

        Case $GUI_EVENT_CLOSE
            _Exit()

        Case $GUI_EVENT_MAXIMIZE
            $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    EndSwitch

WEnd


Func _Mouse_Proc($nCode, $wParam, $lParam)
    Local $info, $mouseData, $time, $timeDiff

    If $nCode < 0 Then
        $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _
                "int", $nCode, "ptr", $wParam, "ptr", $lParam)
        Return $ret[0]
    EndIf

    $info = DllStructCreate($MSLLHOOKSTRUCT, $lParam)
    $mouseData = DllStructGetData($info, 3)
    $time = DllStructGetData($info, 5)
    $timeDiff = $time - $currentEvent[1]

    Select
        Case $wParam = $WM_MOUSEMOVE
            ;Test for Drag in here

            If $currentEvent[0] <> "LDrag" Or $currentEvent[0] <> "LRDrag" Or $currentEvent[0] <> "LMDrag" Then
                If $iLBUTTONDOWN = 1 Then
;~                  If $currentEvent[0] <> "LDrag" Then GUICtrlSetBkColor($tab_data_gui_fille[$index_gui_fille_en_deplacement][1], $violet) ; violet
                    $currentEvent[0] = "LDrag"

                    If $deplacement_en_cours Then
                        $mouseX = MouseGetPos(0)
                        $mouseY = MouseGetPos(1)

                        _GDIPlus_GraphicsClear($hBackbuffer, 0xFFF0F0F0)
                        _GDIPlus_GraphicsDrawRect($hBackbuffer, $mouseX - $decalageX, $mouseY - $decalageY, $cadre_largeur, $cadre_hauteur, $hPen) ; cadre
                        _GDIPlus_GraphicsDrawRect($hBackbuffer, $mouseX - $decalageX, $mouseY - $decalageY + 15, $cadre_largeur, 15, $hPen) ; titre
                        _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $max_width, $max_height)

                        $tab[$index_stack][0] = $mouseX - $decalageX
                        $tab[$index_stack][1] = $mouseY - $decalageY

                    EndIf

                    If $iRBUTTONDOWN = 1 Then
                        $currentEvent[0] = "LRDrag"
                        $LRDrag = 2
                    EndIf
                EndIf
            EndIf

            If $currentEvent[0] <> "RDrag" Or $currentEvent[0] <> "RMDrag" Or $currentEvent[0] <> "LRDrag" Then
                If $iRBUTTONDOWN = 1 Then
                    $currentEvent[0] = "RDrag"
                EndIf
            EndIf

            If $currentEvent[0] <> "MDrag" Then
                If $iMBUTTONDOWN = 1 Then
                    $currentEvent[0] = "MDrag"
                    $currentEvent[1] = $time
                EndIf
            EndIf

            If $iRBUTTONDOWN = 1 And $iMBUTTONDOWN = 1 And $currentEvent[0] <> "RMDrag" Then
                $RMDrag = 2
                $currentEvent[0] = "RMDrag"
                $currentEvent[1] = $time
            EndIf

            If $iLBUTTONDOWN = 1 And $iMBUTTONDOWN = 1 And $currentEvent[0] <> "LMDrag" Then
                $LMDrag = 2
                $currentEvent[0] = "LMDrag"
                $currentEvent[1] = $time
            EndIf


        Case $wParam = $WM_MOUSEWHEEL

            If _WinAPI_HiWord($mouseData) > 0 Then
                ;Wheel Up
                $currentEvent[0] = "WheelUp"
                $currentEvent[1] = $time
            Else
                ;Wheel Down
                $currentEvent[0] = "WheelDown"
                $currentEvent[1] = $time
            EndIf

        Case $wParam = $WM_LBUTTONDOWN
            $mouseX = MouseGetPos(0)
            $mouseY = MouseGetPos(1)

            For $i = 0 To UBound($tab) - 1
                If  $mouseX > $tab[$i][0] And $mouseX < $tab[$i][0] + $cadre_largeur And _
                    $mouseY > $tab[$i][1] And $mouseY < $tab[$i][1] + $cadre_hauteur Then

                    $decalageX = $mouseX - $tab[$i][0]
                    $decalageY = $mouseY - $tab[$i][1]

                    ; ... on peut déplacer
                    $deplacement_en_cours = True
                    $index_stack = $i
                EndIf
            Next


            ; Register Button Down, check for Right/Left
            If $currentEvent[0] = "RClick" Then
                $LRClickStatus = 1
            EndIf

            $iLBUTTONDOWN = 1

        Case $wParam = $WM_LBUTTONUP
            ;Update $iLBUTTONDOWN
            $iLBUTTONDOWN = 0

;~          If $deplacement_en_cours Then GUICtrlSetBkColor($tab_data_gui_fille[$index_gui_fille_en_deplacement][1], $vert) ; vert

            ;Test for Right/Left Click
            If $RLClickStatus = 1 And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "RLClick"
                $currentEvent[1] = $time
            EndIf
            If $currentEvent[0] = "LClick" And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "LDClick"
                $currentEvent[1] = $time
            EndIf

            ;Test for Drops
            If $currentEvent[0] = "LDrag" Then
                $currentEvent[0] = "LDrop"
                $currentEvent[1] = $time

                ; si un déplacement était en cours, on indique que c'est terminé puisqu'on vient de relacher le bouton de la souris
                If $deplacement_en_cours Then
                    $deplacement_en_cours = False
                EndIf

            EndIf

            If $LRDrag = 2 And $iRBUTTONDOWN = 1 Then
                $LRDrag = 1 ; Denote $LRDrag as still having one button clicked, need to register the drop on RButton up
            EndIf

            If $LRDrag = 1 And $iRBUTTONDOWN = 0 Then
                $currentEvent[0] = "LRDrop"
                $currentEvent[1] = $time
                $LRDrag = 0
            EndIf

            If $LMDrag = 2 And $iMBUTTONDOWN = 1 Then
                $LMDrag = 1 ; Denote $LMDrag as still having one button clicked, need to register the drop on MButton up
            EndIf

            If $LMDrag = 1 And $iMBUTTONDOWN = 0 Then
                $currentEvent[0] = "LMDrop"
                $currentEvent[1] = $time
                $LMDrag = 0
            EndIf

            ;Set LClick if other events haven't fired
            If $currentEvent[1] <> $time Then
                $currentEvent[0] = "LClick"
                $currentEvent[1] = $time
            EndIf

            ;Negate $LRClickStatus
            $RLClickStatus = 0


        Case $wParam = $WM_RBUTTONDOWN
            ;Register Button Down
            If $currentEvent[0] = "LClick" Then
                $RLClickStatus = 1
            EndIf
            $iRBUTTONDOWN = 1

        Case $wParam = $WM_RBUTTONUP
            ;Test for Left, Right, and Right Doubleclick here
            ;Update $iRBUTTONDOWN
            $iRBUTTONDOWN = 0
            ;Test for Right/Left Click
            If $LRClickStatus = 1 And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "LRClick"
                $currentEvent[1] = $time
            EndIf
            If $currentEvent[0] = "RClick" And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "RDClick"
                $currentEvent[1] = $time
            EndIf
            ;Test for Drops
            If $currentEvent[0] = "RDrag" Then
                $currentEvent[0] = "RDrop"
                $currentEvent[1] = $time
            EndIf

            If $LRDrag = 2 And $iLBUTTONDOWN = 1 Then
                $LRDrag = 1 ; Denote $LRDrag as still having one button clicked, need to register the drop on RButton up
            EndIf

            If $LRDrag = 1 And $iLBUTTONDOWN = 0 Then
                $currentEvent[0] = "LRDrop"
                $currentEvent[1] = $time
                $LRDrag = 0
            EndIf



            If $RMDrag = 2 And $iMBUTTONDOWN = 1 Then
                $RMDrag = 1 ; Denote $LMDrag as still having one button clicked, need to register the drop on MButton up
            EndIf

            If $RMDrag = 1 And $iMBUTTONDOWN = 0 Then
                $currentEvent[0] = "RMDrop"
                $currentEvent[1] = $time
                $RMDrag = 0
            EndIf

            ;Set LClick if other events haven't fired
            If $currentEvent[1] <> $time Then
                $currentEvent[0] = "RClick"
                $currentEvent[1] = $time
            EndIf

            ;Negate $LRClickStatus
            $LRClickStatus = 0


        Case $wParam = $WM_MBUTTONDOWN
            ;Register Button Down
            $iMBUTTONDOWN = 1

        Case $wParam = $WM_MBUTTONUP
            ;Test for Middle Double Click here
            ;Update $iRBUTTONDOWN
            $iMBUTTONDOWN = 0
            ;Test for Right/Left Click
            If $currentEvent[0] = "MClick" And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "MDClick"
                $currentEvent[1] = $time
            EndIf
            ;Test for Drops
            If $currentEvent[0] = "MDrag" Then
                $currentEvent[0] = "MDrop"
                $currentEvent[1] = $time
            EndIf

            If $LMDrag = 2 And $iLBUTTONDOWN = 1 Then
                $LMDrag = 1 ; Denote $LRDrag as still having one button clicked, need to register the drop on RButton up
            EndIf

            If $LMDrag = 1 And $iLBUTTONDOWN = 0 Then
                $currentEvent[0] = "LMDrop"
                $currentEvent[1] = $time
                $LMDrag = 0
            EndIf



            If $RMDrag = 2 And $iRBUTTONDOWN = 1 Then
                $RMDrag = 1 ; Denote $LMDrag as still having one button clicked, need to register the drop on MButton up
            EndIf

            If $RMDrag = 1 And $iRBUTTONDOWN = 0 Then
                $currentEvent[0] = "RMDrop"
                $currentEvent[1] = $time
                $RMDrag = 0
            EndIf

            ;Set MClick if other events haven't fired
            If $currentEvent[1] <> $time Then
                $currentEvent[0] = "MClick"
                $currentEvent[1] = $time
            EndIf

    EndSelect

;~  If $currentEvent[0] <> "" Then ConsoleWrite("event:"&$currentEvent[0] & @CRLF)

    $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _
            "int", $nCode, "ptr", $wParam, "ptr", $lParam)
    Return $ret[0]
EndFunc   ;==>_Mouse_Proc


Func WM_PAINT($hwnd, $iMsg, $wParam, $lParam)
    If $hwnd = $hGUI Then
        _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0)
        _WinAPI_RedrawWindow($hwnd, 0, 0, $RDW_VALIDATE)
    EndIf

    Return 'GUI_RUNDEFMSG'
EndFunc   ;==>WM_PAINT

Func WM_SIZE($hwnd, $iMsg, $wParam, $lParam)
    If $hwnd = $hGUI Then
        $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    EndIf

    Return 'GUI_RUNDEFMSG'
EndFunc


Func _Exit()
    DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hM_Hook[0])
    $hM_Hook[0] = 0
    DllCallbackFree($hKey_Proc)
    $hKey_Proc = 0

    ; Clean up
    _GDIPlus_BrushDispose($hPen)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_BitmapDispose ($hBitmap)
    _GDIPlus_GraphicsDispose($hGraphics)

    ; Uninitialize GDI+
    _GDIPlus_Shutdown()

    DllClose($hDLL)
    Exit
EndFunc

 

Edited by tatane
Link to comment
Share on other sites

Like this?

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPISysWin.au3>
#include <WinAPIGdi.au3>
#include <WinAPI.au3>



Local $hDLL = DllOpen("user32.dll")
AutoItSetOption("MouseCoordMode", 2)

;Register callback
$hKey_Proc = DllCallbackRegister("_Mouse_Proc", "int", "int;ptr;ptr")
$hM_Module = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
$hM_Hook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", $WH_MOUSE_LL, "ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hM_Module[0], "dword", 0)

Global Const $MSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo"

Global $currentEvent[2]
Global $iLBUTTONDOWN = 0
Global $iRBUTTONDOWN = 0
Global $iMBUTTONDOWN = 0
Global $LRClickStatus = 0
Global $RLClickStatus = 0
Global $LRDrag = 0
Global $RLDrag = 0
Global $LMDrag = 0
Global $RMDrag = 0
Global $doubleClickTime = 400
Global $tPoint


Local $hGUI, $hGraphics, $hBackbuffer, $hBitmap
Local Const $width = Int(@DesktopWidth * 0.5), $height = Int(@DesktopHeight * 0.5)

Global $max_width = 1900
Global $max_height = 1000


; Initialize GDI+
_GDIPlus_Startup()

Local $GUI_title = "GDI+"
$hGUI = GUICreate($GUI_title, $width, $height, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_THICKFRAME,$WS_TABSTOP))
GUISetState()


Dim $tab[1][2]


;~ $tab[0][0] = $cadre_x
;~ $tab[0][1] = $cadre_y

Global $decalageX, $decalageY
Global $deplacement_en_cours = False
Global $index_stack


GUIRegisterMsg($WM_PAINT, "WM_PAINT")
GUIRegisterMsg($WM_SIZE, "WM_SIZE")

While 1
    $msg = GUIGetMsg()

    Local $aWindowsSize = WinGetClientSize($hGUI)
    Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($max_width, $max_height, $hGraphics)
    $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFFF0F0F0)


    $hPen = _GDIPlus_PenCreate(0xFF000000, 2)

    $cadre_x = 100
    $cadre_y = 100
    $cadre_largeur = $aWindowsSize[0] - 200
    $cadre_hauteur = $aWindowsSize[1] - 200

    _GDIPlus_GraphicsDrawRect($hBackbuffer, $cadre_x, $cadre_y, $cadre_largeur, $cadre_hauteur, $hPen) ; cadre
    _GDIPlus_GraphicsDrawRect($hBackbuffer, $cadre_x, $cadre_y + 15, $cadre_largeur, 15, $hPen) ; titre
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $max_width, $max_height)

    Switch $msg

        Case $GUI_EVENT_CLOSE
            _Exit()

        Case $GUI_EVENT_MAXIMIZE
            $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    EndSwitch

WEnd


Func _Mouse_Proc($nCode, $wParam, $lParam)
    Local $info, $mouseData, $time, $timeDiff

    If $nCode < 0 Then
        $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _
                "int", $nCode, "ptr", $wParam, "ptr", $lParam)
        Return $ret[0]
    EndIf

    $info = DllStructCreate($MSLLHOOKSTRUCT, $lParam)
    $mouseData = DllStructGetData($info, 3)
    $time = DllStructGetData($info, 5)
    $timeDiff = $time - $currentEvent[1]

    Select
        Case $wParam = $WM_MOUSEMOVE
            ;Test for Drag in here

            If $currentEvent[0] <> "LDrag" Or $currentEvent[0] <> "LRDrag" Or $currentEvent[0] <> "LMDrag" Then
                If $iLBUTTONDOWN = 1 Then
;~                  If $currentEvent[0] <> "LDrag" Then GUICtrlSetBkColor($tab_data_gui_fille[$index_gui_fille_en_deplacement][1], $violet) ; violet
                    $currentEvent[0] = "LDrag"

                    If $deplacement_en_cours Then
                        $mouseX = MouseGetPos(0)
                        $mouseY = MouseGetPos(1)

                        _GDIPlus_GraphicsClear($hBackbuffer, 0xFFF0F0F0)
                        _GDIPlus_GraphicsDrawRect($hBackbuffer, $mouseX - $decalageX, $mouseY - $decalageY, $cadre_largeur, $cadre_hauteur, $hPen) ; cadre
                        _GDIPlus_GraphicsDrawRect($hBackbuffer, $mouseX - $decalageX, $mouseY - $decalageY + 15, $cadre_largeur, 15, $hPen) ; titre
                        _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $max_width, $max_height)

                        $tab[$index_stack][0] = $mouseX - $decalageX
                        $tab[$index_stack][1] = $mouseY - $decalageY

                    EndIf

                    If $iRBUTTONDOWN = 1 Then
                        $currentEvent[0] = "LRDrag"
                        $LRDrag = 2
                    EndIf
                EndIf
            EndIf

            If $currentEvent[0] <> "RDrag" Or $currentEvent[0] <> "RMDrag" Or $currentEvent[0] <> "LRDrag" Then
                If $iRBUTTONDOWN = 1 Then
                    $currentEvent[0] = "RDrag"
                EndIf
            EndIf

            If $currentEvent[0] <> "MDrag" Then
                If $iMBUTTONDOWN = 1 Then
                    $currentEvent[0] = "MDrag"
                    $currentEvent[1] = $time
                EndIf
            EndIf

            If $iRBUTTONDOWN = 1 And $iMBUTTONDOWN = 1 And $currentEvent[0] <> "RMDrag" Then
                $RMDrag = 2
                $currentEvent[0] = "RMDrag"
                $currentEvent[1] = $time
            EndIf

            If $iLBUTTONDOWN = 1 And $iMBUTTONDOWN = 1 And $currentEvent[0] <> "LMDrag" Then
                $LMDrag = 2
                $currentEvent[0] = "LMDrag"
                $currentEvent[1] = $time
            EndIf


        Case $wParam = $WM_MOUSEWHEEL

            If _WinAPI_HiWord($mouseData) > 0 Then
                ;Wheel Up
                $currentEvent[0] = "WheelUp"
                $currentEvent[1] = $time
            Else
                ;Wheel Down
                $currentEvent[0] = "WheelDown"
                $currentEvent[1] = $time
            EndIf

        Case $wParam = $WM_LBUTTONDOWN
            $mouseX = MouseGetPos(0)
            $mouseY = MouseGetPos(1)

            For $i = 0 To UBound($tab) - 1
                If  $mouseX > $tab[$i][0] And $mouseX < $tab[$i][0] + $cadre_largeur And _
                    $mouseY > $tab[$i][1] And $mouseY < $tab[$i][1] + $cadre_hauteur Then

                    $decalageX = $mouseX - $tab[$i][0]
                    $decalageY = $mouseY - $tab[$i][1]

                    ; ... on peut déplacer
                    $deplacement_en_cours = True
                    $index_stack = $i
                EndIf
            Next


            ; Register Button Down, check for Right/Left
            If $currentEvent[0] = "RClick" Then
                $LRClickStatus = 1
            EndIf

            $iLBUTTONDOWN = 1

        Case $wParam = $WM_LBUTTONUP
            ;Update $iLBUTTONDOWN
            $iLBUTTONDOWN = 0

;~          If $deplacement_en_cours Then GUICtrlSetBkColor($tab_data_gui_fille[$index_gui_fille_en_deplacement][1], $vert) ; vert

            ;Test for Right/Left Click
            If $RLClickStatus = 1 And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "RLClick"
                $currentEvent[1] = $time
            EndIf
            If $currentEvent[0] = "LClick" And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "LDClick"
                $currentEvent[1] = $time
            EndIf

            ;Test for Drops
            If $currentEvent[0] = "LDrag" Then
                $currentEvent[0] = "LDrop"
                $currentEvent[1] = $time

                ; si un déplacement était en cours, on indique que c'est terminé puisqu'on vient de relacher le bouton de la souris
                If $deplacement_en_cours Then
                    $deplacement_en_cours = False
                EndIf

            EndIf

            If $LRDrag = 2 And $iRBUTTONDOWN = 1 Then
                $LRDrag = 1 ; Denote $LRDrag as still having one button clicked, need to register the drop on RButton up
            EndIf

            If $LRDrag = 1 And $iRBUTTONDOWN = 0 Then
                $currentEvent[0] = "LRDrop"
                $currentEvent[1] = $time
                $LRDrag = 0
            EndIf

            If $LMDrag = 2 And $iMBUTTONDOWN = 1 Then
                $LMDrag = 1 ; Denote $LMDrag as still having one button clicked, need to register the drop on MButton up
            EndIf

            If $LMDrag = 1 And $iMBUTTONDOWN = 0 Then
                $currentEvent[0] = "LMDrop"
                $currentEvent[1] = $time
                $LMDrag = 0
            EndIf

            ;Set LClick if other events haven't fired
            If $currentEvent[1] <> $time Then
                $currentEvent[0] = "LClick"
                $currentEvent[1] = $time
            EndIf

            ;Negate $LRClickStatus
            $RLClickStatus = 0


        Case $wParam = $WM_RBUTTONDOWN
            ;Register Button Down
            If $currentEvent[0] = "LClick" Then
                $RLClickStatus = 1
            EndIf
            $iRBUTTONDOWN = 1

        Case $wParam = $WM_RBUTTONUP
            ;Test for Left, Right, and Right Doubleclick here
            ;Update $iRBUTTONDOWN
            $iRBUTTONDOWN = 0
            ;Test for Right/Left Click
            If $LRClickStatus = 1 And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "LRClick"
                $currentEvent[1] = $time
            EndIf
            If $currentEvent[0] = "RClick" And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "RDClick"
                $currentEvent[1] = $time
            EndIf
            ;Test for Drops
            If $currentEvent[0] = "RDrag" Then
                $currentEvent[0] = "RDrop"
                $currentEvent[1] = $time
            EndIf

            If $LRDrag = 2 And $iLBUTTONDOWN = 1 Then
                $LRDrag = 1 ; Denote $LRDrag as still having one button clicked, need to register the drop on RButton up
            EndIf

            If $LRDrag = 1 And $iLBUTTONDOWN = 0 Then
                $currentEvent[0] = "LRDrop"
                $currentEvent[1] = $time
                $LRDrag = 0
            EndIf



            If $RMDrag = 2 And $iMBUTTONDOWN = 1 Then
                $RMDrag = 1 ; Denote $LMDrag as still having one button clicked, need to register the drop on MButton up
            EndIf

            If $RMDrag = 1 And $iMBUTTONDOWN = 0 Then
                $currentEvent[0] = "RMDrop"
                $currentEvent[1] = $time
                $RMDrag = 0
            EndIf

            ;Set LClick if other events haven't fired
            If $currentEvent[1] <> $time Then
                $currentEvent[0] = "RClick"
                $currentEvent[1] = $time
            EndIf

            ;Negate $LRClickStatus
            $LRClickStatus = 0


        Case $wParam = $WM_MBUTTONDOWN
            ;Register Button Down
            $iMBUTTONDOWN = 1

        Case $wParam = $WM_MBUTTONUP
            ;Test for Middle Double Click here
            ;Update $iRBUTTONDOWN
            $iMBUTTONDOWN = 0
            ;Test for Right/Left Click
            If $currentEvent[0] = "MClick" And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "MDClick"
                $currentEvent[1] = $time
            EndIf
            ;Test for Drops
            If $currentEvent[0] = "MDrag" Then
                $currentEvent[0] = "MDrop"
                $currentEvent[1] = $time
            EndIf

            If $LMDrag = 2 And $iLBUTTONDOWN = 1 Then
                $LMDrag = 1 ; Denote $LRDrag as still having one button clicked, need to register the drop on RButton up
            EndIf

            If $LMDrag = 1 And $iLBUTTONDOWN = 0 Then
                $currentEvent[0] = "LMDrop"
                $currentEvent[1] = $time
                $LMDrag = 0
            EndIf



            If $RMDrag = 2 And $iRBUTTONDOWN = 1 Then
                $RMDrag = 1 ; Denote $LMDrag as still having one button clicked, need to register the drop on MButton up
            EndIf

            If $RMDrag = 1 And $iRBUTTONDOWN = 0 Then
                $currentEvent[0] = "RMDrop"
                $currentEvent[1] = $time
                $RMDrag = 0
            EndIf

            ;Set MClick if other events haven't fired
            If $currentEvent[1] <> $time Then
                $currentEvent[0] = "MClick"
                $currentEvent[1] = $time
            EndIf

    EndSelect

;~  If $currentEvent[0] <> "" Then ConsoleWrite("event:"&$currentEvent[0] & @CRLF)

    $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _
            "int", $nCode, "ptr", $wParam, "ptr", $lParam)
    Return $ret[0]
EndFunc   ;==>_Mouse_Proc


Func WM_PAINT($hwnd, $iMsg, $wParam, $lParam)
    If $hwnd = $hGUI Then
        _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0)
        _WinAPI_RedrawWindow($hwnd, 0, 0, $RDW_VALIDATE)
    EndIf

    Return 'GUI_RUNDEFMSG'
EndFunc   ;==>WM_PAINT

Func WM_SIZE($hwnd, $iMsg, $wParam, $lParam)
    If $hwnd = $hGUI Then
        $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    EndIf

    Return 'GUI_RUNDEFMSG'
EndFunc


Func _Exit()
    DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hM_Hook[0])
    $hM_Hook[0] = 0
    DllCallbackFree($hKey_Proc)
    $hKey_Proc = 0

    ; Clean up
    _GDIPlus_BrushDispose($hPen)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_BitmapDispose ($hBitmap)
    _GDIPlus_GraphicsDispose($hGraphics)

    ; Uninitialize GDI+
    _GDIPlus_Shutdown()

    DllClose($hDLL)
    Exit
EndFunc

It won't resize as you drag but will on mouse button up.

Link to comment
Share on other sites

Sorry, they should only be declared once outside the while/wend loop. Any additional graphics objects should be disposed of after drawing to the backbuffer (The pen in this case). I think this is everything, there doesn't seem to be any memory problems, although I only ran it for a minute or so. 

This is fixed here.

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPISysWin.au3>
#include <WinAPIGdi.au3>
#include <WinAPI.au3>



Local $hDLL = DllOpen("user32.dll")
AutoItSetOption("MouseCoordMode", 2)

;Register callback
$hKey_Proc = DllCallbackRegister("_Mouse_Proc", "int", "int;ptr;ptr")
$hM_Module = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
$hM_Hook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", $WH_MOUSE_LL, "ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hM_Module[0], "dword", 0)

Global Const $MSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo"

Global $currentEvent[2]
Global $iLBUTTONDOWN = 0
Global $iRBUTTONDOWN = 0
Global $iMBUTTONDOWN = 0
Global $LRClickStatus = 0
Global $RLClickStatus = 0
Global $LRDrag = 0
Global $RLDrag = 0
Global $LMDrag = 0
Global $RMDrag = 0
Global $doubleClickTime = 400
Global $tPoint


Local $hGUI, $hGraphics, $hBackbuffer, $hBitmap
Local Const $width = Int(@DesktopWidth * 0.5), $height = Int(@DesktopHeight * 0.5)

Global $max_width = 1900
Global $max_height = 1000


; Initialize GDI+
_GDIPlus_Startup()

Local $GUI_title = "GDI+"
$hGUI = GUICreate($GUI_title, $width, $height, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_THICKFRAME,$WS_TABSTOP))
GUISetState()


Dim $tab[1][2]
Global  $cadre_x = 100
Global  $cadre_y = 100

$tab[0][0] = $cadre_x
$tab[0][1] = $cadre_y

Global $decalageX, $decalageY
Global $deplacement_en_cours = False
Global $index_stack


GUIRegisterMsg($WM_PAINT, "WM_PAINT")
GUIRegisterMsg($WM_SIZE, "WM_SIZE")

Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
       $hBitmap = _GDIPlus_BitmapCreateFromGraphics($max_width, $max_height, $hGraphics)
       $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

While 1
    $msg = GUIGetMsg()

    Local $aWindowsSize = WinGetClientSize($hGUI)

    _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFFF0F0F0)


    $hPen = _GDIPlus_PenCreate(0xFF000000, 2)

    $cadre_largeur = $aWindowsSize[0] - 200
    $cadre_hauteur = $aWindowsSize[1] - 200

    _GDIPlus_GraphicsDrawRect($hBackbuffer, $cadre_x, $cadre_y, $cadre_largeur, $cadre_hauteur, $hPen) ; cadre
    _GDIPlus_GraphicsDrawRect($hBackbuffer, $cadre_x, $cadre_y + 15, $cadre_largeur, 15, $hPen) ; titre
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $max_width, $max_height)

    Switch $msg

        Case $GUI_EVENT_CLOSE
            _Exit()

        Case $GUI_EVENT_MAXIMIZE
            $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    EndSwitch

    _GDIPlus_PenDispose($hPen)
WEnd


Func _Mouse_Proc($nCode, $wParam, $lParam)
    Local $info, $mouseData, $time, $timeDiff

    If $nCode < 0 Then
        $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _
                "int", $nCode, "ptr", $wParam, "ptr", $lParam)
        Return $ret[0]
    EndIf

    $info = DllStructCreate($MSLLHOOKSTRUCT, $lParam)
    $mouseData = DllStructGetData($info, 3)
    $time = DllStructGetData($info, 5)
    $timeDiff = $time - $currentEvent[1]

    Select
        Case $wParam = $WM_MOUSEMOVE
            ;Test for Drag in here

            If $currentEvent[0] <> "LDrag" Or $currentEvent[0] <> "LRDrag" Or $currentEvent[0] <> "LMDrag" Then
                If $iLBUTTONDOWN = 1 Then
;~                  If $currentEvent[0] <> "LDrag" Then GUICtrlSetBkColor($tab_data_gui_fille[$index_gui_fille_en_deplacement][1], $violet) ; violet
                    $currentEvent[0] = "LDrag"

                    If $deplacement_en_cours Then
                        $mouseX = MouseGetPos(0)
                        $mouseY = MouseGetPos(1)

                        _GDIPlus_GraphicsClear($hBackbuffer, 0xFFF0F0F0)
                        _GDIPlus_GraphicsDrawRect($hBackbuffer, $mouseX - $decalageX, $mouseY - $decalageY, $cadre_largeur, $cadre_hauteur, $hPen) ; cadre
                        _GDIPlus_GraphicsDrawRect($hBackbuffer, $mouseX - $decalageX, $mouseY - $decalageY + 15, $cadre_largeur, 15, $hPen) ; titre
                        _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $max_width, $max_height)

                        $tab[$index_stack][0] = $mouseX - $decalageX
                        $tab[$index_stack][1] = $mouseY - $decalageY

                    EndIf

                    If $iRBUTTONDOWN = 1 Then
                        $currentEvent[0] = "LRDrag"
                        $LRDrag = 2
                    EndIf
                EndIf
            EndIf

            If $currentEvent[0] <> "RDrag" Or $currentEvent[0] <> "RMDrag" Or $currentEvent[0] <> "LRDrag" Then
                If $iRBUTTONDOWN = 1 Then
                    $currentEvent[0] = "RDrag"
                EndIf
            EndIf

            If $currentEvent[0] <> "MDrag" Then
                If $iMBUTTONDOWN = 1 Then
                    $currentEvent[0] = "MDrag"
                    $currentEvent[1] = $time
                EndIf
            EndIf

            If $iRBUTTONDOWN = 1 And $iMBUTTONDOWN = 1 And $currentEvent[0] <> "RMDrag" Then
                $RMDrag = 2
                $currentEvent[0] = "RMDrag"
                $currentEvent[1] = $time
            EndIf

            If $iLBUTTONDOWN = 1 And $iMBUTTONDOWN = 1 And $currentEvent[0] <> "LMDrag" Then
                $LMDrag = 2
                $currentEvent[0] = "LMDrag"
                $currentEvent[1] = $time
            EndIf


        Case $wParam = $WM_MOUSEWHEEL

            If _WinAPI_HiWord($mouseData) > 0 Then
                ;Wheel Up
                $currentEvent[0] = "WheelUp"
                $currentEvent[1] = $time
            Else
                ;Wheel Down
                $currentEvent[0] = "WheelDown"
                $currentEvent[1] = $time
            EndIf

        Case $wParam = $WM_LBUTTONDOWN
            $mouseX = MouseGetPos(0)
            $mouseY = MouseGetPos(1)

            For $i = 0 To UBound($tab) - 1
                If  $mouseX > $tab[$i][0] And $mouseX < $tab[$i][0] + $cadre_largeur And _
                    $mouseY > $tab[$i][1] And $mouseY < $tab[$i][1] + $cadre_hauteur Then

                    $decalageX = $mouseX - $tab[$i][0]
                    $decalageY = $mouseY - $tab[$i][1]

                    ; ... on peut déplacer
                    $deplacement_en_cours = True
                    $index_stack = $i
                EndIf
            Next


            ; Register Button Down, check for Right/Left
            If $currentEvent[0] = "RClick" Then
                $LRClickStatus = 1
            EndIf

            $iLBUTTONDOWN = 1

        Case $wParam = $WM_LBUTTONUP
            ;Update $iLBUTTONDOWN
            $iLBUTTONDOWN = 0

;~          If $deplacement_en_cours Then GUICtrlSetBkColor($tab_data_gui_fille[$index_gui_fille_en_deplacement][1], $vert) ; vert

            ;Test for Right/Left Click
            If $RLClickStatus = 1 And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "RLClick"
                $currentEvent[1] = $time
            EndIf
            If $currentEvent[0] = "LClick" And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "LDClick"
                $currentEvent[1] = $time
            EndIf

            ;Test for Drops
            If $currentEvent[0] = "LDrag" Then
                $currentEvent[0] = "LDrop"
                $currentEvent[1] = $time

                ; si un déplacement était en cours, on indique que c'est terminé puisqu'on vient de relacher le bouton de la souris
                If $deplacement_en_cours Then
                    $deplacement_en_cours = False
                EndIf

            EndIf

            If $LRDrag = 2 And $iRBUTTONDOWN = 1 Then
                $LRDrag = 1 ; Denote $LRDrag as still having one button clicked, need to register the drop on RButton up
            EndIf

            If $LRDrag = 1 And $iRBUTTONDOWN = 0 Then
                $currentEvent[0] = "LRDrop"
                $currentEvent[1] = $time
                $LRDrag = 0
            EndIf

            If $LMDrag = 2 And $iMBUTTONDOWN = 1 Then
                $LMDrag = 1 ; Denote $LMDrag as still having one button clicked, need to register the drop on MButton up
            EndIf

            If $LMDrag = 1 And $iMBUTTONDOWN = 0 Then
                $currentEvent[0] = "LMDrop"
                $currentEvent[1] = $time
                $LMDrag = 0
            EndIf

            ;Set LClick if other events haven't fired
            If $currentEvent[1] <> $time Then
                $currentEvent[0] = "LClick"
                $currentEvent[1] = $time
            EndIf

            ;Negate $LRClickStatus
            $RLClickStatus = 0


        Case $wParam = $WM_RBUTTONDOWN
            ;Register Button Down
            If $currentEvent[0] = "LClick" Then
                $RLClickStatus = 1
            EndIf
            $iRBUTTONDOWN = 1

        Case $wParam = $WM_RBUTTONUP
            ;Test for Left, Right, and Right Doubleclick here
            ;Update $iRBUTTONDOWN
            $iRBUTTONDOWN = 0
            ;Test for Right/Left Click
            If $LRClickStatus = 1 And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "LRClick"
                $currentEvent[1] = $time
            EndIf
            If $currentEvent[0] = "RClick" And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "RDClick"
                $currentEvent[1] = $time
            EndIf
            ;Test for Drops
            If $currentEvent[0] = "RDrag" Then
                $currentEvent[0] = "RDrop"
                $currentEvent[1] = $time
            EndIf

            If $LRDrag = 2 And $iLBUTTONDOWN = 1 Then
                $LRDrag = 1 ; Denote $LRDrag as still having one button clicked, need to register the drop on RButton up
            EndIf

            If $LRDrag = 1 And $iLBUTTONDOWN = 0 Then
                $currentEvent[0] = "LRDrop"
                $currentEvent[1] = $time
                $LRDrag = 0
            EndIf



            If $RMDrag = 2 And $iMBUTTONDOWN = 1 Then
                $RMDrag = 1 ; Denote $LMDrag as still having one button clicked, need to register the drop on MButton up
            EndIf

            If $RMDrag = 1 And $iMBUTTONDOWN = 0 Then
                $currentEvent[0] = "RMDrop"
                $currentEvent[1] = $time
                $RMDrag = 0
            EndIf

            ;Set LClick if other events haven't fired
            If $currentEvent[1] <> $time Then
                $currentEvent[0] = "RClick"
                $currentEvent[1] = $time
            EndIf

            ;Negate $LRClickStatus
            $LRClickStatus = 0


        Case $wParam = $WM_MBUTTONDOWN
            ;Register Button Down
            $iMBUTTONDOWN = 1

        Case $wParam = $WM_MBUTTONUP
            ;Test for Middle Double Click here
            ;Update $iRBUTTONDOWN
            $iMBUTTONDOWN = 0
            ;Test for Right/Left Click
            If $currentEvent[0] = "MClick" And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "MDClick"
                $currentEvent[1] = $time
            EndIf
            ;Test for Drops
            If $currentEvent[0] = "MDrag" Then
                $currentEvent[0] = "MDrop"
                $currentEvent[1] = $time
            EndIf

            If $LMDrag = 2 And $iLBUTTONDOWN = 1 Then
                $LMDrag = 1 ; Denote $LRDrag as still having one button clicked, need to register the drop on RButton up
            EndIf

            If $LMDrag = 1 And $iLBUTTONDOWN = 0 Then
                $currentEvent[0] = "LMDrop"
                $currentEvent[1] = $time
                $LMDrag = 0
            EndIf



            If $RMDrag = 2 And $iRBUTTONDOWN = 1 Then
                $RMDrag = 1 ; Denote $LMDrag as still having one button clicked, need to register the drop on MButton up
            EndIf

            If $RMDrag = 1 And $iRBUTTONDOWN = 0 Then
                $currentEvent[0] = "RMDrop"
                $currentEvent[1] = $time
                $RMDrag = 0
            EndIf

            ;Set MClick if other events haven't fired
            If $currentEvent[1] <> $time Then
                $currentEvent[0] = "MClick"
                $currentEvent[1] = $time
            EndIf

    EndSelect

;~  If $currentEvent[0] <> "" Then ConsoleWrite("event:"&$currentEvent[0] & @CRLF)

    $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _
            "int", $nCode, "ptr", $wParam, "ptr", $lParam)
    Return $ret[0]
EndFunc   ;==>_Mouse_Proc


Func WM_PAINT($hwnd, $iMsg, $wParam, $lParam)
    If $hwnd = $hGUI Then
        _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0)
        _WinAPI_RedrawWindow($hwnd, 0, 0, $RDW_VALIDATE)
    EndIf

    Return 'GUI_RUNDEFMSG'
EndFunc   ;==>WM_PAINT

Func WM_SIZE($hwnd, $iMsg, $wParam, $lParam)
    If $hwnd = $hGUI Then
        $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    EndIf

    Return 'GUI_RUNDEFMSG'
EndFunc


Func _Exit()
    DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hM_Hook[0])
    $hM_Hook[0] = 0
    DllCallbackFree($hKey_Proc)
    $hKey_Proc = 0

    ; Clean up
    _GDIPlus_BrushDispose($hPen)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_BitmapDispose ($hBitmap)
    _GDIPlus_GraphicsDispose($hGraphics)

    ; Uninitialize GDI+
    _GDIPlus_Shutdown()

    DllClose($hDLL)
    Exit
EndFunc

 

Link to comment
Share on other sites

For the curious, here is a script drawing 2 GDI frames with some text inside that you can drag individually.

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPISysWin.au3>
#include <WinAPIGdi.au3>
#include <WinAPI.au3>



Local $hDLL = DllOpen("user32.dll")
AutoItSetOption("MouseCoordMode", 2)

;Register callback
$hKey_Proc = DllCallbackRegister("_Mouse_Proc", "int", "int;ptr;ptr")
$hM_Module = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
$hM_Hook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", $WH_MOUSE_LL, "ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hM_Module[0], "dword", 0)

Global Const $MSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo"

Global $currentEvent[2]
Global $iLBUTTONDOWN = 0
Global $iRBUTTONDOWN = 0
Global $iMBUTTONDOWN = 0
Global $LRClickStatus = 0
Global $RLClickStatus = 0
Global $LRDrag = 0
Global $RLDrag = 0
Global $LMDrag = 0
Global $RMDrag = 0
Global $doubleClickTime = 400
Global $tPoint


Local $hGUI, $hGraphics, $hBackbuffer, $hBitmap
Local Const $width = Int(@DesktopWidth * 0.5), $height = Int(@DesktopHeight * 0.5)

Global $max_width = 1900
Global $max_height = 1000


; Initialize GDI+
_GDIPlus_Startup()

Local $GUI_title = "GDI+"
$hGUI = GUICreate($GUI_title, $width, $height, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_THICKFRAME,$WS_TABSTOP))
GUISetState()


Dim $tab[2][3]

; Création de la zone principale d'affichage
Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($max_width, $max_height, $hGraphics)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
_GDIPlus_GraphicsClear($hBackbuffer, 0xFFF0F0F0)

; Formatage du texte
$hBrush = _GDIPlus_BrushCreateSolid(0xFF000000)
$hFormat = _GDIPlus_StringFormatCreate()
_GDIPlus_StringFormatSetAlign($hFormat, 1)
$hFamily = _GDIPlus_FontFamilyCreate("Arial")
$hFont = _GDIPlus_FontCreate($hFamily, 10, 2)

$hPen = _GDIPlus_PenCreate(0xFF000000, 2)


Global $cadre_largeur = 200
Global $cadre_hauteur = 200


; Premier stack
$cadre_x = 100
$cadre_y = 100

$tLayout = _GDIPlus_RectFCreate($cadre_x, $cadre_y, $cadre_largeur, 15)
_GDIPlus_GraphicsDrawStringEx($hBackbuffer, "Hello world A", $hFont, $tLayout, $hFormat, $hBrush)

$tLayout2 = _GDIPlus_RectFCreate($cadre_x, $cadre_y + 15, $cadre_largeur, 15)
_GDIPlus_GraphicsDrawStringEx($hBackbuffer, "Bye world A", $hFont, $tLayout2, $hFormat, $hBrush)

_GDIPlus_GraphicsDrawRect($hBackbuffer, $cadre_x, $cadre_y, $cadre_largeur, $cadre_hauteur, $hPen) ; cadre
_GDIPlus_GraphicsDrawRect($hBackbuffer, $cadre_x, $cadre_y + 15, $cadre_largeur, 15, $hPen) ; titre

$tab[0][0] = $cadre_x
$tab[0][1] = $cadre_y
$tab[0][2] = "A"


; Second stack
$cadre_x = 400
$cadre_y = 300

$tLayout = _GDIPlus_RectFCreate($cadre_x, $cadre_y, $cadre_largeur, 15)
_GDIPlus_GraphicsDrawStringEx($hBackbuffer, "Hello world B", $hFont, $tLayout, $hFormat, $hBrush)

$tLayout2 = _GDIPlus_RectFCreate($cadre_x, $cadre_y + 15, $cadre_largeur, 15)
_GDIPlus_GraphicsDrawStringEx($hBackbuffer, "Bye world B", $hFont, $tLayout2, $hFormat, $hBrush)

_GDIPlus_GraphicsDrawRect($hBackbuffer, $cadre_x, $cadre_y, $cadre_largeur, $cadre_hauteur, $hPen) ; cadre
_GDIPlus_GraphicsDrawRect($hBackbuffer, $cadre_x, $cadre_y + 15, $cadre_largeur, 15, $hPen) ; titre

_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $max_width, $max_height) ; copy from backbuffer to visible graphic

$tab[1][0] = $cadre_x
$tab[1][1] = $cadre_y
$tab[1][2] = "B"


Global $decalageX, $decalageY
Global $deplacement_en_cours = False
Global $index_stack


GUIRegisterMsg($WM_PAINT, "WM_PAINT")
GUIRegisterMsg($WM_SIZE, "WM_SIZE")

While 1
    $msg = GUIGetMsg()

    Switch $msg

        Case $GUI_EVENT_CLOSE
            _Exit()

        Case $GUI_EVENT_MAXIMIZE
            $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    EndSwitch

WEnd


Func _Mouse_Proc($nCode, $wParam, $lParam)
    Local $info, $mouseData, $time, $timeDiff

    If $nCode < 0 Then
        $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _
                "int", $nCode, "ptr", $wParam, "ptr", $lParam)
        Return $ret[0]
    EndIf

    $info = DllStructCreate($MSLLHOOKSTRUCT, $lParam)
    $mouseData = DllStructGetData($info, 3)
    $time = DllStructGetData($info, 5)
    $timeDiff = $time - $currentEvent[1]

    Select
        Case $wParam = $WM_MOUSEMOVE
            ;Test for Drag in here

            If $currentEvent[0] <> "LDrag" Or $currentEvent[0] <> "LRDrag" Or $currentEvent[0] <> "LMDrag" Then

                If $iLBUTTONDOWN = 1 Then
                    $currentEvent[0] = "LDrag"

                    If $deplacement_en_cours Then
                        $mouseX = MouseGetPos(0)
                        $mouseY = MouseGetPos(1)

                        _GDIPlus_GraphicsClear($hBackbuffer, 0xFFF0F0F0)

                        For $i = 0 To UBound($tab) - 1
                            ; on déplace seulement celui dont l'index correspond dans le tableau
                            If $i = $index_stack Then
                                $tLayout = _GDIPlus_RectFCreate($mouseX - $decalageX, $mouseY - $decalageY, $cadre_largeur, 15)
                                _GDIPlus_GraphicsDrawStringEx($hBackbuffer, "Hello world " & $tab[$i][2], $hFont, $tLayout, $hFormat, $hBrush)

                                $tLayout2 = _GDIPlus_RectFCreate($mouseX - $decalageX, $mouseY - $decalageY + 15, $cadre_largeur, 15)
                                _GDIPlus_GraphicsDrawStringEx($hBackbuffer, "Bye world " & $tab[$i][2], $hFont, $tLayout2, $hFormat, $hBrush)

                                _GDIPlus_GraphicsDrawRect($hBackbuffer, $mouseX - $decalageX, $mouseY - $decalageY, $cadre_largeur, $cadre_hauteur, $hPen) ; cadre
                                _GDIPlus_GraphicsDrawRect($hBackbuffer, $mouseX - $decalageX, $mouseY - $decalageY + 15, $cadre_largeur, 15, $hPen) ; titre

                                $tab[$index_stack][0] = $mouseX - $decalageX
                                $tab[$index_stack][1] = $mouseY - $decalageY

                            Else ; les autres sont simplement redessinés au même endroit
                                $tLayout = _GDIPlus_RectFCreate($tab[$i][0], $tab[$i][1], $cadre_largeur, 15)
                                _GDIPlus_GraphicsDrawStringEx($hBackbuffer, "Hello world " & $tab[$i][2], $hFont, $tLayout, $hFormat, $hBrush)

                                $tLayout2 = _GDIPlus_RectFCreate($tab[$i][0], $tab[$i][1] + 15, $cadre_largeur, 15)
                                _GDIPlus_GraphicsDrawStringEx($hBackbuffer, "Bye world " & $tab[$i][2], $hFont, $tLayout2, $hFormat, $hBrush)

                                _GDIPlus_GraphicsDrawRect($hBackbuffer, $tab[$i][0], $tab[$i][1], $cadre_largeur, $cadre_hauteur, $hPen) ; cadre
                                _GDIPlus_GraphicsDrawRect($hBackbuffer, $tab[$i][0], $tab[$i][1] + 15, $cadre_largeur, 15, $hPen) ; titre
                            EndIf
                        Next
                        _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $max_width, $max_height)
                    EndIf

                    If $iRBUTTONDOWN = 1 Then
                        $currentEvent[0] = "LRDrag"
                        $LRDrag = 2
                    EndIf
                EndIf
            EndIf

            If $currentEvent[0] <> "RDrag" Or $currentEvent[0] <> "RMDrag" Or $currentEvent[0] <> "LRDrag" Then
                If $iRBUTTONDOWN = 1 Then
                    $currentEvent[0] = "RDrag"
                EndIf
            EndIf

            If $currentEvent[0] <> "MDrag" Then
                If $iMBUTTONDOWN = 1 Then
                    $currentEvent[0] = "MDrag"
                    $currentEvent[1] = $time
                EndIf
            EndIf

            If $iRBUTTONDOWN = 1 And $iMBUTTONDOWN = 1 And $currentEvent[0] <> "RMDrag" Then
                $RMDrag = 2
                $currentEvent[0] = "RMDrag"
                $currentEvent[1] = $time
            EndIf

            If $iLBUTTONDOWN = 1 And $iMBUTTONDOWN = 1 And $currentEvent[0] <> "LMDrag" Then
                $LMDrag = 2
                $currentEvent[0] = "LMDrag"
                $currentEvent[1] = $time
            EndIf


        Case $wParam = $WM_MOUSEWHEEL

            If _WinAPI_HiWord($mouseData) > 0 Then
                ;Wheel Up
                $currentEvent[0] = "WheelUp"
                $currentEvent[1] = $time
            Else
                ;Wheel Down
                $currentEvent[0] = "WheelDown"
                $currentEvent[1] = $time
            EndIf

        Case $wParam = $WM_LBUTTONDOWN
            $mouseX = MouseGetPos(0)
            $mouseY = MouseGetPos(1)

            For $i = 0 To UBound($tab) - 1
                If  $mouseX > $tab[$i][0] And $mouseX < $tab[$i][0] + $cadre_largeur And _
                    $mouseY > $tab[$i][1] And $mouseY < $tab[$i][1] + $cadre_hauteur Then

                    $decalageX = $mouseX - $tab[$i][0]
                    $decalageY = $mouseY - $tab[$i][1]

                    ; ... on peut déplacer
                    $deplacement_en_cours = True
                    $index_stack = $i
                EndIf
            Next


            ; Register Button Down, check for Right/Left
            If $currentEvent[0] = "RClick" Then
                $LRClickStatus = 1
            EndIf

            $iLBUTTONDOWN = 1

        Case $wParam = $WM_LBUTTONUP
            ;Update $iLBUTTONDOWN
            $iLBUTTONDOWN = 0

            ;Test for Right/Left Click
            If $RLClickStatus = 1 And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "RLClick"
                $currentEvent[1] = $time
            EndIf
            If $currentEvent[0] = "LClick" And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "LDClick"
                $currentEvent[1] = $time
            EndIf

            ;Test for Drops
            If $currentEvent[0] = "LDrag" Then
                $currentEvent[0] = "LDrop"
                $currentEvent[1] = $time

                ; si un déplacement était en cours, on indique que c'est terminé puisqu'on vient de relacher le bouton de la souris
                If $deplacement_en_cours Then
                    $deplacement_en_cours = False
                EndIf

            EndIf

            If $LRDrag = 2 And $iRBUTTONDOWN = 1 Then
                $LRDrag = 1 ; Denote $LRDrag as still having one button clicked, need to register the drop on RButton up
            EndIf

            If $LRDrag = 1 And $iRBUTTONDOWN = 0 Then
                $currentEvent[0] = "LRDrop"
                $currentEvent[1] = $time
                $LRDrag = 0
            EndIf

            If $LMDrag = 2 And $iMBUTTONDOWN = 1 Then
                $LMDrag = 1 ; Denote $LMDrag as still having one button clicked, need to register the drop on MButton up
            EndIf

            If $LMDrag = 1 And $iMBUTTONDOWN = 0 Then
                $currentEvent[0] = "LMDrop"
                $currentEvent[1] = $time
                $LMDrag = 0
            EndIf

            ;Set LClick if other events haven't fired
            If $currentEvent[1] <> $time Then
                $currentEvent[0] = "LClick"
                $currentEvent[1] = $time
            EndIf

            ;Negate $LRClickStatus
            $RLClickStatus = 0


        Case $wParam = $WM_RBUTTONDOWN
            ;Register Button Down
            If $currentEvent[0] = "LClick" Then
                $RLClickStatus = 1
            EndIf
            $iRBUTTONDOWN = 1

        Case $wParam = $WM_RBUTTONUP
            ;Test for Left, Right, and Right Doubleclick here
            ;Update $iRBUTTONDOWN
            $iRBUTTONDOWN = 0
            ;Test for Right/Left Click
            If $LRClickStatus = 1 And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "LRClick"
                $currentEvent[1] = $time
            EndIf
            If $currentEvent[0] = "RClick" And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "RDClick"
                $currentEvent[1] = $time
            EndIf
            ;Test for Drops
            If $currentEvent[0] = "RDrag" Then
                $currentEvent[0] = "RDrop"
                $currentEvent[1] = $time
            EndIf

            If $LRDrag = 2 And $iLBUTTONDOWN = 1 Then
                $LRDrag = 1 ; Denote $LRDrag as still having one button clicked, need to register the drop on RButton up
            EndIf

            If $LRDrag = 1 And $iLBUTTONDOWN = 0 Then
                $currentEvent[0] = "LRDrop"
                $currentEvent[1] = $time
                $LRDrag = 0
            EndIf



            If $RMDrag = 2 And $iMBUTTONDOWN = 1 Then
                $RMDrag = 1 ; Denote $LMDrag as still having one button clicked, need to register the drop on MButton up
            EndIf

            If $RMDrag = 1 And $iMBUTTONDOWN = 0 Then
                $currentEvent[0] = "RMDrop"
                $currentEvent[1] = $time
                $RMDrag = 0
            EndIf

            ;Set LClick if other events haven't fired
            If $currentEvent[1] <> $time Then
                $currentEvent[0] = "RClick"
                $currentEvent[1] = $time
            EndIf

            ;Negate $LRClickStatus
            $LRClickStatus = 0


        Case $wParam = $WM_MBUTTONDOWN
            ;Register Button Down
            $iMBUTTONDOWN = 1

        Case $wParam = $WM_MBUTTONUP
            ;Test for Middle Double Click here
            ;Update $iRBUTTONDOWN
            $iMBUTTONDOWN = 0
            ;Test for Right/Left Click
            If $currentEvent[0] = "MClick" And ($timeDiff) < $doubleClickTime Then
                $currentEvent[0] = "MDClick"
                $currentEvent[1] = $time
            EndIf
            ;Test for Drops
            If $currentEvent[0] = "MDrag" Then
                $currentEvent[0] = "MDrop"
                $currentEvent[1] = $time
            EndIf

            If $LMDrag = 2 And $iLBUTTONDOWN = 1 Then
                $LMDrag = 1 ; Denote $LRDrag as still having one button clicked, need to register the drop on RButton up
            EndIf

            If $LMDrag = 1 And $iLBUTTONDOWN = 0 Then
                $currentEvent[0] = "LMDrop"
                $currentEvent[1] = $time
                $LMDrag = 0
            EndIf



            If $RMDrag = 2 And $iRBUTTONDOWN = 1 Then
                $RMDrag = 1 ; Denote $LMDrag as still having one button clicked, need to register the drop on MButton up
            EndIf

            If $RMDrag = 1 And $iRBUTTONDOWN = 0 Then
                $currentEvent[0] = "RMDrop"
                $currentEvent[1] = $time
                $RMDrag = 0
            EndIf

            ;Set MClick if other events haven't fired
            If $currentEvent[1] <> $time Then
                $currentEvent[0] = "MClick"
                $currentEvent[1] = $time
            EndIf

    EndSelect

;~  If $currentEvent[0] <> "" Then ConsoleWrite("event:"&$currentEvent[0] & @CRLF)

    $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _
            "int", $nCode, "ptr", $wParam, "ptr", $lParam)
    Return $ret[0]
EndFunc   ;==>_Mouse_Proc


Func WM_PAINT($hwnd, $iMsg, $wParam, $lParam)
    If $hwnd = $hGUI Then
        _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0)
        _WinAPI_RedrawWindow($hwnd, 0, 0, $RDW_VALIDATE)
    EndIf

    Return 'GUI_RUNDEFMSG'
EndFunc   ;==>WM_PAINT

Func WM_SIZE($hwnd, $iMsg, $wParam, $lParam)
    If $hwnd = $hGUI Then
        $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    EndIf

    Return 'GUI_RUNDEFMSG'
EndFunc


Func _Exit()
    DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hM_Hook[0])
    $hM_Hook[0] = 0
    DllCallbackFree($hKey_Proc)
    $hKey_Proc = 0

    ; Clean up
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_BitmapDispose ($hBitmap)
    _GDIPlus_GraphicsDispose($hGraphics)

    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)

    ; Uninitialize GDI+
    _GDIPlus_Shutdown()

    DllClose($hDLL)
    Exit
EndFunc

 

Edited by tatane
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...