Sign in to follow this  
Followers 0
lbsl

Tapping into the AutoIT3 event trapping handler.

4 posts in this topic

Hi folks,

I've been happily abusing this forum resources (and many others as well) for over three years now to get stuff done in AutoIT3.

I'm currently stuck at a point where i need to fake some sort of multithreading.

I know AutoIT3 does not and will not support it, but if there only was a good way to tap into the full event trapping cycle of the AU3 engine, i could at least add in some of the routines that need a checkup.

I figured so far that using the GuiOnEventMode and TrayOnEventMode should allow me to give me this opportunity, but unfortunately, it doesn't.

I have extended the existing Au3 examples for both options with a counter to show what i mean:

#include <GUIConstantsEx.au3>
#include <Constants.au3>
#NoTrayIcon
Global $x = 1

Example()


Func Example()
    Opt("GUICoordMode", 2)
    Opt("GUIResizeMode", 1)
    Opt("GUIOnEventMode", 1)

    Opt("TrayOnEventMode", 1)
    Opt("TrayMenuMode", 1) ; Default tray menu items (Script Paused/Exit) will not be shown.

    TrayCreateItem("Exit")
    TrayItemSetOnEvent(-1, "ExitEvent")

    TraySetOnEvent($TRAY_EVENT_PRIMARYDOUBLE, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_SECONDARYDOUBLE, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_MOUSEOVER, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_PRIMARYUP, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_SECONDARYDOWN, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_SECONDARYUP, "SpecialEvent")

    TraySetState()

    Local $WinHandle = GUICreate("Parent1")
    ConsoleWrite("WinHandle:" & Hex($WinHandle, 8) & @CRLF)
    GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents")


    GUICtrlCreateButton("OK", 10, 30, 50)
    GUICtrlSetOnEvent(-1, "OKPressed")

    GUICtrlCreateButton("Cancel", 0, -1)
    GUICtrlSetOnEvent(-1, "CancelPressed")

    GUICtrlCreateEdit("A small text box with some text in it to test the scrollbar clicking" & @CRLF & @CRLF & @CRLF & @CRLF & "and a couple of lines, click and drag the scrollbars to stop the counter", 80, 80, 180, 100)
    GUICtrlSetOnEvent(-1, "EditTouched")

    GUISetState(@SW_SHOW)


    ; Just idle around
    While 1
        Sleep(500)

        ConsoleWrite("Testing message loop:" & $x & @CRLF)
        $x += 1
    WEnd
EndFunc   ;==>Example


Func EditTouched()
    ConsoleWrite("Testing message loop:" & $x & @CRLF)
    $x += 1
    MsgBox(0, "OK Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle)
EndFunc   ;==>EditTouched

Func OKPressed()
    ConsoleWrite("Testing message loop:" & $x & @CRLF)
    $x += 1
    MsgBox(0, "OK Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle)
EndFunc   ;==>OKPressed


Func CancelPressed()
    ConsoleWrite("Testing message loop:" & $x & @CRLF)
    $x += 1
    MsgBox(0, "Cancel Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle)
EndFunc   ;==>CancelPressed


Func SpecialEvents()

    ConsoleWrite("Testing message loop:" & $x & @CRLF)
    $x += 1

    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            ConsoleWrite("Testing message loop:" & $x & @CRLF)
            $x += 1
            MsgBox(0, "Close Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)
            Exit

        Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
            ConsoleWrite("Testing message loop:" & $x & @CRLF)
            $x += 1
            MsgBox(0, "Window Minimized", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)

        Case @GUI_CtrlId = $GUI_EVENT_RESTORE
            ConsoleWrite("Testing message loop:" & $x & @CRLF)
            $x += 1
            MsgBox(0, "Window Restored", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)

    EndSelect

EndFunc   ;==>SpecialEvents


Func SpecialEvent()
    Select
        Case @TRAY_ID = $TRAY_EVENT_PRIMARYDOUBLE
            MsgBox(64, "SpecialEvent-Info", "Primary mouse button double clicked.")
        Case @TRAY_ID = $TRAY_EVENT_SECONDARYUP
            MsgBox(64, "SpecialEvent-Info", "Secondary mouse button clicked.")
    EndSelect
EndFunc   ;==>SpecialEvent


Func ExitEvent()
    Exit
EndFunc   ;==>ExitEvent

The counter keeps updating the console output, until you hover above a Tray context menu or you click and hold down any of the scrollbars.

The counter that i am running in the background here is in my real life a network process that needs to clear a message buffer from time to time.
I have two applications in Autoit3 running, one server that is doing all the network activity and no GUI related stuff at all and i attach a client to it that has to exchange messages with the server to at least be able to command it up to some level.

However whenever that message buffer of this client stalls, the server that is broadcasting the ACK messages will also stall eventually because his buffers do not get cleared.

I have considered using an Sqlite database in WAL mode to exchange messages between the two apps and even if that can work mighty fast, it looks clumsy, but it ensures me that my client app will not crash on partial messages or miss out on messages.

But if anyone can guide me to a trick where i could at least have all functions called in a processing loop without the AutoIT engine being able to stall that process, in other words:how can i keep that counter "running" at all cost?

Thanks in advance!

Share this post


Link to post
Share on other sites



Might want to have a look at the Mailslot UDF by Trancexx, I have used it

with much success for inter-script communication, even across a network.

Share this post


Link to post
Share on other sites

lbsl, A trick you can use here is to install a hook procedure to catch windows messages. Since windows messages are generated all the time, this will give you an always running loop.

Advantages of this solution are:

  • Very easy to implement and a generally applicable solution.
  • Low impact on your script: No additional globals, only a few lines of extra code.
  • No measurable impact on performance: These functions are small efficient functions.
In this example I have added 9 lines to your original code (comment and blank lines not included):

#include <GUIConstantsEx.au3>
#include <Constants.au3>
#include <WinAPI.au3>
#NoTrayIcon
Global $x = 1

Example()


Func Example()
    Opt("GUICoordMode", 2)
    Opt("GUIResizeMode", 1)
    Opt("GUIOnEventMode", 1)

    Opt("TrayOnEventMode", 1)
    Opt("TrayMenuMode", 1) ; Default tray menu items (Script Paused/Exit) will not be shown.

    TrayCreateItem("Exit")
    TrayItemSetOnEvent(-1, "ExitEvent")

    TraySetOnEvent($TRAY_EVENT_PRIMARYDOUBLE, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_SECONDARYDOUBLE, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_MOUSEOVER, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_PRIMARYUP, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_SECONDARYDOWN, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_SECONDARYUP, "SpecialEvent")

    TraySetState()

    Local $WinHandle = GUICreate("Parent1")
    ConsoleWrite("WinHandle:" & Hex($WinHandle, 8) & @CRLF)
    GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents")


    GUICtrlCreateButton("OK", 10, 30, 50)
    GUICtrlSetOnEvent(-1, "OKPressed")

    GUICtrlCreateButton("Cancel", 0, -1)
    GUICtrlSetOnEvent(-1, "CancelPressed")

    GUICtrlCreateEdit("A small text box with some text in it to test the scrollbar clicking" & @CRLF & @CRLF & @CRLF & @CRLF & "and a couple of lines, click and drag the scrollbars to stop the counter", 80, 80, 180, 100)
    GUICtrlSetOnEvent(-1, "EditTouched")

    ; Catch window messages
    Local $hMessageHandler = DllCallbackRegister( "MessageHandler", "long", "int;wparam;lparam" )
    Local $hMessageHook = _WinAPI_SetWindowsHookEx( $WH_GETMESSAGE, DllCallbackGetPtr( $hMessageHandler ), 0, _WinAPI_GetCurrentThreadId() )

    GUISetState(@SW_SHOW)


    ; Just idle around
    While 1
        Sleep(500)

        ConsoleWrite("Testing message loop:" & $x & @CRLF)
        $x += 1
    WEnd

    _WinAPI_UnhookWindowsHookEx( $hMessageHook )
EndFunc   ;==>Example


Func EditTouched()
    ConsoleWrite("Testing message loop:" & $x & @CRLF)
    $x += 1
    MsgBox(0, "OK Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle)
EndFunc   ;==>EditTouched

Func OKPressed()
    ConsoleWrite("Testing message loop:" & $x & @CRLF)
    $x += 1
    MsgBox(0, "OK Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle)
EndFunc   ;==>OKPressed


Func CancelPressed()
    ConsoleWrite("Testing message loop:" & $x & @CRLF)
    $x += 1
    MsgBox(0, "Cancel Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle)
EndFunc   ;==>CancelPressed


Func SpecialEvents()

    ConsoleWrite("Testing message loop:" & $x & @CRLF)
    $x += 1

    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            ConsoleWrite("Testing message loop:" & $x & @CRLF)
            $x += 1
            MsgBox(0, "Close Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)
            Exit

        Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
            ConsoleWrite("Testing message loop:" & $x & @CRLF)
            $x += 1
            MsgBox(0, "Window Minimized", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)

        Case @GUI_CtrlId = $GUI_EVENT_RESTORE
            ConsoleWrite("Testing message loop:" & $x & @CRLF)
            $x += 1
            MsgBox(0, "Window Restored", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)

    EndSelect

EndFunc   ;==>SpecialEvents


Func SpecialEvent()
    Select
        Case @TRAY_ID = $TRAY_EVENT_PRIMARYDOUBLE
            MsgBox(64, "SpecialEvent-Info", "Primary mouse button double clicked.")
        Case @TRAY_ID = $TRAY_EVENT_SECONDARYUP
            MsgBox(64, "SpecialEvent-Info", "Secondary mouse button clicked.")
    EndSelect
EndFunc   ;==>SpecialEvent


Func ExitEvent()
    Exit
EndFunc   ;==>ExitEvent


Func MessageHandler( $nCode, $wParam, $lParam )
    Local Static $y = 1
    ConsoleWrite("Testing hook message handler: " & $y & @CRLF)
    $y += 1
EndFunc

You can use a timer in the message handler function to execute code at specified intervals.

Share this post


Link to post
Share on other sites

Might want to have a look at the Mailslot UDF by Trancexx, I have used it

with much success for inter-script communication, even across a network.

 

Thanks dmob,

It sounds like a more graceful idea than using a database file to frequently poll for messages.

The GUI client and the proxy-server however will not be used on different computers, so i don't necessarily need the network connection for that.

But something i will keep in mind in case i have no other option.

 

lbsl, A trick you can use here is to install a hook procedure to catch windows messages. Since windows messages are generated all the time, this will give you an always running loop.

Advantages of this solution are:

  • Very easy to implement and a generally applicable solution.
  • Low impact on your script: No additional globals, only a few lines of extra code.
  • No measurable impact on performance: These functions are small efficient functions.
In this example I have added 9 lines to your original code (comment and blank lines not included):

#include <GUIConstantsEx.au3>
#include <Constants.au3>
#include <WinAPI.au3>
#NoTrayIcon
Global $x = 1

Example()


Func Example()
    Opt("GUICoordMode", 2)
    Opt("GUIResizeMode", 1)
    Opt("GUIOnEventMode", 1)

    Opt("TrayOnEventMode", 1)
    Opt("TrayMenuMode", 1) ; Default tray menu items (Script Paused/Exit) will not be shown.

    TrayCreateItem("Exit")
    TrayItemSetOnEvent(-1, "ExitEvent")

    TraySetOnEvent($TRAY_EVENT_PRIMARYDOUBLE, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_SECONDARYDOUBLE, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_MOUSEOVER, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_PRIMARYUP, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_SECONDARYDOWN, "SpecialEvent")
    TraySetOnEvent($TRAY_EVENT_SECONDARYUP, "SpecialEvent")

    TraySetState()

    Local $WinHandle = GUICreate("Parent1")
    ConsoleWrite("WinHandle:" & Hex($WinHandle, 8) & @CRLF)
    GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "SpecialEvents")
    GUISetOnEvent($GUI_EVENT_RESTORE, "SpecialEvents")


    GUICtrlCreateButton("OK", 10, 30, 50)
    GUICtrlSetOnEvent(-1, "OKPressed")

    GUICtrlCreateButton("Cancel", 0, -1)
    GUICtrlSetOnEvent(-1, "CancelPressed")

    GUICtrlCreateEdit("A small text box with some text in it to test the scrollbar clicking" & @CRLF & @CRLF & @CRLF & @CRLF & "and a couple of lines, click and drag the scrollbars to stop the counter", 80, 80, 180, 100)
    GUICtrlSetOnEvent(-1, "EditTouched")

    ; Catch window messages
    Local $hMessageHandler = DllCallbackRegister( "MessageHandler", "long", "int;wparam;lparam" )
    Local $hMessageHook = _WinAPI_SetWindowsHookEx( $WH_GETMESSAGE, DllCallbackGetPtr( $hMessageHandler ), 0, _WinAPI_GetCurrentThreadId() )

    GUISetState(@SW_SHOW)


    ; Just idle around
    While 1
        Sleep(500)

        ConsoleWrite("Testing message loop:" & $x & @CRLF)
        $x += 1
    WEnd

    _WinAPI_UnhookWindowsHookEx( $hMessageHook )
EndFunc   ;==>Example


Func EditTouched()
    ConsoleWrite("Testing message loop:" & $x & @CRLF)
    $x += 1
    MsgBox(0, "OK Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle)
EndFunc   ;==>EditTouched

Func OKPressed()
    ConsoleWrite("Testing message loop:" & $x & @CRLF)
    $x += 1
    MsgBox(0, "OK Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle)
EndFunc   ;==>OKPressed


Func CancelPressed()
    ConsoleWrite("Testing message loop:" & $x & @CRLF)
    $x += 1
    MsgBox(0, "Cancel Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle)
EndFunc   ;==>CancelPressed


Func SpecialEvents()

    ConsoleWrite("Testing message loop:" & $x & @CRLF)
    $x += 1

    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            ConsoleWrite("Testing message loop:" & $x & @CRLF)
            $x += 1
            MsgBox(0, "Close Pressed", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)
            Exit

        Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
            ConsoleWrite("Testing message loop:" & $x & @CRLF)
            $x += 1
            MsgBox(0, "Window Minimized", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)

        Case @GUI_CtrlId = $GUI_EVENT_RESTORE
            ConsoleWrite("Testing message loop:" & $x & @CRLF)
            $x += 1
            MsgBox(0, "Window Restored", "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle)

    EndSelect

EndFunc   ;==>SpecialEvents


Func SpecialEvent()
    Select
        Case @TRAY_ID = $TRAY_EVENT_PRIMARYDOUBLE
            MsgBox(64, "SpecialEvent-Info", "Primary mouse button double clicked.")
        Case @TRAY_ID = $TRAY_EVENT_SECONDARYUP
            MsgBox(64, "SpecialEvent-Info", "Secondary mouse button clicked.")
    EndSelect
EndFunc   ;==>SpecialEvent


Func ExitEvent()
    Exit
EndFunc   ;==>ExitEvent


Func MessageHandler( $nCode, $wParam, $lParam )
    Local Static $y = 1
    ConsoleWrite("Testing hook message handler: " & $y & @CRLF)
    $y += 1
EndFunc
You can use a timer in the message handler function to execute code at specified intervals.

 

 

Thanks Lars,

This indeed works fine. It even looks like i can drop the whole GuiEventMode and TrayEventMode idea with this. (Which saves me a lot of time because i haven't converted any of the dialog message handlers yet to work with the GuiEventMode)

I owe you a big one!

Share this post


Link to post
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
Sign in to follow this  
Followers 0

  • Similar Content

    • JakeJohnson74
      By JakeJohnson74
      Hey Guys, this is somewhat related to another post in here but my specific question was "answered" and so I thought I would make a new post that is referencing the same code, with slightly different issues. 
      Problem 1
      Setup: I am using a label docked to the main GUI to set the size of a child GUI. 
      Issue: When I slowly drag the borders, I can see my green label kind of peeking out from behind the GUI, not a huge problem I guess. If I drag the border very quicky I can get the offset to be really big (200-300 pixels)
      ** Edit - I just realized that the child of the child GUI actually does not display this same "lag" or difference in sizing. hmmmm
      Problem 2
      *discaimer! - Melba if you see this, I know you have Aero disabled so I understand if you don't want anything to do with this one! haha
      Setup: Using windows message WM_WINDOWPOSCHANGING. This should give me a message "While" the window is changing. There is a WM_WINDOWPOSCHANGED, which should fire after the change happens. 
      Issue: Upon a normal maximize/restore methods (double clicking title bar, or using the buttons) the window behaves. Upon an Aero Snap maximize/restore the update only happens AFTER I let go of my left click. So while dragging the window down from its maximized state the child GUI's remain maximized until I let go of the left click  mouse button and it resizes. I really want this to resize the second it unsnaps from the maximized state. 
      **Edit - This is due to the way I am handling the flags parameter of the WINDOWPOS Struct. I'm masking only using 1 of the members and it only sees that once the LMB is released. So I am basically misusing the message because im not very familiar with it I have experimented with bitOR(member1, member2, member3) because im thinking SWP_FRAMECHANGED is not the only member I should be masking against "flags" (although it works somewhat)
      Here is my code. 
      #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> $iGuiWidth = 660 $iGUIHeight = 320 $DividerOffset = 244 Global $aGUIPos[6] Global $hgui, $hgui1, $hguiInner1, $cLabel_1, $cLabel_2, $cLabel_3, $iOFfset_X1, $iOFfset_Y1 Global $bSysMsg = False GUI() GUIRegisterMsg($WM_SIZE, "_WM_SIZE") GUIRegisterMsg($WM_WINDOWPOSCHANGING, "_WM_WINDOWPOSCHANGING") Func GUI() $hgui = GUICreate("test", $iGuiWidth, $iGUIHeight, -1, -1, BitOR($WS_OVERLAPPEDWINDOW, $WS_POPUP)) GUISetBkColor(0x666666) $cLabel_1 = GUICtrlCreateLabel("I am the label", 4, 65, $iGuiWidth - 7, 250) GUICtrlSetBkColor(-1, 0x00FF00) GUICtrlSetResizing(-1, BitOR($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKBOTTOM, $GUI_DOCKWIDTH, $GUI_DOCKRIGHT)) GUICtrlSetState(-1, $GUI_DISABLE) GUISetState() $hgui1 = GUICreate("", $iGuiWidth - 7, $iGUIHeight - 70, -1, 60, $WS_POPUP, $WS_EX_MDICHILD, $hgui) GUISetBkColor(0x888888) GUISetState() $Divider = GUICtrlCreateLabel('', $DividerOffset, 0, 5, 250) GUICtrlSetBkColor(-1, 0xFF0000) GUICtrlSetResizing(-1, BitOR($GUI_DOCKWIDTH, $GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKBOTTOM)) GUICtrlSetCursor(-1, 13) GUISetState() $cLabel_2 = GUICtrlCreateLabel("I am the label", 249, 25, 403, 225) GUICtrlSetBkColor(-1, 0x0000FF) GUICtrlSetResizing(-1, BitOR($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKBOTTOM, $GUI_DOCKWIDTH, $GUI_DOCKRIGHT)) GUICtrlSetState(-1, $GUI_DISABLE) GUISetState() $hGuiInner1 = GUICreate("", 403, 225, 252,28, $WS_POPUP, $WS_EX_MDICHILD, $hgui1) GUISetBkColor(0x555555) GUISetState() _GetGuiPos($hgui,0,1) _GetGuiPos($hgui1,2,3) ;~ _GetGuiPos(hgui2,3,4) For $i = 0 to 5 ConsoleWrite("$aguipos[" & $i & "]:=" & $aguipos[$i] & @LF) Next EndFunc ;==>GUI While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Quit() EndSwitch If $bSysMsg Then $bSysMsg = False _Resize_GUIs() EndIf WEnd Func Quit() Exit EndFunc ;==>Quit Func _Resize_GUIs() ;GUI1 $aWin1 = WinGetPos($hgui) $aRet1 = ControlGetPos($hgui, "", $cLabel_1) WinMove($hgui1, "", $aWin1[0] + $aGUIPos[0] + $aRet1[0], $aWin1[1] + $aGUIPos[1] + $aRet1[1], $aRet1[2], $aRet1[3]) $aWin2 = WinGetPos($hgui1) $aRet2 = ControlGetPos($hgui1, "", $cLabel_2) WinMove($hguiInner1, "", $aWin2[0] + $aGUIPos[2] + $aRet2[0], $aWin2[1] + $aGUIPos[3] + $aRet2[1], $aRet2[2], $aRet2[3]) ;~ $aWin3 = WinGetPos($hgui) ;~ $aRet3 = ControlGetPos($hgui, "", $cLabel_3) ;~ WinMove($hgui1, "", $aWin3[0] + $aGUIPos[4] + $aRet3[0], $aWin3[1] + $aGUIPos[5] + $aRet3[1], $aRet3[2], $aRet3[3]) EndFunc ;==>_Resize_GUIs func _WM_WINDOWPOSCHANGING($hWnd, $msg, $wParam, $lParam) Local $winpos_Struct = DllStructCreate("hwnd hwnd;hwnd hwndInsertAfter;int x;int y;int cx;int cy;uint flags", $lParam) $MaximizeOrRestore = bitand(DllStructGetData($winpos_Struct, "flags"), $SWP_FRAMECHANGED) if $MaximizeOrRestore > 0 then $bSysMsg = True endif EndFunc Func _WM_SIZE($hWnd, $msg, $wParam, $lParam) _Resize_GUIs() Return $GUI_RUNDEFMSG EndFunc ;==>_WM_SIZE Func _Exit($s_Msg) MsgBox(0, "Error", $s_Msg) Exit EndFunc Func _GetGuiPos($hTargGUI,$iArrayEle1,$iArrayEle2) $aWin = WinGetPos($hTargGUI) Local $tPoint = DllStructCreate("int X;int Y") DllStructSetData($tPoint, "X", 0) DllStructSetData($tPoint, "Y", 0) _WinAPI_ClientToScreen($hTargGUI, $tPoint) $aGUIPos[$iArrayEle1] = DllStructGetData($tPoint, "X") - $aWin[0] $aGUIPos[$iArrayEle2] = DllStructGetData($tPoint, "Y") - $aWin[1] EndFunc
    • drego
      By drego
      It's been requested in the past to have multithreading to which the response was "It would take too much redesigning of Autoit" but what about Async? Multithreading and Async are two different things. This way we could put tasks in the background without having to fork processes. Right? Also better event handling would be nice rather than throwing everything in a while loop we could have some functionality like javascript which seems to be far more responsive and reliable as the more you add to your while loop the less change there is of your "event" getting caught for some reason (At least in my experience).