Jump to content

Recommended Posts

Posted (edited)

Array / object / map > not supported.

ExampleA:

#include "ProcessManager.au3"

__AutoItThread_Bootstrapper()
__ExampleA()

Func __ExampleA()
    Local $aTest1Params[2] = ["Test 1 Title", "This is the message payload!"]

    Local $hProc1 = __AutoItCreateThread("Test1", $aTest1Params)
    Local $hProc2 = __AutoItCreateThread("Test2")
    Local $hProc3 = __AutoItCreateThread("Test3", "5")

    MsgBox(0, "Main Process", "All 3 background processes have been fired off concurrently!")

    Local $sResult1 = __AutoItWaitThread($hProc1)
    Local $sResult2 = __AutoItWaitThread($hProc2)
    Local $sResult3 = __AutoItWaitThread($hProc3)

    MsgBox(0, "Main Process - Received Data", "Test1 returned:>  " & $sResult1)
    MsgBox(0, "Main Process", "All threads completed successfully.")
EndFunc

Func Test1($sTitle, $sMessage)
    Local $iResp = MsgBox(0, $sTitle, $sMessage)
    Return "Done with value: " & $iResp
EndFunc

Func Test2()
    MsgBox(0, "2", "Test 2 Executed")
EndFunc

Func Test3($iTimeout)
    MsgBox(0, "3", "Test 3 checking in with timeout: " & $iTimeout, Number($iTimeout))
EndFunc

 

ExampleB:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPIFiles.au3>
#include <WinAPIHObj.au3>
#include "ProcessManager.au3"

Global Const $sStructFormat = "int NewMsg;int ExitFlag;char Msg[512];"
Global Const $iStructSize = DllStructGetSize(DllStructCreate($sStructFormat))
Global $g_idLabel

__AutoItThread_Bootstrapper()
__ExampleB()

Func __ExampleB()
    Local $sUniqueMapName = "Local\AutoItThreadMap_" & @AutoItPID & "_" & int(TimerInit())

    Local $hSharedMapping = _WinAPI_CreateFileMapping(-1, $iStructSize, $sUniqueMapName)
    If @error Or Not $hSharedMapping Then Exit MsgBox(16, "Error", "Parent failed to create file mapping.")

    Local $pSharedAddress = _WinAPI_MapViewOfFile($hSharedMapping)
    If @error Or Not $pSharedAddress Then
        _WinAPI_CloseHandle($hSharedMapping)
        Exit MsgBox(16, "Error", "Parent failed to map view of file.")
    EndIf
    Local $tStruct2 = DllStructCreate($sStructFormat, $pSharedAddress)

    Local $hGUI = GUICreate("To-and-Forth Controller", 400, 200)
    Local $idInput = GUICtrlCreateInput("Hello Worker!", 20, 30, 360, 20)
    Local $idSend  = GUICtrlCreateButton("Send Message to Worker", 20, 70, 180, 30)
    Local $idExit  = GUICtrlCreateButton("Shutdown Worker & Exit", 210, 70, 170, 30)
    $g_idLabel = GUICtrlCreateLabel("Last Reply: None", 20, 130, 360, 40)

    GUIRegisterMsg($WM_COPYDATA, "__OnThreadReply")
    GUISetState(@SW_SHOW, $hGUI)

    Local $aWorkerArgs[2] = [String($hGUI), $sUniqueMapName]
    Local $hProc2 = __AutoItCreateThread("__Background_Message_Thread", $aWorkerArgs)
    If @error Then Exit MsgBox(16, "Error", "Failed to create background process")

    Local $sResponse = ''
    While True
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE, $idExit
                DllStructSetData($tStruct2, "ExitFlag", 1)
                $sResponse = __AutoItWaitThread($hProc2)
                ExitLoop

            Case $idSend
                Local $sTextToSend = GUICtrlRead($idInput)
                If $sTextToSend == "" Then ContinueLoop

                DllStructSetData($tStruct2, "Msg", $sTextToSend)
                DllStructSetData($tStruct2, "NewMsg", 1)
                GUICtrlSetData($g_idLabel, "Status: Message dispatched, awaiting WM_COPYDATA response...")
        EndSwitch

        Sleep(10)
    WEnd

    _WinAPI_UnmapViewOfFile($pSharedAddress)
    _WinAPI_CloseHandle($hSharedMapping)
    MsgBox(64, "Parent Process", "Worker thread exited. Return pipe string value: " & $sResponse)
EndFunc


Func __OnThreadReply($hWnd, $iMsg, $wParam, $lParam)
    Local $tCopyData = DllStructCreate("ulong_ptr dwData;dword cbData;ptr lpData", $lParam)
    Local $iBytes     = DllStructGetData($tCopyData, "cbData")
    Local $pData      = DllStructGetData($tCopyData, "lpData")

    Local $tStringBuf = DllStructCreate("wchar[" & ($iBytes / 2) & "]", $pData)
    Local $sReceivedMessage = DllStructGetData($tStringBuf, 1)

    GUICtrlSetData($g_idLabel, "Last Worker Reply: " & $sReceivedMessage)
    Return 1
EndFunc

Func __Background_Message_Thread($hNotifyWindow, $sMapName)
    Local $hWndTarget = HWnd($hNotifyWindow)

    Local $hWorkerMapping = _WinAPI_OpenFileMapping($sMapName, 0x0002)
    If @error Or Not $hWorkerMapping Then Return "Error: Worker failed to open file mapping layout."

    Local $pWorkerAddress = _WinAPI_MapViewOfFile($hWorkerMapping)
    If @error Or Not $pWorkerAddress Then
        _WinAPI_CloseHandle($hWorkerMapping)
        Return "Error: Worker failed to view memory layout mapping."
    EndIf

    Local $tLocalStruct = DllStructCreate($sStructFormat, $pWorkerAddress)
    While True
        If DllStructGetData($tLocalStruct, "ExitFlag") = 1 Then
            ExitLoop
        EndIf

        If DllStructGetData($tLocalStruct, "NewMsg") = 1 Then
            Local $sSharedText = DllStructGetData($tLocalStruct, "Msg")
            Local $sProcessedReply = "Processed: [" & $sSharedText & "] at " & @SEC & "s"

            DllStructSetData($tLocalStruct, "NewMsg", 0)
            __WM_COPYDATA_SendData($hWndTarget, $sProcessedReply)
        EndIf
        Sleep(50)
    WEnd

    _WinAPI_UnmapViewOfFile($pWorkerAddress)
    _WinAPI_CloseHandle($hWorkerMapping)

    Return '-Done ok-'
EndFunc

 

to do ConsoleWrite from Child Process....

Func __SciTE_ConsoleWrite($sText)
    Local $hSciTE = WinGetHandle("[CLASS:DirectorExtension]")
    If Not $hSciTE Then Return False

    $sText = StringReplace($sText, @CRLF, "\r\n")
    $sText = StringReplace($sText, @LF, "\n")
    $sText = StringReplace($sText, @CR, "\r")

    Local $sCommand = "output:" & $sText
    Local $iLen = StringLen($sCommand) + 1
    Local $tString = DllStructCreate("char[" & $iLen & "]")
    DllStructSetData($tString, 1, $sCommand)

    Local $tCOPYDATA = DllStructCreate("ulong_ptr dwData;dword cbData;ptr lpData")
    DllStructSetData($tCOPYDATA, "dwData", 1)
    DllStructSetData($tCOPYDATA, "cbData", $iLen)
    DllStructSetData($tCOPYDATA, "lpData", DllStructGetPtr($tString))

    Local Const $WM_COPYDATA = 0x004A
    DllCall("user32.dll", "lresult", "SendMessageA", "hwnd", $hSciTE, "uint", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA))
    Return True
EndFunc

ProcessManager.au3

Edited by jugador
Posted

With the combination of RegisterActiveObject, everything is now supported.......
https://www.autoitscript.com/forum/topic/211008-registeractiveobject/

ExampleC:

#include "ProcessManager.au3"

__AutoItThread_Bootstrapper()
_Main()

Func _Main()
    Local $hProc2 = __AutoItCreateThread("Test2")
    MsgBox(0, "Main Process", "background processes have been fired from _Main!")

    __AutoItWaitThread($hProc2)
    MsgBox(0, "Main Process", "All threads completed successfully.")
EndFunc

Func Test2()
    MsgBox(0, "2", "Test 2 Executed")
    __AutoItCreateThread("Test3")
    MsgBox(0, "Test2", "background processes have been fired from Test2!")
EndFunc

Func Test3()
    MsgBox(0, "2", "Test 3 Executed")
    __AutoItCreateThread("Test4")
    MsgBox(0, "Test3", "background processes have been fired from Test3!")
EndFunc

Func Test4()
    MsgBox(0, "2", "Test 4 Executed")
EndFunc

 

ExampleD: non-blocking ArrayDisplay

#include <Constants.au3>
#include <Array.au3>
#include "RegisterActiveObject UDF3.au3"
#include "ProcessManager.au3"

Global $g__Clsid = '{EE09B103-97E0-11CF-978F-00A02463E06F}'

__AutoItThread_Bootstrapper()
_Main()

Func _Main()
    Local $Oobj = __RegisterActiveObject(Default, $g__Clsid)
    If @error Or Not IsObj($Oobj) Then Return

    Local $aArray_1[2] = ["Item A0", "item A1"]
    $Oobj.add("ArrayA", $aArray_1)
    __AutoItCreateThread("__Array_Display_1", "ArrayA")

    Local $aArray_2 = [123, 456, 789]
    $Oobj.add("ArrayB", $aArray_2)
    __AutoItCreateThread("__Array_Display_1", "ArrayB")

    Local $aArray_3 = [[123456, 12.34, 'how are you?', -0.1234], [-100.001, 0.00009, "", 'Is it working?']]
    $Oobj.add("ArrayC", $aArray_3)
    __AutoItCreateThread("__Array_Display_1", "ArrayC")

    MsgBox(0, "Main Process", "background processes have been fired off concurrently!")
    __RevokeActiveObject()
EndFunc

Func __Array_Display_1($sName)
    Local $m_object = ObjGet("", $g__Clsid)
    _ArrayDisplay(($m_object.item($sName)))

    ;~~ Autoit bug
    ; _ArrayDisplay($m_object.item($sName))     ; <-- will not worked
    ; _ArrayDisplay(($m_object.item($sName)))   ; <-- will work
EndFunc

 

@WildByDesign if you are thinking of subclassing, that's not possible using this :P.

  • 2 weeks later...
Posted

ExampleE: DllCall

#include "ProcessManager.au3"

__AutoItThread_Bootstrapper()

_Main()
Func _Main()
    Local $hProc2 = __AutoItCreateThread("Test2")
    MsgBox(0, "Main Process", "background processes have been fired off!")

    Local $sResult2 = __AutoItWaitThread($hProc2)
    MsgBox(0, "Main Process - Received Data", "Test Result:  " & $sResult2)
EndFunc

Func Test2()
    Local $Result = DllCall("user32.dll", "int", "MessageBoxW", "hwnd", 0, "wstr", "This is a dynamic call", "wstr", "Some title", "uint", 0x44)
    Return $Result[0]
EndFunc

 

ExampleF: DllCallbackRegister

#include "ProcessManager.au3"

__AutoItThread_Bootstrapper()

_Main()
Func _Main()
    Local $hProc2 = __AutoItCreateThread("Test2")
    MsgBox(0, "Main Process", "background processes have been fired off!")

    Local $sResult2 = __AutoItWaitThread($hProc2)
    MsgBox(0, "Main Process", "Done" )
EndFunc

Func Test2()
    Local $hHandle = DllCallbackRegister("_EnumWindowsProc", "int", "hwnd;lparam")
    DllCall("user32.dll", "int", "EnumWindows", "ptr", DllCallbackGetPtr($hHandle), "lparam", 10)
    DllCallbackFree($hHandle)
EndFunc

; Callback Procedure
Func _EnumWindowsProc($hWnd, $lParam)
    ; If the Title is empty or if the window is not visible then continue enumeration.
    If WinGetTitle($hWnd) = "" Or BitAND(WinGetState($hWnd), 2) = 0 Then Return 1

    Local $iRes = MsgBox(BitOR($MB_SYSTEMMODAL, $MB_OKCANCEL), _
            WinGetTitle($hWnd), "$hWnd=" & $hWnd & @CRLF & _
            "$lParam=" & $lParam & @CRLF & _
            "$hWnd(type)=" & VarGetType($hWnd))

    If $iRes <> $IDOK Then Return 0 ; Cancel/Close button clicked, return 0 to stop enumeration.

    Return 1 ; Return 1 to continue enumeration.
EndFunc   ;==>_EnumWindowsProc

 

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
×
×
  • Create New...