Jump to content

Scope of #include


ahha
 Share

Go to solution Solved by mistersquirrle,

Recommended Posts

I whittled down much code and have isolated my problem to where a #include is located in the code, but apparently do not understand the scope of #include.  In the example code below I open up a window, then when you press Alt+W I open a second window with a List All button.  Clicking the List All button invokes a _DebugArrayDisplay().  At line  4 and 50 are the #include <Debug.au3> for the _DebugArrayDisplay().  If I comment out the line 4 #include <Debug.au3> the program crashes.  I thought the line 50 #include <Debug.au3> would work however it does not, so I'm concluding I don't understand what' going on.  Any assistance greatly appreciated.

#AutoIt3Wrapper_run_debug_mode=Y    ;use this to debug in console window <--- LOOK

#include <Debug.au3>    ;for _DebugArrayDisplay()   ;<-- commenting this out makes it fail vs #include at line 50 ???
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiEdit.au3>
#include <WindowsConstants.au3>

AutoItSetOption("MustDeclareVars", 1)

;create an example window with an edit control
Local $hGUI = GUICreate("Test", 500, 400)   ;the main window
Local $cIDEdit1 = GUICtrlCreateEdit("Edit control #1", 10, 10, 200, 250, Bitor($ES_WANTRETURN, $WS_VSCROLL, $ES_AUTOVSCROLL, $WS_HSCROLL))
GUISetState(@SW_SHOW, $hGUI)    ;show it

MsgBox(262144, "USAGE", "Example window." &@CRLF&@CRLF& "Press Alt+W (once or twice) after clicking OK to enter window/control mode.")

Local $nMsg

While 1     ;this is your code main loop
    $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
                Exit
            Case Else
                ;do nothing
        EndSwitch   ;End running through GUI events.
    Else    ;no message
        Sleep(100)  ;do something in your program
    EndIf

    ;---------------------------------------------------------------------------------------------------------------------------+
    ;ADD this function into your $nMsg loop after the $nMsg EndIf   ;as shown here or in your While 1 loop so it gets executed  |
    _WindowControlOperations()      ;let's go into move/adjust window/control operations if Alt+W pressed                       |
    ;comment out this function call when all done, or delete it                                                                 |
    ;---------------------------------------------------------------------------------------------------------------------------+
WEnd


;------------------------------------------ this code below intended to be in a UDF eventually ----------------------------------------

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 <Debug.au3>    ;for _DebugArrayDisplay()   ;<-- this one does not seem to work, only one in user's program above seems to work
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiEdit.au3>
#include <Misc.au3>     ;for _IsPressed()
#include <WindowsConstants.au3>

AutoItSetOption("MustDeclareVars", 1)


Func _WindowControlOperations()     ;called by user program and only continues below if Alt+W pressed else returns to calling program above
        If NOT ( ((_IsPressed("12") = 1) AND (_IsPressed("57") = 1)) ) Then ;check for Alt+W    ;12 ALT key, 57 W key ; default DLL=user32.dll
            Return(0)   ;as Alt+W not pressed
        Else    ;Alt+W pressed to call rest
            _WindowControlOperationsContinue()
        EndIf
EndFunc     ;Func _WindowControlOperations()


Func _WindowControlOperationsContinue()     ;Alt+W was pressed

    Global $aWindowControlLog[1][3] = [ ["Window/Control", "Title", "Left, Top, Width, Height"] ]   ;element [0] [Row][Column]

    ;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, 457)  ;the main instructions window

    Local $sInstructions =  "Click List All to list all adjustments made." &@CRLF& _
                            " " &@CRLF& _
                            "Click upper right X to exit program."

    ;create an edit control - into which we'll put the instruction text
    Local $cIDInstructions = GUICtrlCreateEdit("", 10, 10, 280, 300, Bitor($ES_WANTRETURN, $WS_VSCROLL, $ES_AUTOVSCROLL))   ;no , $WS_HSCROLL))

    Global $sStatus = "$iLeft, $iTop, $iWidth, $iHeight" &@CRLF& $iLeft &", "& $iTop  &", "& $iWidth &", "& $iHeight
    Global $hStatus = _GUICtrlEdit_Create($hWndInstructions, $sStatus, 10, 318, 280, 50)

    Global $idButton_List = GUICtrlCreateButton("List All" &@CRLF& "Sizes/Positions", 152, 412, 139, 35, 0x2000)    ;create control button ,0x2000=multi-line

    GUISetState(@SW_SHOW, $hWndInstructions)    ;show window and edit controls
    ControlSetText("", "", $cIDInstructions, $sInstructions)    ;show instructions
    ControlSetText("", "", $hStatus, $sStatus)  ;show status

    _While1()   ;enter our message loop

    Return(0)   ;to main calling program
EndFunc     ;Func _WindowControlOperationsContinue()


Func _While1()
    Local $nMsg
    While 1
        ;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
                    GUIDelete($hWndInstructions)    ;destroy the Instructions window and all controls therein
                    Return(0)   ;to Func _WindowControlOperationsContinue()
                Case $idButton_List
                    _DebugArrayDisplay($aWindowControlLog, "$aWindowControlLog")    ;<-- problem here with #include <Debug.au3> scope
                Case Else
                    ;do nothing
            EndSwitch   ;End running through GUI events.
        Else    ;no message - do nothing
            ;no message
        EndIf
    WEnd    ;While 1
EndFunc     ;Func _While1()

 

Link to comment
Share on other sites

An #include directive simply pastes the contents of the specified to-be-included file where you place that directive. Since #includes frequently contain both function definitions and global variable definitions, it makes sense to always place #includes at the top of your script, so all required definitions are processed before your own code relies upon them.

Have a look in Debug.au3 and you'll find:

; #CONSTANTS# ===================================================================================================================
Global Const $__g_sReportWindowText_Debug = "Debug Window hidden text"
; ===============================================================================================================================

; #VARIABLE# ====================================================================================================================
Global $__g_sReportTitle_Debug = "AutoIt Debug Report"
Global $__g_iReportType_Debug = 0
Global $__g_bReportWindowWaitClose_Debug = True, $__g_bReportWindowClosed_Debug = True
Global $__g_hReportEdit_Debug = 0
Global $__g_hReportNotepadEdit_Debug = 0
Global $__g_sReportCallBack_Debug
Global $__g_bReportTimeStamp_Debug = False
Global $__g_bComErrorExit_Debug = False, $__g_oComError_Debug = Null
; ===============================================================================================================================

Do you think Debug functions will work nicely if you call them without these being predefined? ;)

Okay, I'll try and explain again. AutoIt includes have no scope; they are just inserted as-is where you put them. If your code makes a forward call to an #included function (as you do, to Windowcontroloperations, which then eventually requires a Debug.au3 function to be available), your code never processses the part of Debug.au3 that it relies upon to function properly, because it never passes that point, because the IP never leaves your first while loop (it only calls directly to other functions, without bothering to define the work environment the #include requires, which would have been set up if you'd just placed it where it belongs, at the top, so the IP passes it before it gets to your script.

Edited by RTFC
clarification
Link to comment
Share on other sites

@RTFCRespectfully, then why does commenting out the first #include at line 4 not default to using the #include at line 50 in my code that follows line 50?  Instead it acts like the line 50 #include is not working.

I still don't understand as I put the #include inside the Func _WindowControlOperationsContinue() and it does not work.  So how does one put a #include in a UDF to have it work?  I looked at Debug.au3 and it has the #include-once structure I'm trying to use.

Edited by ahha
Link to comment
Share on other sites

  • Solution
3 hours ago, RTFC said:

An #include directive simply pastes the contents of the specified to-be-included file where you place that directive.

AutoIt includes have no scope; they are just inserted as-is where you put them. If your code makes a forward call to an #included function (as you do, to Windowcontroloperations, which then eventually requires a Debug.au3 function to be available), your code never processses the part of Debug.au3 that it relies upon to function properly

 

3 hours ago, ahha said:

@RTFCRespectfully, then why does commenting out the first #include at line 4 not default to using the #include at line 50 in my code that follows line 50?  Instead it acts like the line 50 #include is not working.

It doesn't work because you're "including" the file too late. You enter a While loop at line 21, and so nothing after it is executed or initialized. That means that this whole section is never reached, and with how AutoIt works, the functions exist, but all the variables from the includes are never initialized and do not exist:

;------------------------------------------ this code below intended to be in a UDF eventually ----------------------------------------

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 <Debug.au3> ;for _DebugArrayDisplay() ;< - -this one does Not seem To work, only one In user's program above seems to work
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiEdit.au3>
#include <Misc.au3> ;for _IsPressed()
#include <WindowsConstants.au3>

AutoItSetOption("MustDeclareVars", 1)

 

So, the FUNCTIONS from the includes DO exist, all the variables do NOT, because they're not initialized. As RTFC said, it's best to put all includes at the TOP of the script, before you do anything, like declare your own variables.

My suggestion would be to treat your "intended to be in a UDF eventually" code as a UDF, and move all of it into a different file, and include that in the first half of the script. Doing that worked just fine for me, so I had the file looking like: 

#AutoIt3Wrapper_run_debug_mode=Y    ;use this to debug in console window <--- LOOK

;~ #include <Debug.au3>    ;for _DebugArrayDisplay()   ;<-- commenting this out makes it fail vs #include at line 50 ???
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiEdit.au3>
#include <WindowsConstants.au3>
#include "ahha-include.au3"

AutoItSetOption("MustDeclareVars", 1)

;create an example window with an edit control
Local $hGUI = GUICreate("Test", 500, 400)   ;the main window
Local $cIDEdit1 = GUICtrlCreateEdit("Edit control #1", 10, 10, 200, 250, BitOR($ES_WANTRETURN, $WS_VSCROLL, $ES_AUTOVSCROLL, $WS_HSCROLL))
GUISetState(@SW_SHOW, $hGUI)    ;show it

MsgBox(262144, "USAGE", "Example window." & @CRLF & @CRLF & "Press Alt+W (once or twice) after clicking OK to enter window/control mode.")

Local $nMsg

While 1     ;this is your code main loop
    $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
                Exit
            Case Else
                ;do nothing
        EndSwitch   ;End running through GUI events.
    Else    ;no message
        Sleep(100)  ;do something in your program
    EndIf

    ;---------------------------------------------------------------------------------------------------------------------------+
    ;ADD this function into your $nMsg loop after the $nMsg EndIf   ;as shown here or in your While 1 loop so it gets executed  |
    _WindowControlOperations()      ;let's go into move/adjust window/control operations if Alt+W pressed                       |
    ;comment out this function call when all done, or delete it                                                                 |
    ;---------------------------------------------------------------------------------------------------------------------------+
WEnd

And then the ahha-include file like:

;------------------------------------------ this code below intended to be in a UDF eventually ----------------------------------------

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 <Debug.au3> ;for _DebugArrayDisplay() ;< - -this one does Not seem To work, only one In user's program above seems to work
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiEdit.au3>
#include <Misc.au3> ;for _IsPressed()
#include <WindowsConstants.au3>

AutoItSetOption("MustDeclareVars", 1)


Func _WindowControlOperations()     ;called by user program and only continues below if Alt+W pressed else returns to calling program above
    If Not (((_IsPressed("12") = 1) And (_IsPressed("57") = 1))) Then       ;check for Alt+W    ;12 ALT key, 57 W key ; default DLL=user32.dll
        Return (0)      ;as Alt+W not pressed
    Else        ;Alt+W pressed to call rest
        _WindowControlOperationsContinue()
    EndIf
EndFunc   ;==>_WindowControlOperations


Func _WindowControlOperationsContinue()     ;Alt+W was pressed

    Global $aWindowControlLog[1][3] = [["Window/Control", "Title", "Left, Top, Width, Height"]]     ;element [0] [Row][Column]

    ;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, 457)  ;the main instructions window

    Local $sInstructions = "Click List All to list all adjustments made." & @CRLF & _
            " " & @CRLF & _
            "Click upper right X to exit program."

    ;create an edit control - into which we'll put the instruction text
    Local $cIDInstructions = GUICtrlCreateEdit("", 10, 10, 280, 300, BitOR($ES_WANTRETURN, $WS_VSCROLL, $ES_AUTOVSCROLL))   ;no , $WS_HSCROLL))

    Global $sStatus = "$iLeft, $iTop, $iWidth, $iHeight" & @CRLF & $iLeft & ", " & $iTop & ", " & $iWidth & ", " & $iHeight
    Global $hStatus = _GUICtrlEdit_Create($hWndInstructions, $sStatus, 10, 318, 280, 50)

    Global $idButton_List = GUICtrlCreateButton("List All" & @CRLF & "Sizes/Positions", 152, 412, 139, 35, 0x2000)  ;create control button ,0x2000=multi-line

    GUISetState(@SW_SHOW, $hWndInstructions)    ;show window and edit controls
    ControlSetText("", "", $cIDInstructions, $sInstructions)    ;show instructions
    ControlSetText("", "", $hStatus, $sStatus)  ;show status

    _While1()   ;enter our message loop

    Return (0)  ;to main calling program
EndFunc   ;==>_WindowControlOperationsContinue


Func _While1()
    Local $nMsg
    While 1
        ;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
                    GUIDelete($hWndInstructions)    ;destroy the Instructions window and all controls therein
                    Return (0)  ;to Func _WindowControlOperationsContinue()
                Case $idButton_List
                    _DebugArrayDisplay($aWindowControlLog, "$aWindowControlLog")    ;<-- problem here with #include <Debug.au3> scope
                Case Else
                    ;do nothing
            EndSwitch   ;End running through GUI events.
        Else    ;no message - do nothing
            ;no message
        EndIf
    WEnd    ;While 1
EndFunc   ;==>_While1

 

Doing it like this worked for me with the #include <Debug.au3> commented or uncommented in the main script.

We ought not to misbehave, but we should look as though we could.

Link to comment
Share on other sites

@mistersquirrleThanks!  You are correct that in a separate file it works.  In all my past scripts I have the #includes at the top.  In this one I was trying not to "burden" a user's example code at the top with the need to have #includes needed in my code and so I stuck at the top of my code the #includes with the assumption that once mycode was run the #includes would be "pasted in" my code.  Wrong assumption as I see even if I put the #include at the top of the While 1 loop it does not work.  Thanks again.

Link to comment
Share on other sites

@RTFCand @mistersquirrlethanks for your inputs.  So often when users provide answers they're just seeing the "problem" the coder is asking about without seeing where it fits in the overall code.  So here you go with what you helped.  The file "Example for _WindowControlOperationsUDF usage.au3" is the calling program and the file "_WindowControlOperationsUDF.au3" is the UDF file.  It's a simple move/adjust window/control application that allows the user to finely move/adjust window/controls in their running program.  At least I find it useful (it was actually used to create the Instructions window (after you press Alt+W)).  Thanks again.

Example for _WindowControlOperationsUDF usage.au3 _WindowControlOperationsUDF.au3

Edited by ahha
Link to comment
Share on other sites

@ahha I was a bit bored and interested in your UDF, so I poked around and made some changes, mostly from changing some Global things to Local. Keep in mind scope:

  • Global - Anywhere you put it, it's available to the current script and anything that includes it. For UDFs, Globals should only be used when you want your variable to be used/available to the scripts that include/call the UDF.
  • Local - When used outside of a function, the variable is available to every function in the script (as long as it's declared/ initialized BEFORE the function is called). When used inside of a function, it's only available to that function, and declaring a Local variable inside a function when that variable already exists outside the function will use the functions locally declared variable/value instead.

Here's a little script that shows how the scopes work a little bit:

Local $sMeow = 'Meow'

Func __Meow()
    Local $sMeow = 'Woof'
    ConsoleWrite('$sMeow inside: ' & $sMeow & @CRLF)
    Global $sWoof = 'Bark'
EndFunc

__Meow()
ConsoleWrite('$sMeow outside: ' & $sMeow & @CRLF)
ConsoleWrite('$sWoof outside: ' & $sWoof & @CRLF)

Exit

Note that if you tried to do the ConsoleWrite($sWoof & @CRLF) before you called the __Meow() function, it would fail (because you haven't declared the variable yet). There are some options you can set in SciTE that would warn you of these issues as well.

 

Another important (in my mind) change that I did was I moved checking the GUIGetMsg() to a separate function so that it can be called while doing both _GetWindowHandle and  _GetControlHandle. This way if you click 'Stop' after you've selected one of those options, but you haven't Shift + Clicked onto something, it'll stop doing those functions.

 

Anyways, here's my modification of your UDF script, I changed a few things all over the place, so I'd recommend using some file comparison tool (like Meld) to see the changes:

;filename: _WindowControlOperationsUDF.au3
;Author: ahha
;Attributions: ;SmOke_N and Valik and bo8ster and corgano 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
;       Control: Edit control #2, 200, 200, 250, 100
;       Control: Nice, 294, 177, 85, 25
;       Control: Edit control #2, 209, 259, 253, 107    ;<-- lastest adjustment
;
;v2pf - cleaning out extraneous code
;v2pi - trying to limit scope of variables to 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

Local $version = "v2q"    ;now Local and outside of all other functions - so it appears Global to all functions called

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 <Debug.au3> ;for _DebugArrayDisplay()
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiEdit.au3>
#include <Misc.au3> ;for _IsPressed()
#include <WinAPI.au3> ;for _WinAPI_WindowFromPoint() ;from bo8ster
#include <WindowsConstants.au3>

Local $While1_hGui, $While1_hControl, $While1_sStatus
Local $aWinPos, $iLeft, $iTop, $iWidth, $iHeight, $aControlPos
Local $sAdjusting = "", $sControlOrigText
Local $hOperationsGui, $hOperationsControl, $hOperationsControlId, $hOperationsStatus, $hOperationsAdjusting
Local $hWndInstructions
Local $iOperationsDebug = 1, $iOriginalMouseCoordMode
Local $sStatus
Local $idOperations_Button_Window, $idOperations_Button_Control, $idOperations_Button_StopAdjust, $idOperations_Button_List
Local $g_tStruct
Local $aWindowControlLog[1][3] = [["Window/Control", "Title", "Left, Top, Width, Height"]]

AutoItSetOption("MustDeclareVars", 1)


Func _WindowControlOperations()        ;called by user program and only continues if Alt+W pressed
    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   ;==>_WindowControlOperations


Func _WindowControlOperationsContinue()        ;called by user program and only continues if Alt+W pressed
    ;Alt+W was pressed so let's continue

    ;NOTE
    ;$hGUI is the user's window main handle for what we are adjusting
    ;$hControl is handle for control (window) in $hGUI
    ;$hOperationsControlId is for a control in $hControl
    ;$hWndInstructions is the Instructions window main handle,
    ;$hOperationsStatus is handle for status control in $hWndInstructions window
    ;$hOperationsAdjusting is handle of window/control we are adjusting

;~  Global $hGUI, $hControl, $hOperationsControlId, $hOperationsStatus, $hOperationsAdjusting        ;eventually make Local <-- no need to as Global to any subsequently called functions
;~  Global $debug = 1    ;0=off, 1=on, 2+ deeper

    ;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.
    ;
;~  $aWindowControlLog[1][3] = [["Window/Control", "Title", "Left, Top, Width, Height"]]      ;element [0] [Row][Column]
    $aWindowControlLog[0][0] = "Window/Control"
    $aWindowControlLog[0][1] = "Title"
    $aWindowControlLog[0][2] = "Left, Top, Width, Height"
    ;_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
    $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
    $sStatus = "$iLeft, $iTop, $iWidth, $iHeight" & @CRLF & $iLeft & ", " & $iTop & ", " & $iWidth & ", " & $iHeight

    ;create main Instructions window
    $hWndInstructions = GUICreate("Instructions", 300, 468)    ;the main instructions window
    ;recall shown window size is 306, 486 - so left/right border is +3 on each side, and Title and bottom border is 29 so compensate accordingly
    ;for example after adjust if it's 306, 497 then in qabove GuiCreate put in 306-6=300, 497-29=468

    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
    $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
    $hOperationsStatus = _GUICtrlEdit_Create($hWndInstructions, $sStatus, 10, 330, 280, 50)
    ;Pause("$hOperationsStatus = '" & $hOperationsStatus & "'")

    ;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/
    $idOperations_Button_Window = GUICtrlCreateButton("Adjust Window" & @CRLF & "Size/Position", 8, 386, 139, 35, 0x2000)  ;create window button ,0x2000=multi-line
    $idOperations_Button_Control = GUICtrlCreateButton("Adjust Control" & @CRLF & "Size/Position", 152, 386, 139, 35, 0x2000)  ;create control button ,0x2000=multi-line
    $idOperations_Button_StopAdjust = GUICtrlCreateButton("Stop Adjusting" & @CRLF & "Current Selection", 8, 424, 139, 35, 0x2000)  ;create window button ,0x2000=multi-line
    $idOperations_Button_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
    ;Pause("Instructions window should be visible.")

    ControlSetText("", "", $hOperationsStatus, $sStatus)    ;show status
    ;Pause("Status should be updated.")

    $g_tStruct = DllStructCreate($tagPOINT) ; Create a structure that defines the point to be checked.


    _While1()    ;enter our message loop
    ;Pause("Back from_While1(")

    ;clean up - these are taken care of in Case $GUI_EVENT_CLOSE

    Return (0)   ;to main calling program

EndFunc   ;==>_WindowControlOperationsContinue


Func _GetWindowHandle()        ;at mouse x,y location
    Local Static $hFoundWnd
    Local $aMousePos[2], $aPrevMousePos[2]
    If $sAdjusting <> 'Window' Then Return ($hFoundWnd)

    Do    ;get Main Window Handle
        $aMousePos = MouseGetPos()    ;get new mouse postion
        If $aPrevMousePos[0] <> $aMousePos[0] Or $aPrevMousePos[1] <> $aMousePos[1] Then ;the mouse has moved so repaint ToolTip
            ;code from Get Handle below mouse _WinAPI_WindowFromPoint v1f.au3
            DllStructSetData($g_tStruct, "x", $aMousePos[0]) ;Update the X and Y elements with the X and Y co-ordinates of the mouse.
            DllStructSetData($g_tStruct, "y", $aMousePos[1])
            MouseMove($aMousePos[0], $aMousePos[1]) ;move mouse to where it's pointing so we don't get messed up
            $hFoundWnd = _WinAPI_WindowFromPoint($g_tStruct) ; Retrieve the window handle.
            ;$hOperationsControlId = _WinAPI_GetDlgCtrlID($hWnd)    ;get Control ID (using Control Handle)
            ;only repaint if mouse moved
            $aPrevMousePos = $aMousePos    ;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 = " & $hFoundWnd)
        EndIf
        __CheckGuiMsg()
    Until ((_IsPressed("10", $hDLL) = 1) And (_IsPressed("01", $hDLL) = 1)) Or $sAdjusting <> 'Window'   ;Shift+LeftClick ;10 SHIFT key, ;01 Left mouse button
    ToolTip("")        ;turn it off
    Return ($hFoundWnd)
EndFunc   ;==>_GetWindowHandle


Func _GetControlHandle()        ;at mouse x,y location
    Local $aMousePos[2], $aPrevMousePos[2]
    Local Static $hControl
    If $sAdjusting <> 'Control' Then Return ($hControl)
    ;$hControl, $hOperationsControlId   ;declared Global above
    Do    ;get Control handle
        ;code from Get Handle below mouse _WinAPI_WindowFromPoint v1f.au3
        $aMousePos = MouseGetPos()
        If $aMousePos[0] <> $aPrevMousePos[0] Or $aMousePos[1] <> $aPrevMousePos[1] Then
            DllStructSetData($g_tStruct, "x", $aMousePos[0]) ;Update the X and Y elements with the X and Y co-ordinates of the mouse.
            DllStructSetData($g_tStruct, "y", $aMousePos[1])
            MouseMove($aMousePos[0], $aMousePos[1]) ;move mouse to where it's pointing so we don't get messed up
            $hControl = _WinAPI_WindowFromPoint($g_tStruct) ; Retrieve the window handle.
            $hOperationsControlId = _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) = " & $hOperationsControlId)
            $aPrevMousePos = $aMousePos
        EndIf
        __CheckGuiMsg()
    Until ((_IsPressed("10", $hDLL) = 1) And (_IsPressed("01", $hDLL) = 1)) Or $sAdjusting <> 'Control'   ;Shift+LeftClick ;10 SHIFT key, ;01 Left mouse button
    ToolTip("")        ;turn it off
    Return ($hControl)
EndFunc   ;==>_GetControlHandle

Func _While1()
    ;$hGUI, $hControl, $hOperationsControlId, $iLeft, $iTop, $iWidth, $iHeight, $hOperationsStatus) ;arguments are all Global
    Local $mposorig = MouseGetPos()    ;get orignal mouse postion
    Local $mposnew
    ;remember these are relative to its *WINDOW*

    ; Local $hGUI, $hGUIOriginalText, $hControl, $sStatus ;, $nMsg, $sToolTipText, $sWindowControl
    ;Global $aWindowControlLog[1][3] = [ ["Window/Control", "Title", "Left, Top, Width, Height"] ]  ;element [0] [Row][Column]

;~  Pause("In: Func _While1()" & @CRLF & _
;~      "$hGUI = '" & $hGUI & "'" & @CRLF & _
;~      "$hControl = '" & $hControl & "'" & @CRLF & _
;~      "$hOperationsControlId = '" & $hOperationsControlId & "'" & @CRLF & _
;~      "$iLeft = '" & $iLeft & "'" & @CRLF & _
;~      "$iTop = '" & $iTop & "'" & @CRLF & _
;~      "$iWidth = '" & $iWidth & "'" & @CRLF & _
;~      "$iHeight = '" & $iHeight & "'" & @CRLF & _
;~      "$hOperationsStatus = '" & $hOperationsStatus & "'" & @CRLF & _
;~      "relative to its *WINDOW*")

    Local Static $sPreviousStatus = ''

    While 1 ; Sleep isn't needed in this loop since GUIGetMsg in __CheckGuiMsg() will handle that
;~      If (_IsPressed("11",$hDLL) = 1) Then Pause("CTRL pressed.")
        ;yes you can press multiple keys at a time as this logic goes through all Ifs sequentially
        If $sAdjusting <> "Stopped" Then
            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
        EndIf

        If __CheckGuiMsg() == -1 Then ExitLoop

        ;This code is executed every time in While 1 loop

        ;only repaint tooltip if position has moved - we also do this in Func _MoveIt()
        ;And we have a button pressed
        If $sAdjusting = "Window" Or $sAdjusting = "Control" Or $sAdjusting = "Stopped" Then
            $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

                If $sAdjusting = "Window" Then    ;get window status
                    $aWinPos = WinGetPos($While1_hGui)    ;$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" & @CRLF & _
                            " width and height of Window." & @CRLF & _
                            "Holding down Ctrl will move faster." & @CRLF & _
                            "Currently:" & @CRLF & _
                            $While1_sStatus)

                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($While1_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("Use arrow keys to move " & $sAdjusting & "." & @CRLF & _
                            "Use SHIFT + arrow keys to change" & @CRLF & _
                            " width and height of " & $sAdjusting & "." & @CRLF & _
                            "Holding down Ctrl will move faster." & @CRLF & _
                            "Currently:" & @CRLF & _
                            $While1_sStatus)
                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

                $While1_sStatus = "$iLeft, $iTop, $iWidth, $iHeight" & @CRLF & $iLeft & ", " & $iTop & ", " & $iWidth & ", " & $iHeight
                If $sPreviousStatus <> $While1_sStatus Then
                    ControlSetText($hOperationsStatus, "", "", $While1_sStatus)    ;show status - use handle to directly address it
                    $sPreviousStatus = $While1_sStatus
                EndIf

            EndIf    ;if mouse moved
        EndIf
    WEnd    ;While 1


    Sleep(100)

EndFunc   ;==>_While1


Func __CheckGuiMsg()
    Local Static $sPreviousStatus = '', $sWndOriginalTitle = ''
    Local $aMousePos[2], $aPrevMousePos[2]
    Local $nMsg

    ;look for button presses
    $nMsg = GUIGetMsg()
    Switch $nMsg            ;Check for GUI events
        Case $GUI_EVENT_NONE Or 0         ; No messages :(
            Return $nMsg
        Case $GUI_EVENT_CLOSE            ;the GUI is closed red [X] is clicked
            ;If $debug > 0 Then Pause("In: Case $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($While1_hGui, "", $sWndOriginalTitle)                ;signify in window operations by changing title text back to original
            Opt("MouseCoordMode", $iOriginalMouseCoordMode)                ;return to original mode
            MsgBox(262144, "INFO", "Press Alt+W to activate again.")
            Return SetError(0, 0, -1)         ;to Func _WindowControlOperationsContinue(), -1 to send a signal back to exit the While1 func


        Case $idOperations_Button_Window            ;let's go adjust size/position of a window
            $sAdjusting = "Window"            ;other option is "Control"

            ;try and indicate active button ;don't use these as causes rounded control ;error at some low level in AutoIt
            ;GUICtrlSetColor($idOperations_Button_Window, 0x00ff00)     ;set text color (RGB) to indicate active
            ;GUICtrlSetBkColor($idOperations_Button_Window, 0x0f0f00)   ;change the color (RGB) of the button background to show mode in
            ;Bolding works and does *not* round the control
            GUICtrlSetFont($idOperations_Button_Control, Default, Default, Default)            ;set Control button to normal text
            GUICtrlSetFont($idOperations_Button_Window, Default, 700, 2)            ;Bold and italic Window button ;FW_BOLD = 700, $GUI_FONTITALIC (2) = Italic

            ;pop up initial tooltip
            $aMousePos = MouseGetPos()
            If $aMousePos[0] <> $aPrevMousePos[0] Or $aMousePos[1] <> $aPrevMousePos[1] Then
                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 = " & $While1_hGui)
                $aPrevMousePos = $aMousePos
            EndIf

            $While1_hGui = _GetWindowHandle()                ;at mouse x,y location
            If $sAdjusting <> "Window" Then Return $nMsg    ; Break if we had exited from the function because our 'Adjusting' changed
            ConsoleWrite('$While1_hGui: ' & $While1_hGui & ', WinGetTitle($While1_hGui): ' & WinGetTitle($While1_hGui) & @CRLF)
            $sWndOriginalTitle = WinGetTitle($While1_hGui)             ;get original window title text
            ;Pause("$sWndOriginalTitle = '" & $sWndOriginalTitle & "'")
            If StringInStr($sWndOriginalTitle, '--> Window Handle = ') = 0 Then
                WinSetTitle($While1_hGui, "", $sWndOriginalTitle & "   --> Window Handle = '" & $While1_hGui & "'")            ;show changing title text
            EndIf
            ;$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]

            $hOperationsAdjusting = $While1_hGui                ;set $hOperationsAdjusting as used in common movement routines


        Case $idOperations_Button_Control            ;let's go adjust size/position of a control
            $sAdjusting = "Control"            ;other option is "Window"

            GUICtrlSetFont($idOperations_Button_Window, Default, Default, Default)            ;set Window button to normal text
            GUICtrlSetFont($idOperations_Button_Control, Default, 700, 2)            ;Bold and italic Control button ;$FW_BOLD = 700, $GUI_FONTITALIC (2) = Italic

            $While1_hControl = _GetControlHandle()                ;at mouse x,y location
            If $sAdjusting <> "Control" Then Return $nMsg      ; Break if we had exited from the function because our 'Adjusting' changed
            ;_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($While1_hGui, "", $While1_hControl)

            $hOperationsAdjusting = $While1_hControl                ;set $hOperationsAdjusting as used in common movement routines


        Case $idOperations_Button_StopAdjust            ;turn off adjusting
            ;grab the curret asjust 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 $While1_sStatus = "$iLeft, $iTop, $iWidth, $iHeight" &@CRLF& $iLeft &", "& $iTop  &", "& $iWidth &", "& $iHeight
            ;So for status need to keep just stuff after @CRLF
            Local $iTemp = StringInStr($While1_sStatus, @CRLF)                ;points to start of @CRLF
            Local $sTemp = StringMid($While1_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] = $sWndOriginalTitle            ;second column
                WinSetTitle($While1_hGui, '', $sWndOriginalTitle) ; Reset the window title
            EndIf
            If $sAdjusting = "Control" Then $aWindowControlLog[UBound($aWindowControlLog) - 1][1] = $sControlOrigText            ;second column
            ;$aWindowControlLog[UBound($aWindowControlLog) - 1][2] = $While1_sStatus    ;third column
            $aWindowControlLog[UBound($aWindowControlLog) - 1][2] = $sTemp            ;third column

            GUICtrlSetFont($idOperations_Button_Window, Default, Default, Default)                ;set Window button to normal text
            GUICtrlSetFont($idOperations_Button_Control, Default, Default, Default)            ;set Control button to normal text
            $sAdjusting = "Stopped"
            $aMousePos = MouseGetPos()
            If $aMousePos[0] <> $aPrevMousePos[0] Or $aMousePos[1] <> $aPrevMousePos[1] Then
                ToolTip("Click a button when you are ready.")            ;show the tooltip
                $aPrevMousePos = $aMousePos
            EndIf

            ;_DebugArrayDisplay($aWindowControlLog, "$aWindowControlLog")


        Case $idOperations_Button_List
            _DebugArrayDisplay($aWindowControlLog, "$aWindowControlLog")


        Case Else
            ;do nothing
    EndSwitch            ;End running through GUI events.

    Return $nMsg
EndFunc   ;==>__CheckGuiMsg


Func _Left()
    ;Pause("25 LEFT ARROW key") ;25 LEFT ARROW key
    $iLeft = $iLeft - 1
    _MoveIt()
EndFunc   ;==>_Left

Func _Right()
    ;Pause("27 RIGHT ARROW key")    ;27 RIGHT ARROW key
    $iLeft = $iLeft + 1
    _MoveIt()
EndFunc   ;==>_Right

Func _Up()
    ;Pause("26 UP ARROW key")   ;26 UP ARROW key
    $iTop = $iTop - 1
    _MoveIt()
EndFunc   ;==>_Up

Func _Down()
    ;Pause("28 DOWN ARROW key") ;28 DOWN ARROW key
    $iTop = $iTop + 1
    _MoveIt()
EndFunc   ;==>_Down


Func _Narrower()
    $iWidth = $iWidth - 1
    _MoveIt()
EndFunc   ;==>_Narrower

Func _Wider()
    $iWidth = $iWidth + 1
    _MoveIt()
EndFunc   ;==>_Wider

Func _Taller()
    $iHeight = $iHeight + 1
    _MoveIt()
EndFunc   ;==>_Taller

Func _Shorter()
    $iHeight = $iHeight - 1
    _MoveIt()
EndFunc   ;==>_Shorter


Func _MoveIt()
;~  Pause("In: Func _MoveIt($hGUI, $hControl, $hOperationsControlId, $iLeft, $iTop, $iWidth, $iHeight, $cIDStatus)" & @CRLF & _
;~  "$hGUI = '" & $hGUI & "'" & @CRLF & _
;~  "$hControl = '" & $hControl & "'" & @CRLF & _
;~  "$hOperationsControlId = '" & $hOperationsControlId & "'" & @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($hOperationsStatus, "", "", $sStatus)        ;show status - use handle to directly address it

    Local $hX
    Local $sToolTipText

    ;Are we adjusting a Window or Control?
    If $sAdjusting = "Window" Then
        ;get the current position/size of the window
        Local $aWinPos = WinGetPos($hWndInstructions)    ;$aArray[0] = X position, $aArray[1] = Y position, $aArray[2] = Width, $aArray[3] = Height

        $hX = WinMove($hOperationsAdjusting, "", $iLeft, $iTop, $iWidth, $iHeight)
        ;If $hX = 0 Then Pause("WinMove window was NOT found.")
        ;If $hX = $hOperationsAdjusting Then Pause("WinMove window WAS found.")

        $sToolTipText = "Use arrow keys to move the window." & @CRLF & _
                "Use SHIFT + arrow keys to change" & @CRLF & _
                " width and height of the window." & @CRLF & _
                "Holding down Ctrl will move faster." & @CRLF & _
                "Currently:" & @CRLF & _
                $sStatus
        ;don't stuff anything in the title.  Let user get parameters from status.
        ToolTip($sToolTipText)        ;show the tooltip
    EndIf

    ;again separate If statements so we can add easily
    If $sAdjusting = "Control" Then
        ;adjust a control ;v2nd
        ControlMove($hOperationsAdjusting, "", "", $iLeft, $iTop, $iWidth, $iHeight)        ;move the control
        ;set up the tooltip text
        $sToolTipText = "Use arrow keys to move control." & @CRLF & _
                "Use SHIFT + arrow keys to change" & @CRLF & _
                " width and height of control." & @CRLF & _
                "Holding down Ctrl will move faster." & @CRLF & _
                "Currently:" & @CRLF & _
                $sStatus
        ToolTip($sToolTipText)        ;show the tooltip
    EndIf

    ;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   ;==>_MoveIt


Func Pause($text = "")
    ;__scrolltext("Debug: Paused " & $text & @CRLF)
    MsgBox(262144, "DEBUG", "Paused: " & $text)
EndFunc   ;==>Pause

 

Edit: Also I recommend that you check out this page: https://www.autoitscript.com/wiki/Best_coding_practices

It has some information on naming things, which I kinda half follow, but I like it in theory :)

Edited by mistersquirrle
Added more

We ought not to misbehave, but we should look as though we could.

Link to comment
Share on other sites

@mistersquirrle I like the changes.  Well done. Thanks.  I'm still looking at the Local Static usage.  Another question - I use #AutoIt3Wrapper_run_debug_mode=Y to debug the main program.  Any way to have the debug trace into the local #include file?  Putting #AutoIt3Wrapper_run_debug_mode=Y in the #included file does not seem to do it.

Link to comment
Share on other sites

@Jos might be able to answer that, I however wasn't aware of #AutoIt3Wrapper_run_debug_mode in general (or forgot about it), so no idea about tracing an include file.

 

Any specific questions about the Local Static? Basically, normal Local variables in functions only exist while the function is... functioning. Once the function is done, the variable is removed along with its data. Static means that it and its value is not removed when the function is done. It remains only accessible to the function it was declared in, however. But this way you could keep count of something, or keep a persistent value. Here's a way that I occasionally store/access variables or options in some scripts:

Func __timeSinceLast($vSet = False)
    Local Static $hTimeSinceLast

    If Not ($vSet == False) Then $hTimeSinceLast = TimerInit()

    Return TimerDiff($hTimeSinceLast)
EndFunc   ;==>__timeSinceLast

Func __CurrentCount($vSet = False)
    Local Static $iCount = 0

    If Not ($vSet == False) Then
        $iCount = $vSet
    EndIf

    Return $iCount
EndFunc   ;==>__CurrentCount

In those examples there's really not much difference in doing it like this versus just having a Local variable in the main script body, or if you want it available outside of the file, making it a Global variable. I see this approach as just a Global variable alternative, I can just call the function instead. 

We ought not to misbehave, but we should look as though we could.

Link to comment
Share on other sites

@ahha Take a look in the Tools-->Compile-->Au3Stripper

/mo : Just merges the Include files into the source and strips the Comments.
      This is similar to aut2exe and helps finding the errorline.

if this help ?

 

Edited by ioa747

I know that I know nothing

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...