
tatane
Active Members-
Posts
117 -
Joined
-
Last visited
Everything posted by tatane
-
Need help for GDIPlus code optimization
tatane replied to tatane's topic in AutoIt General Help and Support
Ok I finally found a trick to do what I need. Instead of redraw everything each cycle, I created a transparent gui on top of the main gui. And I drawn the frame I'm dragging on it. This cloned gui is destroy when the drag is finished. Took me some time to understand the basic mecanics of gdiplus... Here is the code (not perfect) : #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> #include <WinAPIGdi.au3> #include <WinAPI.au3> 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 Const $width = Int(@DesktopWidth * 0.8), $height = Int(@DesktopHeight * 0.8) Global $max_width = 1900 Global $max_height = 1000 ; Initialize GDI+ _GDIPlus_Startup() Global $gui_clone = -1 Global $hGraphics_clone, $hBitmap_clone, $hBackbuffer_clone, $hHBitmap_clone, $hBrush_clone ; pour la gui clone Global $hGUI = GUICreate("", $width, $height, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_THICKFRAME,$WS_TABSTOP)) $aggrandissement = GUICtrlCreateButton("+", 10, 10, 20) $diminution = GUICtrlCreateButton("-", 40, 10, 20) GUISetState() ; main graphic and buffer Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($max_width, $max_height, $hGraphics) Global $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 1) _GDIPlus_GraphicsSetInterpolationMode($hBackbuffer, 1) _GDIPlus_GraphicsSetCompositingQuality($hBackbuffer, 1) _GDIPlus_GraphicsSetPixelOffsetMode($hBackbuffer, 1) Global $hBitmap_switch = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\OS6250-24M.jpg") Global $iHeight_switch = _GDIPlus_ImageGetHeight($hBitmap_switch) ; exclude controls from GDI+ graphic region Local $hRegion = _GDIPlus_RegionCreateFromRect(0, 0, $width, $height) $aRect = ControlGetPos("", "", $aggrandissement) _GDIPlus_RegionCombineRect($hRegion, $aRect[0], $aRect[1], $aRect[2], $aRect[3], 3) $aRect = ControlGetPos("", "", $diminution) _GDIPlus_RegionCombineRect($hRegion, $aRect[0], $aRect[1], $aRect[2], $aRect[3], 3) _GDIPlus_GraphicsSetClipRegion($hGraphics, $hRegion) _GDIPlus_RegionDispose($hRegion) ; Text format Global $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000) Global $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) Global $hFamily = _GDIPlus_FontFamilyCreate("Arial") Global $hFont = _GDIPlus_FontCreate($hFamily, 10, 2) ; for the frames drawing Global $hPen = _GDIPlus_PenCreate(0xFF000000, 2) Global $hBrush_cadre_titre = _GDIPlus_BrushCreateSolid(0x55FF0000) Global $frame_width = 200 Global $frame_height = 200 Global $shift_X, $shift_Y Global $move_inprogress = False Global $index_stack Global $iScale = 1 ; creating array Global $array[51][4] $array[0][0] = 50 Local $startx = 50 Local $starty = 50 Local $guipos = WinGetPos($hGUI) Local $intervalle_x = $guipos[2] / 10 ; width Local $intervalle_y = $guipos[3] / 7 ; height For $i = 1 To $array[0][0] ; auto positionning If Mod($i, 10) = 0 Then $x = $startx $y = $array[$i - 1][1] + $intervalle_y Else If $i - 1 = 0 Then ; first pass $x = $startx $y = $starty Else $x = $array[$i - 1][0] + $intervalle_x $y = $array[$i - 1][1] EndIf EndIf $array[$i][0] = $x $array[$i][1] = $y $array[$i][2] = "Hello world " & $i $array[$i][3] = "Bye world " & $i Next Global $fps = 0, $fps_maintimer, $fps_timer, $fps_diff $fps_maintimer = TimerInit() _DrawStack() 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) $winpos = WinGetPos($hGUI) ; exclude controls from GDI+ graphic region Local $hRegion = _GDIPlus_RegionCreateFromRect(0, 0, $winpos[2], $winpos[3]) $aRect = ControlGetPos("", "", $aggrandissement) _GDIPlus_RegionCombineRect($hRegion, $aRect[0], $aRect[1], $aRect[2], $aRect[3], 3) $aRect = ControlGetPos("", "", $diminution) _GDIPlus_RegionCombineRect($hRegion, $aRect[0], $aRect[1], $aRect[2], $aRect[3], 3) _GDIPlus_GraphicsSetClipRegion($hGraphics, $hRegion) _GDIPlus_RegionDispose($hRegion) Case $aggrandissement $iScale = $iScale + 0.2 _DrawStack($iScale) Case $diminution $iScale = $iScale - 0.2 _DrawStack($iScale) EndSwitch WEnd Func _Create_CloneGUI($clone, $x_frame = -1, $y_frame = -1) Local $winpos = WinGetPos($hGUI) Local $width_border = _WinAPI_GetSystemMetrics($SM_CXSIZEFRAME) Local $height_menu = _WinAPI_GetSystemMetrics($SM_CYCAPTION) If $clone Then If $gui_clone = -1 Then $gui_clone = GUICreate("clone", $width, $height, $winpos[0] + $width_border, $winpos[1] + $height_menu + $width_border, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) GUISetState() ; delete previous dragging frame drawing on the main gui $hBrush_clone = _GDIPlus_BrushCreateSolid(0xFFF0F0F0) _GDIPlus_GraphicsFillRect($hBackbuffer, $x_frame, $y_frame, $frame_width * $iScale, $frame_height * $iScale, $hBrush_clone) _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) ; new graphic for the cloned gui (with buffer) $hGraphics_clone = _GDIPlus_GraphicsCreateFromHWND($gui_clone) $hBitmap_clone = _GDIPlus_BitmapCreateFromGraphics($winpos[2] - 2 * $width_border, $winpos[3] - $height_menu - 2 * $width_border, $hGraphics_clone) $hBackbuffer_clone = _GDIPlus_ImageGetGraphicsContext($hBitmap_clone) EndIf Else If $gui_clone <> -1 Then _GDIPlus_BrushDispose($hBrush_clone) _GDIPlus_BitmapDispose($hBitmap_clone) _GDIPlus_GraphicsDispose($hGraphics_clone) _GDIPlus_GraphicsDispose($hBackbuffer_clone) _WinAPI_DeleteObject($hHBitmap_clone) GUIDelete($gui_clone) $gui_clone = -1 EndIf EndIf EndFunc ; Draw all the frames Func _DrawStack($scale = 1, $index_en_cours = -1, $new_x = 0, $new_y = 0) Local $x, $y, $titre, $info, $tmp_cadre_largeur, $tmp_cadre_hauteur, $hauteur_cadre_titre $fps_timer = TimerInit() _GDIPlus_GraphicsClear($hBackbuffer, 0xFFF0F0F0) ; fps Local $tLayout_fps = _GDIPlus_RectFCreate(100, 10, 200, 20) _GDIPlus_GraphicsDrawStringEx($hBackbuffer, "FPS: " & StringFormat("%.2f", $fps), $hFont, $tLayout_fps, $hFormat, $hBrush) If $index_en_cours = -1 Then For $i = 1 To $array[0][0] $x = $array[$i][0] $y = $array[$i][1] $titre = $array[$i][2] $info = $array[$i][3] $tmp_cadre_largeur = Int($frame_width * $scale) $tmp_cadre_hauteur = Int($frame_height * $scale) $hauteur_cadre_titre = Int(16 * $scale) ; 15 pixels de haut $hFont = _GDIPlus_FontCreate($hFamily, Int(10 * $scale), 2) Local $tLayout_titre = _GDIPlus_RectFCreate($x, $y, $tmp_cadre_largeur, $hauteur_cadre_titre) _GDIPlus_GraphicsDrawStringEx($hBackbuffer, $titre, $hFont, $tLayout_titre, $hFormat, $hBrush) Local $tLayout_info = _GDIPlus_RectFCreate($x, $y + $hauteur_cadre_titre, $tmp_cadre_largeur, $hauteur_cadre_titre) _GDIPlus_GraphicsDrawStringEx($hBackbuffer, $info, $hFont, $tLayout_info, $hFormat, $hBrush) _GDIPlus_GraphicsDrawRect($hBackbuffer, $x, $y, $tmp_cadre_largeur, $tmp_cadre_hauteur, $hPen) ; cadre _GDIPlus_GraphicsFillRect($hBackbuffer, $x, $y, $tmp_cadre_largeur, $hauteur_cadre_titre, $hBrush_cadre_titre) ; titre _GDIPlus_GraphicsDrawRect($hBackbuffer, $x, $y + $hauteur_cadre_titre, $tmp_cadre_largeur, $hauteur_cadre_titre, $hPen) ; info _GDIPlus_GraphicsDrawImageRect($hBackbuffer, $hBitmap_switch, $x + 2, $y + Int(50 * $scale), $tmp_cadre_largeur - 4, Int(($iHeight_switch / 2) * $scale)) ; affichage de l'image du switch _GDIPlus_GraphicsDrawImageRect($hBackbuffer, $hBitmap_switch, $x + 2, $y + Int(($iHeight_switch / 2) * $scale) + Int(50 * $scale), $tmp_cadre_largeur - 4, Int(($iHeight_switch / 2) * $scale)) ; affichage de l'image du switch Next Else For $i = 1 To $array[0][0] $x = $array[$i][0] $y = $array[$i][1] $titre = $array[$i][2] $info = $array[$i][3] $tmp_cadre_largeur = Int($frame_width * $scale) $tmp_cadre_hauteur = Int($frame_height * $scale) $hauteur_cadre_titre = Int(16 * $scale) ; 15 pixels de haut If $index_en_cours = $i Then ; le stack en cours de déplacement suit les mouvements de la souris, les autres ne bougent pas $x = $new_x $y = $new_y $hFont = _GDIPlus_FontCreate($hFamily, Int(10 * $scale), 2) Local $tLayout_titre = _GDIPlus_RectFCreate($x, $y, $tmp_cadre_largeur, $hauteur_cadre_titre) _GDIPlus_GraphicsDrawStringEx($hBackbuffer, $titre, $hFont, $tLayout_titre, $hFormat, $hBrush) Local $tLayout_info = _GDIPlus_RectFCreate($x, $y + $hauteur_cadre_titre, $tmp_cadre_largeur, $hauteur_cadre_titre) _GDIPlus_GraphicsDrawStringEx($hBackbuffer, $info, $hFont, $tLayout_info, $hFormat, $hBrush) _GDIPlus_GraphicsDrawRect($hBackbuffer, $x, $y, $tmp_cadre_largeur, $tmp_cadre_hauteur, $hPen) ; cadre _GDIPlus_GraphicsFillRect($hBackbuffer, $x, $y, $tmp_cadre_largeur, $hauteur_cadre_titre, $hBrush_cadre_titre) ; titre _GDIPlus_GraphicsDrawRect($hBackbuffer, $x, $y + $hauteur_cadre_titre, $tmp_cadre_largeur, $hauteur_cadre_titre, $hPen) ; info _GDIPlus_GraphicsDrawImageRect($hBackbuffer, $hBitmap_switch, $x + 2, $y + Int(50 * $scale), $tmp_cadre_largeur - 4, Int(($iHeight_switch / 2) * $scale)) ; affichage de l'image du switch _GDIPlus_GraphicsDrawImageRect($hBackbuffer, $hBitmap_switch, $x + 2, $y + Int(($iHeight_switch / 2) * $scale) + Int(50 * $scale), $tmp_cadre_largeur - 4, Int(($iHeight_switch / 2) * $scale)) ; affichage de l'image du switch EndIf Next EndIf _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0);, $max_width, $max_height) ; copy from backbuffer to visible graphic ; FPS $fps_diff = TimerDiff($fps_timer) If TimerDiff($fps_maintimer) > 999 Then ;calculate FPS $fps = Round(1000 / $fps_diff, 2) $fps_maintimer = TimerInit() EndIf EndFunc ; Draw the dragging frame on the cloned transparent gui Func _DrawStack_GUIClone($scale = 1, $index_en_cours = -1, $new_x = 0, $new_y = 0) Local $x, $y, $titre, $info, $tmp_cadre_largeur, $tmp_cadre_hauteur, $hauteur_cadre_titre $x = $new_x $y = $new_y $titre = $array[$index_en_cours][2] $info = $array[$index_en_cours][3] $tmp_cadre_largeur = Int($frame_width * $scale) $tmp_cadre_hauteur = Int($frame_height * $scale) $hauteur_cadre_titre = Int(16 * $scale) ; 16 pixels de haut _GDIPlus_GraphicsClear($hBackbuffer_clone, 0x00000000) Local $hFont = _GDIPlus_FontCreate($hFamily, Int(10 * $scale), 2) Local $tLayout_titre = _GDIPlus_RectFCreate($x, $y, $tmp_cadre_largeur, $hauteur_cadre_titre) _GDIPlus_GraphicsDrawStringEx($hBackbuffer_clone, $titre, $hFont, $tLayout_titre, $hFormat, $hBrush) Local $tLayout_info = _GDIPlus_RectFCreate($x, $y + $hauteur_cadre_titre, $tmp_cadre_largeur, $hauteur_cadre_titre) _GDIPlus_GraphicsDrawStringEx($hBackbuffer_clone, $info, $hFont, $tLayout_info, $hFormat, $hBrush) _GDIPlus_GraphicsDrawRect($hBackbuffer_clone, $x, $y, $tmp_cadre_largeur, $tmp_cadre_hauteur, $hPen) ; cadre _GDIPlus_GraphicsFillRect($hBackbuffer_clone, $x, $y, $tmp_cadre_largeur, $hauteur_cadre_titre, $hBrush_cadre_titre) ; titre _GDIPlus_GraphicsDrawRect($hBackbuffer_clone, $x, $y + $hauteur_cadre_titre, $tmp_cadre_largeur, $hauteur_cadre_titre, $hPen) ; info _GDIPlus_GraphicsDrawImageRect($hBackbuffer_clone, $hBitmap_switch, $x + 2, $y + Int(50 * $scale), $tmp_cadre_largeur - 4, Int(($iHeight_switch / 2) * $scale)) ; affichage de l'image du switch _GDIPlus_GraphicsDrawImageRect($hBackbuffer_clone, $hBitmap_switch, $x + 2, $y + Int(($iHeight_switch / 2) * $scale) + Int(50 * $scale), $tmp_cadre_largeur - 4, Int(($iHeight_switch / 2) * $scale)) ; affichage de l'image du switch _GDIPlus_GraphicsDrawImage($hGraphics_clone, $hBitmap_clone, 0, 0) ; copy from backbuffer to visible graphic ; change the cloned gui to transparent ; should be placed here to be done each time your refresh the drawing (why ?) $hHBitmap_clone = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_clone) _WinAPI_BitmapDisplayTransparentInGUI($hHBitmap_clone, $gui_clone) _WinAPI_DeleteObject($hHBitmap_clone) EndFunc 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 $move_inprogress Then $mouseX = MouseGetPos(0) $mouseY = MouseGetPos(1) ; draw only one frame, the one dragging _DrawStack_GUIClone($iScale, $index_stack, $mouseX - $shift_X, $mouseY - $shift_Y) $array[$index_stack][0] = $mouseX - $shift_X $array[$index_stack][1] = $mouseY - $shift_Y 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 = 1 To $array[0][0] If $mouseX > $array[$i][0] And $mouseX < $array[$i][0] + $frame_width * $iScale And _ $mouseY > $array[$i][1] And $mouseY < $array[$i][1] + $frame_height * $iScale Then $shift_X = $mouseX - $array[$i][0] $shift_Y = $mouseY - $array[$i][1] ; create cloned gui on top of main gui _Create_CloneGUI(True, $mouseX - $shift_X, $mouseY - $shift_Y) ; ... we can move $move_inprogress = 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 ; If movement in progress, then it's finished, left click released If $move_inprogress Then $move_inprogress = False _DrawStack($iScale) ; draw everything in main gui _Create_CloneGUI(False) ; destroy cloned gui 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 ; From UEZ ? Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True) If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0) Local $tDim = DllStructCreate($tagBITMAP) If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0) Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION) Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap) $tSize.X = $tDim.bmWidth $tSize.Y = $tDim.bmHeight $tBlend.Alpha = $iOpacity $tBlend.Format = 1 _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteDC($hMemDC) If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap) Return True 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_BitmapDispose($hBitmap_switch) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_BrushDispose($hBrush) _GDIPlus_BrushDispose($hBrush_cadre_titre) ; Uninitialize GDI+ _GDIPlus_Shutdown() Exit EndFunc If one of you have better ideas to make it work, I am obviously interested to read them -
Need help for GDIPlus code optimization
tatane replied to tatane's topic in AutoIt General Help and Support
Indeed, I confirm your thoughts. That's why i'm asking for help -
Hi, I'm playing with GDIPlus drawing for few days and I can't find a way to optimize my script. In the code below, you'll see 50 frames created by GDIPlus functions. You can move them separately and when the drag is initiate, all the graphic is clear and every frames are redrawn. But it's sloooow. Could you help me ? Thanks for your time. P.S : You will need the attached .jpg #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> #include <WinAPIGdi.au3> #include <WinAPI.au3> 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 Const $width = Int(@DesktopWidth * 0.8), $height = Int(@DesktopHeight * 0.8) Global $max_width = 1900 Global $max_height = 1000 ; Initialize GDI+ _GDIPlus_Startup() Local $GUI_title = "GDI+" Global $hGUI = GUICreate($GUI_title, $width, $height, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_THICKFRAME,$WS_TABSTOP)) $aggrandissement = GUICtrlCreateButton("+", 10, 10, 20) $diminution = GUICtrlCreateButton("-", 40, 10, 20) GUISetState() ; main graphic and buffer Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($max_width, $max_height, $hGraphics) Global $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2) Global $hBitmap_switch = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\OS6250-24M.jpg") Global $iHeight_switch = _GDIPlus_ImageGetHeight($hBitmap_switch) ; exclude controls from GDI+ graphic region Local $hRegion = _GDIPlus_RegionCreateFromRect(0, 0, $width, $height) $aRect = ControlGetPos("", "", $aggrandissement) _GDIPlus_RegionCombineRect($hRegion, $aRect[0], $aRect[1], $aRect[2], $aRect[3], 3) $aRect = ControlGetPos("", "", $diminution) _GDIPlus_RegionCombineRect($hRegion, $aRect[0], $aRect[1], $aRect[2], $aRect[3], 3) _GDIPlus_GraphicsSetClipRegion($hGraphics, $hRegion) _GDIPlus_RegionDispose($hRegion) ; Text format Global $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000) Global $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) Global $hFamily = _GDIPlus_FontFamilyCreate("Arial") Global $hFont = _GDIPlus_FontCreate($hFamily, 10, 2) ; for the frames drawing Global $hPen = _GDIPlus_PenCreate(0xFF000000, 2) Global $hBrush_cadre_titre = _GDIPlus_BrushCreateSolid(0x55FF0000) Global $frame_width = 200 Global $frame_height = 200 Global $shift_X, $shift_Y Global $move_inprogress = False Global $index_stack Global $iScale = 1 ; creating array Global $array[51][4] $array[0][0] = 50 Local $startx = 50 Local $starty = 50 Local $guipos = WinGetPos($hGUI) Local $intervalle_x = $guipos[2] / 10 ; width Local $intervalle_y = $guipos[3] / 7 ; height For $i = 1 To $array[0][0] ; auto positionning If Mod($i, 10) = 0 Then $x = $startx $y = $array[$i - 1][1] + $intervalle_y Else If $i - 1 = 0 Then ; premier passage $x = $startx $y = $starty Else $x = $array[$i - 1][0] + $intervalle_x $y = $array[$i - 1][1] EndIf EndIf $array[$i][0] = $x $array[$i][1] = $y $array[$i][2] = "Hello world " & $i $array[$i][3] = "Bye world " & $i Next _DrawStack() 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) Case $aggrandissement $iScale = $iScale + 0.2 _DrawStack($iScale) Case $diminution $iScale = $iScale - 0.2 _DrawStack($iScale) EndSwitch WEnd Func _DrawStack($scale = 1, $index_en_cours = -1, $new_x = 0, $new_y = 0) Local $x, $y, $titre, $info, $tmp_cadre_largeur, $tmp_cadre_hauteur, $hauteur_cadre_titre _GDIPlus_GraphicsClear($hBackbuffer, 0xFFF0F0F0) For $i = 1 To $array[0][0] $x = $array[$i][0] $y = $array[$i][1] $titre = $array[$i][2] $info = $array[$i][3] $tmp_cadre_largeur = Int($frame_width * $scale) $tmp_cadre_hauteur = Int($frame_height * $scale) $hauteur_cadre_titre = Int(16 * $scale) ; 15 pixels de haut If $index_en_cours = $i Then ; le stack en cours de déplacement suit les mouvements de la souris, les autres ne bougent pas $x = $new_x $y = $new_y EndIf $hFont = _GDIPlus_FontCreate($hFamily, Int(10 * $scale), 2) Local $tLayout_titre = _GDIPlus_RectFCreate($x, $y, $tmp_cadre_largeur, $hauteur_cadre_titre) _GDIPlus_GraphicsDrawStringEx($hBackbuffer, $titre, $hFont, $tLayout_titre, $hFormat, $hBrush) Local $tLayout_info = _GDIPlus_RectFCreate($x, $y + $hauteur_cadre_titre, $tmp_cadre_largeur, $hauteur_cadre_titre) _GDIPlus_GraphicsDrawStringEx($hBackbuffer, $info, $hFont, $tLayout_info, $hFormat, $hBrush) _GDIPlus_GraphicsDrawRect($hBackbuffer, $x, $y, $tmp_cadre_largeur, $tmp_cadre_hauteur, $hPen) ; cadre _GDIPlus_GraphicsFillRect($hBackbuffer, $x, $y, $tmp_cadre_largeur, $hauteur_cadre_titre, $hBrush_cadre_titre) ; titre _GDIPlus_GraphicsDrawRect($hBackbuffer, $x, $y + $hauteur_cadre_titre, $tmp_cadre_largeur, $hauteur_cadre_titre, $hPen) ; info _GDIPlus_GraphicsDrawImageRect($hBackbuffer, $hBitmap_switch, $x + 2, $y + Int(50 * $scale), $tmp_cadre_largeur - 4, Int(($iHeight_switch / 2) * $scale)) ; affichage de l'image du switch Next _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0);, $max_width, $max_height) ; copy from backbuffer to visible graphic EndFunc 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 $move_inprogress Then $mouseX = MouseGetPos(0) $mouseY = MouseGetPos(1) _DrawStack($iScale, $index_stack, $mouseX - $shift_X, $mouseY - $shift_Y) $array[$index_stack][0] = $mouseX - $shift_X $array[$index_stack][1] = $mouseY - $shift_Y 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 = 1 To $array[0][0] If $mouseX > $array[$i][0] And $mouseX < $array[$i][0] + $frame_width * $iScale And _ $mouseY > $array[$i][1] And $mouseY < $array[$i][1] + $frame_height * $iScale Then $shift_X = $mouseX - $array[$i][0] $shift_Y = $mouseY - $array[$i][1] ; ... we can move $move_inprogress = 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 $move_inprogress Then $move_inprogress = 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_BitmapDispose($hBitmap_switch) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_BrushDispose($hBrush) _GDIPlus_BrushDispose($hBrush_cadre_titre) ; Uninitialize GDI+ _GDIPlus_Shutdown() Exit EndFunc
-
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 ?
-
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
-
Indeed, it seems there is no memory leak when resizing the Gui. I will try this way. Thanks.
-
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.
-
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
-
No idea ?
-
Scrollbars Made Easy - New version 27 Jan 22
tatane replied to Melba23's topic in AutoIt Example Scripts
Sorry, there are some problem with this version too. I will try something else. If even you have some problem with scrollbars, I'm not skilled enough to do better. I thank you for the time you passed helping me. -
Hi, I'm starting with GDIPlus functions and I've got problem (of course 😑 ). Here is the code : #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> #include <WinAPIGdi.au3> Opt("GUIOnEventMode", 1) Local $hGUI, $hGraphics, $hBackbuffer, $hBitmap Local Const $iX = Int(@DesktopWidth * 0.5), $iY = Int(@DesktopHeight * 0.5) ; Initialize GDI+ _GDIPlus_Startup() Local $GUI_title = "GDI+" $hGUI = GUICreate($GUI_title, $iX, $iY, -1, -1, BitOR($GUI_SS_DEFAULT_GUI,$WS_THICKFRAME,$WS_TABSTOP)) GUISetState() Local $Child_Gui1 = GUICreate("Child1", 200, 200, 50, 50) GUISetBkColor(0x99B4D1) GUISetState() _WinAPI_SetParent($Child_Gui1, $hGUI) Local $Child_Gui2 = GUICreate("Child2", 200, 200, 300, 300) GUISetBkColor(0x99B4D1) GUISetState() _WinAPI_SetParent($Child_Gui2, $hGUI) $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iX, $iY, $hGraphics) $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; Using antialiasing _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2) Local $hPen = _GDIPlus_PenCreate(0xFF000000, 2) GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit") GUIRegisterMsg(0x0216, "WM_MOVING") While 1 Sleep(20) WEnd Func WM_MOVING($hWnd, $Msg, $wParam, $lParam) Local $trect ;~ typedef struct _RECT { ;~ LONG left; ;~ LONG top; ;~ LONG right; ;~ LONG bottom; ;~ } RECT, *PRECT; If $hWnd = $Child_Gui2 Then $winposChild1 = WinGetPos($Child_Gui1) ; absolute coord ; coord conversion absolute to relative for child1 $tPoint_parent = DllStructCreate("int X;int Y") DllStructSetData($tPoint_parent, "X", $winposChild1[0]) DllStructSetData($tPoint_parent, "Y", $winposChild1[1]) _WinAPI_ScreenToClient($hGUI, $tPoint_parent) $X_relative_child1 = DllStructGetData($tPoint_parent, "X") $Y_relative_child1 = DllStructGetData($tPoint_parent, "Y") $trect = DllStructCreate("struct;long left;long top;long right;long bottom;endstruct" ,$lParam) ; absolute ; coord conversion absolute to relative for child2 $tPoint_parent = DllStructCreate("int X;int Y") DllStructSetData($tPoint_parent, "X", DllStructGetData($trect, "left")) DllStructSetData($tPoint_parent, "Y", DllStructGetData($trect, "top")) _WinAPI_ScreenToClient($hGUI, $tPoint_parent) $X_relative_child2 = DllStructGetData($tPoint_parent, "X") $Y_relative_child2 = DllStructGetData($tPoint_parent, "Y") ; Drawing _GDIPlus_GraphicsClear($hBackbuffer, 0xFFFFFFFF) _GDIPlus_GraphicsDrawLine($hBackbuffer, $X_relative_child2, $Y_relative_child2, $X_relative_child1, $Y_relative_child1, $hPen) ; relative coord _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $iX, $iY) _WinAPI_RedrawWindow($hGUI) EndIf Return 0 EndFunc Func _Exit() ; Clean up _GDIPlus_BrushDispose($hPen) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hBackbuffer) _GDIPlus_GraphicsDispose($hGraphics) ; Uninitialize GDI+ _GDIPlus_Shutdown() Exit EndFunc Just move the Child2, you should see a line between the 2 childs and this line follow the movement of the child2. The repaint works but it flickers a lot. How can I handle that ? Thanks for your time. EDIT : Here is a screenshot of what I am looking for. I'm scanning a LAN with Alcatel Switches (through snmp) and I make this layout. I can move the child Gui and I would like that the line follow the gui I'm dragging. For now all the lines are drawn when I click the "Dessiner" button.
-
Scrollbars Made Easy - New version 27 Jan 22
tatane replied to Melba23's topic in AutoIt Example Scripts
Hi, No problem when I start the script. As soon as I resize the GUI, a second GUI appears/disappears on my second screen. When the Gui is at max size, the scrollbars are still there and I can scroll down/right. Sorry to bother you with that, if Windows scrollbars stuff is so messy, I will remove the resize Gui functionality and replace it by 3 differents resolutions. -
Scrollbars Made Easy - New version 27 Jan 22
tatane replied to Melba23's topic in AutoIt Example Scripts
Thanks a lot. I guess you change something in GUIScrollbars_Size_Test.au3 ? It's buggy with the "official" version. Could you attach the code please ? -
Scrollbars Made Easy - New version 27 Jan 22
tatane replied to Melba23's topic in AutoIt Example Scripts
Yes, it removes the scrollbar but you can still scroll down and left (green background appears). -
Scrollbars Made Easy - New version 27 Jan 22
tatane replied to Melba23's topic in AutoIt Example Scripts
Thank you Melba23. Just a last thing. When your start the script, enlarge at max the GUI, zoom+ one or several time, then zoom- to get back to $diviseur = 1, the scrollbars stay visible. They should be hide. If I hide them manually, it works but i can still scroll while it is at max size. -
Scrollbars Made Easy - New version 27 Jan 22
tatane replied to Melba23's topic in AutoIt Example Scripts
Sorry I didn't find any sort of example in the forum. Is it complicated ? -
Scrollbars Made Easy - New version 27 Jan 22
tatane replied to Melba23's topic in AutoIt Example Scripts
Good job, It's working ! Thanks a lot I've found another strange behaviour if I add $WS_MAXIMIZEBOX style to the GUI. If you just Run the example and maximized the GUI, it takes the max width and height defined in _WM_GETMINMAXINFO() but the scrollbars are still shown and we can still scroll. EDIT : I've added this case and it seems to solve the problem. I don't know if this is the right way to do this Case $GUI_EVENT_MAXIMIZE _GUIScrollbars_Restore($hGUI, False, False) EDIT 2 : Could you have a look at the commented stuff please. I'm trying to make a zoom in/out but I can't get it to work properly -
Scrollbars Made Easy - New version 27 Jan 22
tatane replied to Melba23's topic in AutoIt Example Scripts
Ok. Do your best Maybe I will find a trick to achieve what I'm looking for. Thank you. -
Scrollbars Made Easy - New version 27 Jan 22
tatane replied to Melba23's topic in AutoIt Example Scripts
Hi Melba23, I'm playing with your nice UDF and I don't understand the behaviour of _Gui_ScrollBar_Ex_Example_5. When the GUI is at full size, the scrollbars are hidden (normal behaviour) but I can still scroll down or scroll to the right. Am I missing something ? #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <MsgBoxConstants.au3> #include <GUIScrollbars_Ex.au3> Global $iGUI_1_MinX = 300, $iGUI_1_MinY = 200 Global $iGUI_1_MaxX, $iGUI_1_MaxY ;~ Global $diviseur = 1 Local $iMax_Scroll = 600 Local $hGUI = GUICreate("Resizeable Test ", 400, 400, Default, Default, $WS_SIZEBOX) GUISetBkColor(0xCCFFCC) Local $cStart = GUICtrlCreateDummy() ;~ GUICtrlCreateLabel("", 0, 0, 500, 500) ;~ GUICtrlSetBkColor(-1, 0xFFCCCC) GUICtrlCreateLabel("Use me to check that the scrolled position" & @CRLF & "is maintained if possible during resizing", 50, 50, 300, 50) GUICtrlSetBkColor(-1, 0xCCCCFF) GUICtrlCreateLabel("", 0, 0, 10, 10) GUICtrlSetBkColor(-1, 0xFF0000) GUICtrlCreateLabel("", 0, 590, 10, 10) GUICtrlSetBkColor(-1, 0xFF0000) GUICtrlCreateLabel("", 590, 0, 10, 10) GUICtrlSetBkColor(-1, 0xFF0000) GUICtrlCreateLabel("", 590, 590, 10, 10) GUICtrlSetBkColor(-1, 0xFF0000) Local $cEnd = GUICtrlCreateDummy() For $i = $cStart To $cEnd GUICtrlSetResizing($i, $GUI_DOCKALL) Next ;~ $b_testminus = GUICtrlCreateButton("zoom -", 5, 5) ;~ $b_testplus = GUICtrlCreateButton("zoom +", 55, 5) ; Generate initial scrollbars - required scrollbar handlers registered _GUIScrollbars_Generate($hGUI, $iMax_Scroll, $iMax_Scroll) ; Intialise for resizing Local $aMaxSize = _GUIScrollbars_ReSizer($hGUI, $iMax_Scroll, $iMax_Scroll, False) GUISetState(@SW_SHOW) $iGUI_1_MaxX = $aMaxSize[0] $iGUI_1_MaxY = $aMaxSize[1] GUIRegisterMsg($WM_GETMINMAXINFO, "_WM_GETMINMAXINFO") While 1 $nmsg = GUIGetMsg() Switch $nmsg ;~ Case $b_testplus ;~ $diviseur = $diviseur * 2 ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $diviseur = ' & $diviseur & @CRLF) ;### Debug Console ;~ $a_scroll = _GUIScrollbars_Generate($hGUI, $iMax_Scroll*$diviseur, $iMax_Scroll*$diviseur) ;~ ConsoleWrite("Aperture width="&$a_scroll[0]&@CRLF) ;~ ConsoleWrite("Aperture height="&$a_scroll[1]&@CRLF) ;~ ConsoleWrite("Width correction factor="&$a_scroll[2]&@CRLF) ;~ ConsoleWrite("Height correction factor="&$a_scroll[3]&@CRLF) ;~ Case $b_testminus ;~ If $diviseur > 1 Then ;~ $diviseur = $diviseur / 2 ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $diviseur = ' & $diviseur & @CRLF) ;### Debug Console ;~ _GUIScrollbars_Generate($hGUI, $iMax_Scroll/$diviseur, $iMax_Scroll/$diviseur) ;~ ConsoleWrite("Aperture width="&$a_scroll[0]&@CRLF) ;~ ConsoleWrite("Aperture height="&$a_scroll[1]&@CRLF) ;~ ConsoleWrite("Width correction factor="&$a_scroll[2]&@CRLF) ;~ ConsoleWrite("Height correction factor="&$a_scroll[3]&@CRLF) ;~ EndIf Case $GUI_EVENT_CLOSE Exit EndSwitch Sleep(10) WEnd GUIRegisterMsg($WM_GETMINMAXINFO, "") GUIDelete($hGUI) Func _WM_GETMINMAXINFO($hWnd, $iMsg, $wParam, $lParam) Local $tagMaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam) DllStructSetData($tagMaxinfo, 7, $iGUI_1_MinX) ; min X DllStructSetData($tagMaxinfo, 8, $iGUI_1_MinY) ; min Y DllStructSetData($tagMaxinfo, 9, $iGUI_1_MaxX) ; max X DllStructSetData($tagMaxinfo, 10, $iGUI_1_MaxY) ; max Y Return 0 EndFunc ;==>_WM_GETMINMAXINFO Thanks for your time -
Hello ! I would like to create a script that allow me to show a network view of my LAN switches. To achieve that I'm loading Pic controls that I can move inside the GUI and resize like a zoom. My problem is to handle the scrollbar/zoom with this GUI. Look at that : #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #Include <GDIPlus.au3> #include <StaticConstants.au3> #include <WinAPI.au3> #include <GUIScrollbars_Ex.au3> #include <Array.au3> ;These constants found in the helpfile under Windows Message Codes ;Global Const $WM_MOUSEMOVE = 0x0200 ;mouse move ;~ Global Const $WM_MOUSEWHEEL = 0x020A ;wheel up/down ;~ Global Const $WM_LBUTTONDOWN = 0x0201 ;~ ;Global Const $WM_LBUTTONUP = 0x0202 ;~ Global Const $WM_RBUTTONDOWN = 0x0204 ;~ Global Const $WM_RBUTTONUP = 0x0205 ;~ Global Const $WM_MBUTTONDOWN = 0x0207 ;~ Global Const $WM_MBUTTONUP = 0x0208 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 Global $diff_x Global $diff_y Global $g_iMouseX, $g_iMouseY Global $diviseur = 1 ;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 $_GUI = GUICreate("Ma GUI", 1020, 720, -1, -1, BitOR($WS_MAXIMIZEBOX,$WS_MINIMIZEBOX,$WS_SYSMENU,$WS_TABSTOP)) Global $b_zoomminus = GUICtrlCreateButton("zoom -", 5, 5) Global $b_zoomplus = GUICtrlCreateButton("zoom +", 55, 5) _GDIPlus_Startup() $sImageName = "" ; choose an jpg or bmp to load with full path $hImage = _GDIPlus_ImageLoadFromFile($sImageName) $iWidth = _GDIPlus_ImageGetWidth($hImage) $iHeight = _GDIPlus_ImageGetHeight($hImage) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() Local $_Image = GUICtrlCreatePic($sImageName, 10, 200, $iWidth, $iHeight) GUICtrlSetPos($_Image, Default, Default, $iWidth / 2, $iHeight / 2) GUISetState(@SW_SHOW) _GUIScrollbars_Generate($_GUI, 2000, 2000) While 1 $nmsg = GUIGetMsg() Switch $nmsg Case $GUI_EVENT_CLOSE DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hM_Hook[0]) $hM_Hook[0] = 0 DllCallbackFree($hKey_Proc) $hKey_Proc = 0 Exit Case $GUI_EVENT_MINIMIZE _GUIScrollbars_Minimize($_GUI) Case $GUI_EVENT_RESTORE _GUIScrollbars_Restore($_GUI) Case $b_zoomplus $diviseur = diviseur * 2 $a_scroll = _GUIScrollbars_Generate($_GUI, 2000 * diviseur, 2000 * diviseur) $a_ctrlcurrentpos = ControlGetPos($_GUI, "", $_Image) GUICtrlSetPos($_Image, Default, Default, $a_ctrlcurrentpos[2] * 2, $a_ctrlcurrentpos[3] * 2) Case $b_zoomminus If $diviseur > 1 Then $diviseur = diviseur / 2 $a_scroll = _GUIScrollbars_Generate($_GUI, 2000 / diviseur, 2000 / diviseur) $a_ctrlcurrentpos = ControlGetPos($_GUI, "", $_Image) GUICtrlSetPos($_Image, Default, Default, $a_ctrlcurrentpos[2] / 2, $a_ctrlcurrentpos[3] / 2) EndIf EndSwitch Sleep(10) WEnd Func _Mouse_Proc($nCode, $wParam, $lParam) Local $info, $mouseData, $time, $timeDiff Local $a_cursorinfo 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" ; coordonnées globales $g_iMouseX = DllStructGetData($info, 1) $g_iMouseY = DllStructGetData($info, 2) ; conversion des coordonnées globales en relatives $tPoint = DllStructCreate("int X;int Y") DllStructSetData($tPoint, "X", $g_iMouseX) DllStructSetData($tPoint, "Y", $g_iMouseY) _WinAPI_ScreenToClient($_GUI, $tPoint) GUICtrlSetPos($_Image, DllStructGetData($tPoint, "X") - $diff_x, DllStructGetData($tPoint, "Y") - $diff_y) 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 ; on récupère la position du curseur lors du clic et l'id du control cliqué s'il y en a un sous le curseur $a_cursorinfo = GUIGetCursorInfo($_GUI) If $a_cursorinfo[4] = $_Image Then ; position du control Local $a_controlpos = ControlGetPos($_GUI, "", $_Image) ; on calcule la différence entre les coordonnées du clic et celles du control ; cela permettra de déplacer le control sans décalage de position $diff_x = $a_cursorinfo[0] - $a_controlpos[0] $diff_y = $a_cursorinfo[1] - $a_controlpos[1] ; Register Button Down, check for Right/Left If $currentEvent[0] = "RClick" Then $LRClickStatus = 1 EndIf $iLBUTTONDOWN = 1 EndIf 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 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 & $currentEvent[1] & @CRLF) $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _ "int", $nCode, "ptr", $wParam, "ptr", $lParam) Return $ret[0] EndFunc ;==>_Mouse_Proc Thanks for your help.
-
How to connect to a snmp v3 configured switch
tatane replied to tatane's topic in AutoIt General Help and Support
I've found this : https://www.nsoftware.com/powershell/netcmdlets/download.aspx There is a commandlet for PowerShell : Get-SNMP. It's working with Snmpv3 but it's slow... like 11 seconds to get the ifinoctets table. Not perfect but it works. -
Thanks for your time passed on looking at my demand. Because of the frequent updating I finally chose a txt file save (write only by the server and read only by the client). I just convert the array to a string with the function made by jguinch.
-
Thanks everybody. I will read all your links/advices. My first script is a tcp server and I would like a second script to handle the "data processing" by this server. So realtime would be great. EDIT : So I can't use AutoitObject because the 2 scripts will be compiled. Because of the realtime update, I can't use command line parameters neither. The array to string function is interesting with _FileWriteFromArray. Maybe Filemapping could be another solution : Edit 2 : I can't make FileMapping to work with 2 compiled scripts. It works with one.
-
Hi, I would like to send an array from a script to a another. This array has 1000 rows and 4 columns with this kind of data : 1st row = 528 ; 31 ; HOSTNAME|1|02:45:47|abcdefgh|username|5 ; old 2nd row = ... What IPC should I use ?