; ;filename: _WindowControlOperationsUDF.au3 ;Author: ahha ;Attributions: ;SmOke_N and Valik and bo8ster and corgano and mistersquirrle and the wonderful AutoIt community ;https://www.autoitscript.com/forum/topic/93527-control-handle-under-mouse/page/2/#comments ;http://www.autoitscript.com/forum/index.php?showtopic=32781 ;https://www.autoitscript.com/forum/topic/190427-how-do-i-remove-the-horizontal-scroll-bar-from-an-edit-control/ ;v1a - original ;v1b - moving edit box around with arrows ;v1c - functions for moving ;v1d - show $iLeft, $iTop, $iWidth, $iHeight in edit box which can be copied and pasted into other code ;v1e - keep edit window active so can see the blue borders - could not figure out a way to do it ;v1f - paint 2 windows and pick one to resize ;v1g - a lot of temp code ;v1h - cleaning up select window code ; good place to find if keyboard shortcuts have been used for https://defkey.com/search?irq=ctrl%2Bshift%2Balt%2Bw ;v1i - adding functions to get handle or control ID ; see: https://www.autoitscript.com/forum/topic/93527-control-handle-under-mouse/ ;v1j - added bo8ster code from https://www.autoitscript.com/forum/topic/93527-control-handle-under-mouse/page/2/#comments ;vik - ;v1l - ;v1m - ;v1n - reverting back to an earlier version as I have cleaned up Get Handle below mouse _WinAPI_WindowFromPoint v1f.au3 to a few short lines ; and plan on incorporating it into this version ;v1o - added in correct MouseCoordMode ;v1p - now have Func _While1() ;v1q - putting more functionality in so don't need to pass as much info to Func _WindowOperations() ;v1r - removing extraneous code ;v2a+ - going to an external (to the target window) floating window for instructions on use ;v2l - using _GUI UDF function for Instructions Status updating so I can just use a handle ;v2m - using Global scope in function that remains a Global in other called functions from the top see: functions v1b.au3 ;v2n - replacing user selected control with one made via _GUI UDF so that I can simply refer to it by a handle ;v2nb - adjusting speed of redraw and changing control shorter to use up arrow ; Note that we replace all controls with an edit box so that we can copy control text if we want although ; the $iLeft, $iTop, $iWidth, $iHeight values are in the status box in the Instructions window ; see https://www.autoitscript.com/forum/topic/151529-moving-controls-around-in-an-already-created-gui/ ; see GUICtrlSetResizing ; see ControlMove - it can use handles ; see https://technology.amis.nl/software-development/automating-actions-on-windows-my-first-steps-with-autoit/ ;v2nc - to be done - adding arrow movement speed up base on hits of arrow in 1 second ;v2nd - Ctrl being pressed with a key speeds up movement, using ControlMove so we don't have to delete control redraw it and get a new handle ;v2ne - cleaning up extraneous code ;v2o - going back to Alt+W and adding Adjust Window Size and Adjust Control Size/Position buttons to Instructions window ;v2p - keep array of window/control text and size/position so that we can List All when button pressed ; only get window title and 1 line of control text ; make listing like this in the order as they are adjusted so latest at bottom. ; ; Window/Control Title, Left, Top, Width, Height ; Window: Text, 707, 307, 506, 429 ;<-- earliest adjustment recorded with "Stop Adjusting Current Selection" button ; Control: Edit control #2, 200, 200, 250, 100 ; Control: Nice, 294, 177, 85, 25 ; Control: Edit control #2, 209, 259, 253, 107 ;<-- last adjustment recorded ; ; Note: You can record size/position by just selecting and then clicking "Stop Adjusting Current Selection" button without having to do any adjustment (good for recording status of window/control) ; ;v2pf - cleaning out extraneous code ;v2pi - trying to limit scope of variables to be ready for a possible UDF implementation ;v2pj - quickly checking for ALt+W, the if true calling another function ;v2q - making it a UDF so user needs to: ; #include "_WindowControlOperationsUDF.au3" if _WindowControlOperationsUDF.au3 in the script directory OR ; #include "[path\]_WindowControlOperationsUDF.au3" if _WindowControlOperationsUDF.au3 located somewhere else ; see help file for #include ;v2qa - cleaning up some code ;v2qb - cleaning up more code ;v2qc - keeping Globals declared in functions as Global only to that function and functions therein thus no need to make Local ;v2qd - ;v3a - polling like mistersquirrle so that we can exit if we click another button - look at using Esc to exit instead using a Hotkeyset ;v3b - splitting out Cases into functions so that other routines can call them also if needed outside of the While 1 message loop ; look at this if decide to code for WM_SYSCOMMAND https://www.autoitscript.com/forum/topic/184084-disable-esk-key-close-window/ ;v3bf - cleaning up ;v3bg - breaking into a UDF again, getting error: Pause() already defined error as a lot of my code uses it, so trying to code around it ; KISS so just rename this UDF Pause to LPause to indicate Local Pause, as not sure how to use Call to not have it included ;v3bh - 1st release 2023-02-19 ; Global $version = "v3bh" ;now Local and outside of all other functions - so it appears Global to all functions called so call it correctly a Global Local $hDLL = DllOpen("user32.dll") ;also Global to all functions called - DO NOT close as calling program may be using user32.dll ;actually we CAN close it as user's call to same user32.dll will have a different handle #AutoIt3Wrapper_run_debug_mode=Y ;use this to debug in console window <--- LOOK #include-Once #include ;for _DebugArrayDisplay() #include #include #include #include ;for _IsPressed() #include ;for _WinAPI_WindowFromPoint() ;from bo8ster #include AutoItSetOption("MustDeclareVars", 1) Opt("GUICloseOnESC", 0) ;turn OFF Esc to close window as we use Esc to get out of some routines and don't want user exiting anything more, user must use X in upper right to close instructions window ;NOTE any variables declared here as Local (outside all the subsequent functions) are actually Global to this entire UDF and all functions therein Global $debug = 1 ;0=off, 1=on, 2+ deeper Func _WindowControlOperations() ;called by user program and only continues if Alt+W pressed, keep it short and sweet as called frequently If NOT ( ((_IsPressed("12") = 1) AND (_IsPressed("57") = 1)) ) Then ;check for Alt+W ;12 ALT key, 57 W key ; default DLL=user32.dll ;DO NOT define DLL in this function as it's called frequently - simply use default Return(0) ;as Alt+W not pressed Else ;Alt+W pressed to call rest _WindowControlOperationsContinue() EndIf EndFunc ;Func _WindowControlOperations() Func _WindowControlOperationsContinue() ;called by user program and only continues if Alt+W pressed ;Alt+W was pressed so let's continue ;NOTE ;$hWnd is the user's window main handle for what we are adjusting ;$hControl is handle for control (window) in $hWnd ;$ControlID is for a control in $hControl ;$hWndInstructions is the Instructions window main handle, ;$hStatus is handle for status control in $hWndInstructions window ;$hAdjusting is handle of window/control we are adjusting Global $hWnd, $hControl, $ControlID, $hStatus, $hAdjusting ;eventually make Local <-- no need to as Global to any subsequently called functions only Global $sAbortMode ;yes or no Global $sAdjusting, $hWndOriginalText ;v2p - keep array of window/control text and size/position so that we can List All when button pressed ; only get window title and 1 line of control text ; make listing like this in the order as they are adjusted so latest at bottom. ; ; Window/Control Title, Left, Top, Width, Height ; Window: Text, 707, 307, 506, 429 ; Control: Edit control #2, 200, 200, 250, 100 ; Control: Nice, 294, 177, 85, 25 ; Control: Edit control #2, 209, 259, 253, 107 ;<-- lastest adjustment ; ; Set up in an array and use _DebugArrayDisplay to show it to user. User can copy from _DebugArrayDisplay if needed. ; Global $aWindowControlLog[1][3] = [ ["Window/Control", "Title", "Left, Top, Width, Height"] ] ;element [0] [Row][Column] ;_DebugArrayDisplay($aWindowControlLog, "$aWindowControlLog") ;get some calling program info ;this we need to keep track of so that when we exit the Alt+W mode we can return it to its original value Global $iOriginalMouseCoordMode = Opt("MouseCoordMode") ;save the calling program MouseCoordMode and return it to this when done with program ;********************************************************************************************************************************************************* ;IMPORTANT NOTE - you *MUST* use absolute mouse coordinates for $g_tStruct to work properly * Opt("MouseCoordMode", 1) ;1=absolute, 0=relative, 2=client ;IMPORTANT NOTE - you *MUST* use absoulte mouse coordinates for $g_tStruct to work properly * ;IMPORTANT NOTE - you *MUST* use absoulte mouse coordinates for $g_tStruct to work properly * ;********************************************************************************************************************************************************* ;v2a - create an Instructions window Global $iLeft = 0, $iTop = 0, $iWidth = 0, $iHeight = 0 ;init values Global $sStatus = "$iLeft, $iTop, $iWidth, $iHeight" &@CRLF& $iLeft &", "& $iTop &", "& $iWidth &", "& $iHeight ;create main Instructions window Global $hWndInstructions = GUICreate("Instructions", 300, 468) ;the main instructions window ;NOTE on Window dimensions ;the Instructions window above is 300 x 468 however the shown size readout from the program is 306 x 497 ;so left/right border is +3 on each side (300 + 3 left + 3 right = 306) ;and Title and bottom border is 29 so compensate accordingly 497-468 = 29 ;so for a given readout size use these values $iWidth-6, $iHeight-29 in your GUICreate code Local $sInstructions = "1st Move this Instructions window out of the way" &@CRLF& _ " so that you can clearly see the window/controls you" &@CRLF& _ " want to adjust." &@CRLF& _ " " &@CRLF& _ "2nd Click one of the Adjust buttons below" &@CRLF& _ " when you are ready to adjust." &@CRLF& _ " " &@CRLF& _ "3rd Shift+LeftClick on the window/control you want to adjust." &@CRLF& _ " " &@CRLF& _ "4th Use arrow keys to move the window/control." &@CRLF& _ "Use SHIFT + arrow keys to change" &@CRLF& _ " width and height of the window/control." &@CRLF& _ " Holding down Ctrl will adjust faster." &@CRLF& _ " " &@CRLF& _ "5th Click Stop Adjust button to save adjustment." &@CRLF& _ " Then click others if needed." &@CRLF& _ " " &@CRLF& _ "6th When done adjusting copy the window/control" &@CRLF& _ " values displayed below and use them in your program." &@CRLF& _ " OR Click List All to list all adjustments made." &@CRLF& _ " " &@CRLF& _ "7th Click upper right X to exit program." ;create an edit control - into which we'll put the instruction text ;Local $iL = 10, $iT = 10, $iW = 280, $iH = 290 Local $cIDInstructions = GUICtrlCreateEdit("", 10, 10, 280, 312, BitOR($ES_WANTRETURN, $WS_VSCROLL, $ES_AUTOVSCROLL)) ;no , $WS_HSCROLL)) ;create status control Global $sStatus = "$iLeft, $iTop, $iWidth, $iHeight" &@CRLF& $iLeft &", "& $iTop &", "& $iWidth &", "& $iHeight ;use _GUICtrlEdit_Create so that I get a handle directly to it and don't need to have a parent or window active Global $hStatus = _GUICtrlEdit_Create($hWndInstructions, $sStatus, 10, 330, 280, 50) ;LPause("$hStatus = '" & $hStatus & "'") ;now some buttons to make it easier for user ;trying to add multi-line see: https://www.autoitscript.com/forum/topic/33001-multiline-on-a-button/ Global $idButton_Window = GUICtrlCreateButton("Adjust Window" &@CRLF& "Size/Position", 8, 386, 139, 35, 0x2000) ;create window button ,0x2000=multi-line Global $idButton_Control = GUICtrlCreateButton("Adjust Control" &@CRLF& "Size/Position", 152, 386, 139, 35, 0x2000) ;create control button ,0x2000=multi-line Global $idButton_StopAdjust = GUICtrlCreateButton("Stop Adjusting" &@CRLF& "Current Selection", 8, 424, 139, 35, 0x2000) ;create window button ,0x2000=multi-line Global $idButton_List = GUICtrlCreateButton("List All" &@CRLF& "Sizes/Positions", 152, 424, 139, 35, 0x2000) ;create control button ,0x2000=multi-line GUISetState(@SW_SHOW, $hWndInstructions) ;show window and edit controls ControlSetText("", "", $cIDInstructions, $sInstructions) ;show instructions ;LPause("Instructions window should be visible.") ControlSetText("", "", $hStatus, $sStatus) ;show status ;LPause("Status should be updated.") Global $g_tStruct = DllStructCreate($tagPOINT) ; Create a structure that defines the point to be checked. _While1() ;enter our message loop ;LPause("Back from_While1(") ;clean up - these are taken care of in Case $GUI_EVENT_CLOSE Return(0) ;to main calling program EndFunc ;Func _WindowControlOperationsContinue() Func _While1() ;$hWnd, $hControl, $ControlID, $iLeft, $iTop, $iWidth, $iHeight, $hStatus) ;arguments are all Global Local $mposorig = MouseGetPos() ;get orignal mouse postion Local $mposnew ;remember these are relative to its *WINDOW* Global $hWndOriginalText, $sStatus, $nMsg, $sToolTipText, $sWindowControl Global $aWinPos, $aControlPos ;$iLeft, $iTop, $iWidth, $iHeight Global above Global $sAdjusting = "", $sControlOrigText ;Global $aWindowControlLog[1][3] = [ ["Window/Control", "Title", "Left, Top, Width, Height"] ] ;element [0] [Row][Column] ;~ LPause("In: Func _While1()" & @CRLF & _ ;~ "$hGUI = '" & $hGUI & "'" & @CRLF & _ ;~ "$hControl = '" & $hControl & "'" & @CRLF & _ ;~ "$ControlID = '" & $ControlID & "'" & @CRLF & _ ;~ "$iLeft = '" & $iLeft & "'" & @CRLF & _ ;~ "$iTop = '" & $iTop & "'" & @CRLF & _ ;~ "$iWidth = '" & $iWidth & "'" & @CRLF & _ ;~ "$iHeight = '" & $iHeight & "'" & @CRLF & _ ;~ "$hStatus = '" & $hStatus & "'" & @CRLF & _ ;~ "relative to its *WINDOW*") While 1 ;~ If (_IsPressed("11",$hDLL) = 1) Then LPause("CTRL pressed.") ;yes you can press multiple keys at a time as this logic goes through all Ifs sequentially If NOT (_IsPressed("10",$hDLL) = 1) Then ;no SHIFT key pressed If (_IsPressed("25",$hDLL) = 1) Then _Left() ;25 LEFT ARROW key If (_IsPressed("27",$hDLL) = 1) Then _Right() ;27 RIGHT ARROW key If (_IsPressed("26",$hDLL) = 1) Then _Up() ;26 UP ARROW key If (_IsPressed("28",$hDLL) = 1) Then _Down() ;28 DOWN ARROW key Else ;we have a SHIFT key pressed If (_IsPressed("25",$hDLL) = 1) Then _Narrower() ;25 LEFT ARROW key ;10 SHIFT key If (_IsPressed("27",$hDLL) = 1) Then _Wider() ;27 RIGHT ARROW key ;10 SHIFT key If (_IsPressed("28",$hDLL) = 1) Then _Taller() ;28 DOWN ARROW key ;10 SHIFT key If (_IsPressed("26",$hDLL) = 1) Then _Shorter() ;26 UP ARROW key ;10 SHIFT key EndIf ;look for button presses $nMsg = GUIGetMsg() If $nMsg <> 0 Then ;we have a message so Switch $nMsg ;Check for GUI events Case $GUI_EVENT_CLOSE ;the GUI is closed red [X] is clicked ;If $debug > 0 Then LPause("In: Case $GUI_EVENT_CLOSE") __GUI_EVENT_CLOSE() Return(0) ;to Func _WindowControlOperationsContinue() Case $idButton_Window ;let's go adjust size/position of a window __idButton_Window() Case $idButton_Control ;let's go adjust size/position of a control __idButton_Control() Case $idButton_StopAdjust ;turn off adjusting __idButton_StopAdjust() Case $idButton_List __idButton_List() Case Else ;do nothing EndSwitch ;End running through GUI events. Else ;no message - do nothing ;no message EndIf ;This code is executed every time in While 1 loop ;only repaint ToolTip if mouse position has changed so we reduce ToolTip flicker - we also do this in Func _MoveIt() ;And we have a button pressed If $sAdjusting = "Window" OR $sAdjusting = "Control" OR $sAdjusting = "Stopped" OR $sAdjusting = "" Then ;LPause("$sAdjusting = '" & $sAdjusting & "'") $mposnew = MouseGetPos() ;get new mouse postion If $mposorig[0] <> $mposnew[0] OR $mposorig[1] <> $mposnew[1] Then ;the mouse has moved so repaint ToolTip $mposorig = $mposnew ;array assignment for next comparison ;use separate If statements so easy to add more. If a bunch then use Case or Switch. If $sAdjusting = "Window" Then ;get window status $aWinPos = WinGetPos($hWnd) ;$aArray[0] = X position, $aArray[1] = Y position, $aArray[2] = Width, $aArray[3] = Height $iLeft = $aWinPos[0] ;get left position $iTop = $aWinPos[1] ;get top position $iWidth = $aWinPos[2] ;get width position $iHeight = $aWinPos[3] ;get height position ;give it a separate tooltip ToolTip("-- In mode: Adjust Window Size/Position --" & @CRLF & _ "Use arrow keys to move Window." & @CRLF & _ "Or use the mouse in the title bar to move it roughly." & @CRLF & _ "Use SHIFT + arrow keys to change width and height of Window." & @CRLF & _ "Holding down Ctrl will move faster." & @CRLF & _ "Currently:" & @CRLF & _ $sStatus & @CRLF & _ "Click Stop Adjusting to record values or press Esc to abort this mode.") EndIf ;use separate If statements so easy to add more. If a bunch then use Case or Switch. If $sAdjusting = "Control" Then ;get window status $aControlPos = ControlGetPos($hControl, "", "") ;$aArray[0] = X position, $aArray[1] = Y position, $aArray[2] = Width, $aArray[3] = Height $iLeft = $aControlPos[0] ;get left position $iTop = $aControlPos[1] ;get top position $iWidth = $aControlPos[2] ;get width position $iHeight = $aControlPos[3] ;get height position ;give it a separate tooltip ToolTip("-- In mode: Adjust Control Size/Position --" & @CRLF & _ "Use arrow keys to move " & $sAdjusting &"." & @CRLF & _ "Use SHIFT + arrow keys to change width and height of Control." & @CRLF & _ "Holding down Ctrl will move faster." & @CRLF & _ "Currently:" & @CRLF & _ $sStatus & @CRLF & _ "Click Stop Adjusting to record values or press Esc to abort this mode.") EndIf ;use separate If statements so easy to add more. If a bunch then use Case or Switch. If $sAdjusting = "Stopped" Then ;get window status ;give it a separate tooltip ToolTip("Click a button when you are ready.") ;show the ToolTip EndIf ;use separate If statements so easy to add more. If a bunch then use Case or Switch. If $sAdjusting = "" Then ;give it a separate tooltip ToolTip("Click a button when you are ready.") ;show the ToolTip EndIf ;show the status if repainted $sStatus = "$iLeft, $iTop, $iWidth, $iHeight" &@CRLF& $iLeft &", "& $iTop &", "& $iWidth &", "& $iHeight ControlSetText($hStatus, "", "",$sStatus ) ;show status - use handle to directly address it EndIf ;if mouse moved EndIf ;if $sAdjusting mode WEnd ;While 1 Sleep(100) EndFunc ;Func _While1() Func __GUI_EVENT_CLOSE() ;close the Alt+W window ;DllClose($hDLL) - DON'T close DLL as it may be in use by calling program ToolTip("") ;turn it off GUIDelete($hWndInstructions) ;destroy the Instructions window and all controls therein ;clean up WinSetTitle($hWnd, "", $hWndOriginalText) ;return user's window to it's original title (don't check just brute force) Opt("MouseCoordMode", $iOriginalMouseCoordMode) ;return to original mode MsgBox(262144, "INFO", "Press Alt+W to activate again.") EndFunc ;Func __GUI_EVENT_CLOSE() Func __idButton_Window() ;try and indicate active button ;don't use these as causes rounded control ;error at some low level in AutoIt ;GUICtrlSetColor($idButton_Window, 0x00ff00) ;set text color (RGB) to indicate active ;GUICtrlSetBkColor($idButton_Window, 0x0f0f00) ;change the color (RGB) of the button background to show mode in ;Bolding works and does *not* round the control GUICtrlSetFont($idButton_Control, Default, Default, Default) ;set Control button to normal text GUICtrlSetFont($idButton_Window, Default, 700, 2) ;Bold and italic Window button ;FW_BOLD = 700, $GUI_FONTITALIC (2) = Italic ;pop up initial tooltip even though we don't yet have $hWnd which we get from $hWnd = _GetWindowHandle() because we only repaint the ToolTip instructions when the mouse moves ToolTip("-- In mode: Adjust Window Size/Position --" & @CRLF & _ "Shift+Left click once (or twice) on the Window to operate on (not the title bar)." & @CRLF & _ "The title bar should change to indicate the Window Handle below." & @CRLF & _ "Window Handle = " & $hWnd & @CRLF & _ "Press Esc to abort this mode.") $hWnd = _GetWindowHandle() ;$hWnd at mouse x,y location ;LPause("$hWnd = '" & $hWnd & "'") If $hWnd = -1 Then ;we Esc'd out as -1 is not a legit handle ;we do this in the abort ;GUICtrlSetFont($idButton_Window, Default, Default, Default) ;reset Window button to normal text Else ;we have a legit handle $hWndOriginalText = WinGetTitle($hWnd) ;get original window title text ;LPause("$hGUIOriginalText = '" & $hGUIOriginalText & "'") WinSetTitle($hWnd, "", $hWndOriginalText & " --> Window Handle = '" & $hWnd & "'") ;show changing title text ;$sWindowControl = "Window" ;not needed as can use $sAdjusting which is "Window" or "Control" ;recall Global $aWindowControlLog[1][3] = [ ["Window/Control", "Title", "Left, Top, Width, Height"] ] ;element [0] [Row][Column] $sAdjusting = "Window" ;other option is "Control" or "Stopped" or "" $hAdjusting = $hWnd ;set $hAdjusting as used in common movement routines EndIf EndFunc ;Func __idButton_Window() Func _GetWindowHandle() ;$hWnd at mouse x,y location Local $hWnd Local $mposorig = MouseGetPos() ;get orignal mouse postion Local $mposnew HotKeySet("{ESC}", "_AbortMode") ;set Esc as a hotkey to abort this operation i.e. exit the Do loop early Do ;get Main Window Handle ;code from Get Handle below mouse _WinAPI_WindowFromPoint v1f.au3 DllStructSetData($g_tStruct, "x", MouseGetPos(0)) ;Update the X and Y elements with the X and Y co-ordinates of the mouse. DllStructSetData($g_tStruct, "y", MouseGetPos(1)) Mousemove(MouseGetPos(0), MouseGetPos(1)) ;move mouse to where it's pointing so we don't get messed up $hWnd = _WinAPI_WindowFromPoint($g_tStruct) ; Retrieve the window handle. ;$ControlID = _WinAPI_GetDlgCtrlID($hWnd) ;get Control ID (using Control Handle) ;only repaint if mouse moved $mposnew = MouseGetPos() ;get new mouse postion If $mposorig[0] <> $mposnew[0] OR $mposorig[1] <> $mposnew[1] Then ;the mouse has moved so repaint ToolTip $mposorig = $mposnew ;array assignment ToolTip("-- In mode: Adjust Window Size/Position --" & @CRLF & _ "Shift+Left click once (or twice) on the Window to operate on (not the title bar)." & @CRLF & _ "The title bar should change to indicate the Window Handle below." & @CRLF & _ "Window Handle = " & $hWnd & @CRLF & _ "Press Esc to abort this mode.") EndIf Sleep(100) If $sAbortMode = "yes" Then ;we turn off HotKeySet in Func _AbortMode(), set $sAbortMode = "yes", and set $sAdjusting = "", and ToolTip to default $sAbortMode = "no" ;indicate abort mode off Return(-1) ;to indicate we Esc'd out as -1 is not a valid handle ;<<<<<<<<<<<<< an early Return EndIf Until ((_IsPressed("10",$hDLL) = 1) AND (_IsPressed("01",$hDLL) = 1)) ;Shift+LeftClick ;10 SHIFT key, ;01 Left mouse button ToolTip("") ;turn it off Return($hWnd) ;return the window handle below the mouse EndFunc ;Func _GetWindowHandle() Func _AbortMode() HotKeySet("{ESC}") ;unregister HotKeySet because we only want to set it for the shortest time needed, so we don't multi trigger $sAbortMode = "yes" ;reset to "no" in calling routine $sAdjusting = "" ;recall $sAdjusting = "Window" OR $sAdjusting = "Control" OR $sAdjusting = "Stopped" OR "" ToolTip("") ;turn it off ToolTip("Click a button when you are ready.") ;show the default ToolTip ;return buttons to normal text - regardless of state GUICtrlSetFont($idButton_Window, Default, Default, Default) ;set Window button to normal text GUICtrlSetFont($idButton_Control, Default, Default, Default) ;set Control button to normal text ;make sure title text is back to original IF we got title text ;LPause("$hWnd = '" & $hWnd & "' $hWndOriginalText = '" & $hWndOriginalText & "'") If $hWndOriginalText = "" Then ;do nothing as we don't have original title text yet, just leave title as is Else WinSetTitle($hWnd, "", $hWndOriginalText) ;make sure title text is back to original EndIf ;reset $sStatus $sStatus = "$iLeft, $iTop, $iWidth, $iHeight" &@CRLF& "0, 0, 0, 0" ControlSetText($hStatus, "", "",$sStatus ) ;show status - use handle to directly address it EndFunc ;Func _AbortMode() Func __idButton_Control() GUICtrlSetFont($idButton_Window, Default, Default, Default) ;set Window button to normal text GUICtrlSetFont($idButton_Control, Default, 700, 2) ;Bold and italic Control button ;$FW_BOLD = 700, $GUI_FONTITALIC (2) = Italic $hControl = _GetControlHandle() ;at mouse x,y location If $hControl = -1 Then ;we Esc'd out as -1 is not a legit handle ;now done in _AbortMode() ;GUICtrlSetFont($idButton_Control, Default, Default, Default) ;reset Control button to normal text Else ;we have a legit handle ;_MoveIt() sets the status in the control so we don't need to do it here ;however we do need to get the original control text $sControlOrigText = ControlGetText($hControl, "", "") ;LPause("$sControlOrigText = '" & $sControlOrigText & "'") ;recall Global $aWindowControlLog[1][3] = [ ["Window/Control", "Title", "Left, Top, Width, Height"] ] ;element [0] [Row][Column] $sAdjusting = "Control" ;other option is "Window" or "Stopped" or "" $hAdjusting = $hControl ;set $hAdjusting as used in common movement routines EndIf EndFunc ;Func __idButton_Control() Func _GetControlHandle() ;$hControl at mouse x,y location ;$hControl, $ControlID ;declared Global above HotKeySet("{ESC}", "_AbortMode") ;set Esc as a hotkey to abort this operation Do ;get Control handle ;code from Get Handle below mouse _WinAPI_WindowFromPoint v1f.au3 DllStructSetData($g_tStruct, "x", MouseGetPos(0)) ;Update the X and Y elements with the X and Y co-ordinates of the mouse. DllStructSetData($g_tStruct, "y", MouseGetPos(1)) Mousemove(MouseGetPos(0), MouseGetPos(1)) ;move mouse to where it's pointing so we don't get messed up $hControl = _WinAPI_WindowFromPoint($g_tStruct) ; Retrieve the window handle. $ControlID = _WinAPI_GetDlgCtrlID($hControl) ;get Control ID (using Control Handle) ToolTip("-- In mode: Adjust Control Size/Position --" & @CRLF & _ "Shift+Left click on contol to operate on." & @CRLF & _ "Control Handle = " & $hControl & @CRLF & _ "Control ID (api) = " & $ControlID& @CRLF & _ "Press Esc to abort this mode.") Sleep(100) If $sAbortMode = "yes" Then ;we turn off HotKeySet in Func _AbortMode(), set $sAbortMode = "yes", and set $sAdjusting = "", and ToolTip to default $sAbortMode = "no" ;indicate abort mode off Return(-1) ;to indicate we Esc'd out as -1 is not a valid handle ;<<<<<<<<<<<<< an early Return EndIf Until ((_IsPressed("10",$hDLL) = 1) AND (_IsPressed("01",$hDLL) = 1)) ;Shift+LeftClick ;10 SHIFT key, ;01 Left mouse button ToolTip("") ;turn it off Return($hControl) EndFunc ;Func _GetControlHandle() Func __idButton_StopAdjust() ;grab the current adjust info and stick in $aWindowControlLog ;recall Global $aWindowControlLog[1][3] = [ ["Window/Control", "Title", "Left, Top, Width, Height"] ] ;element [0] [Row][Column] ;add another Row to the array ReDim $aWindowControlLog[UBound($aWindowControlLog) + 1][3] ;Rows from UBound are 1 based ;_DebugArrayDisplay($aWindowControlLog, "$aWindowControlLog after adding a Row") ;now fill the entries, -1 because array 0 based ;Global $sStatus = "$iLeft, $iTop, $iWidth, $iHeight" &@CRLF& $iLeft &", "& $iTop &", "& $iWidth &", "& $iHeight ;So for status need to keep just stuff after @CRLF Local $iTemp = StringInStr($sStatus, @CRLF) ;points to start of @CRLF Local $sTemp = StringMid($sStatus, $iTemp+2) ;+2 for CR and LF ;returns string to right $aWindowControlLog[UBound($aWindowControlLog) - 1][0] = $sAdjusting ;first column If $sAdjusting = "Window" Then $aWindowControlLog[UBound($aWindowControlLog) - 1][1] = $hWndOriginalText ;second column If $sAdjusting = "Control" Then $aWindowControlLog[UBound($aWindowControlLog) - 1][1] = $sControlOrigText ;second column $aWindowControlLog[UBound($aWindowControlLog) - 1][2] = $sTemp ;third column GUICtrlSetFont($idButton_Window, Default, Default, Default) ;set Window button to normal text GUICtrlSetFont($idButton_Control, Default, Default, Default) ;set Control button to normal text $sAdjusting = "Stopped" ToolTip("Click a button when you are ready.") ;show the tooltip ;_DebugArrayDisplay($aWindowControlLog, "$aWindowControlLog") WinSetTitle($hWnd, "", $hWndOriginalText) ;turn off Window title - don't bother checking EndFunc ;Func __idButton_StopAdjust() Func __idButton_List() _DebugArrayDisplay($aWindowControlLog, "$aWindowControlLog") ;show coordinate and size information EndFunc ;Func __idButton_List() Func _Left() ;LPause("25 LEFT ARROW key") ;25 LEFT ARROW key $iLeft = $iLeft - 1 _MoveIt() EndFunc ;Func _Left() Func _Right() ;LPause("27 RIGHT ARROW key") ;27 RIGHT ARROW key $iLeft = $iLeft + 1 _MoveIt() EndFunc ;Func _Right() Func _Up() ;LPause("26 UP ARROW key") ;26 UP ARROW key $iTop = $iTop - 1 _MoveIt() EndFunc ;Func _Up() Func _Down() ;LPause("28 DOWN ARROW key") ;28 DOWN ARROW key $iTop = $iTop + 1 _MoveIt() EndFunc ;Func _Up() Func _Narrower() $iWidth = $iWidth - 1 _MoveIt() EndFunc ;Func _Narrower() Func _Wider() $iWidth = $iWidth + 1 _MoveIt() EndFunc ;Func _Wider() Func _Taller() $iHeight = $iHeight + 1 _MoveIt() EndFunc ;Func _Taller() Func _Shorter() $iHeight = $iHeight - 1 _MoveIt() EndFunc ;Func _Shorter() Func _MoveIt() ;~ LPause("In: Func _MoveIt($hGUI, $hControl, $ControlID, $iLeft, $iTop, $iWidth, $iHeight, $cIDStatus)" & @CRLF & _ ;~ "$hGUI = '" & $hGUI & "'" & @CRLF & _ ;~ "$hControl = '" & $hControl & "'" & @CRLF & _ ;~ "$ControlID = '" & $ControlID & "'" & @CRLF & _ ;~ "$iLeft = '" & $iLeft & "'" & @CRLF & _ ;~ "$iTop = '" & $iTop & "'" & @CRLF & _ ;~ "$iWidth = '" & $iWidth & "'" & @CRLF & _ ;~ "$iHeight = '" & $iHeight & "'" & @CRLF & _ ;~ "relative to its *WINDOW*") ;in earlier versions we put status into the control - not doing that now as we need to see control and user can see status in control in Instructions ;show the status in the Instructions window Local $sStatus = "$iLeft, $iTop, $iWidth, $iHeight" &@CRLF& $iLeft &", "& $iTop &", "& $iWidth &", "& $iHeight ControlSetText($hStatus, "", "",$sStatus ) ;show status - use handle to directly address it Local $hX ;Are we adjusting a Window or Control? If $sAdjusting = "Window" Then $hX = WinMove($hAdjusting, "", $iLeft, $iTop, $iWidth, $iHeight) ;If $hX = 0 Then LPause("WinMove window was NOT found.") ;If $hX = $hAdjusting Then LPause("WinMove window WAS found.") ToolTip("-- In mode: Adjust Window Size/Position --" & @CRLF & _ "Use arrow keys to move Window." & @CRLF & _ "Or use the mouse in the title bar to move it roughly." & @CRLF & _ "Use SHIFT + arrow keys to change width and height of Window." & @CRLF & _ "Holding down Ctrl will move faster." & @CRLF & _ "Currently:" & @CRLF & _ $sStatus & @CRLF & _ "Click Stop Adjusting to record values or press Esc to abort this mode.") ;don't stuff anything in the title. Let user get parameters from status. EndIf ;$sAdjusting = "Window" ;again separate If statements so we can add easily If $sAdjusting = "Control" Then ;adjust a control ;v2nd ControlMove($hAdjusting, "", "", $iLeft, $iTop, $iWidth, $iHeight) ;move the control ToolTip("-- In mode: Adjust Control Size/Position --" & @CRLF & _ "Use arrow keys to move Control" & @CRLF & _ "Use SHIFT + arrow keys to change width and height of Control" & @CRLF & _ "Holding down Ctrl will move faster." & @CRLF & _ "Currently:" & @CRLF & _ $sStatus & @CRLF & _ "Click Stop Adjusting to record values or press Esc to abort this mode.") EndIf ;$sAdjusting = "Control" ;Ctrl pressed speeds it up If (_IsPressed("11",$hDLL) = 1) Then ;11 CTRL key ;no sleep Else ;limit it to to 4/second Sleep(250) EndIf EndFunc ;Func _MoveIt() Func LPause($text="") ;__scrolltext("Debug: Paused " & $text & @CRLF) MsgBox(262144, "DEBUG", "Paused: " & $text) EndFunc