tatane Posted June 3, 2019 Posted June 3, 2019 (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. expandcollapse popup#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 June 3, 2019 by tatane
Sidley Posted June 4, 2019 Posted June 4, 2019 Like this? expandcollapse popup#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.
tatane Posted June 4, 2019 Author Posted June 4, 2019 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.
Sidley Posted June 4, 2019 Posted June 4, 2019 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. expandcollapse popup#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
tatane Posted June 4, 2019 Author Posted June 4, 2019 Indeed, it seems there is no memory leak when resizing the Gui. I will try this way. Thanks.
tatane Posted June 4, 2019 Author Posted June 4, 2019 (edited) For the curious, here is a script drawing 2 GDI frames with some text inside that you can drag individually. expandcollapse popup#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 June 5, 2019 by tatane Sidley 1
tatane Posted June 5, 2019 Author Posted June 5, 2019 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 ?
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now