Jump to content

Recommended Posts

Posted (edited)

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
Posted

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.

Posted

I just would like to know if the way I (re)declare my $hGraphics when the Gui is resized is ok or if I should Dispose it before recreating.

Posted

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

 

Posted (edited)

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
Posted

I noticed the movement of the frame is slower when the gui is maximized.

The graphics object is bigger, is it the source of the slowdown ?

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...