jugador Posted June 8 Posted June 8 (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: expandcollapse popup#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 June 22 by jugador ioa747 and WildByDesign 1 1
WildByDesign Posted June 8 Posted June 8 This is really special. Thank you so much for sharing. I can see lots of great use cases for this.
jugador Posted June 9 Author Posted June 9 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 expandcollapse popup#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 . WildByDesign and ioa747 2
jugador Posted June 19 Author Posted June 19 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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now