j0kky Posted September 25, 2014 Share Posted September 25, 2014 (edited) Hi guys, I need to send a message (WM_APP message) to my thread and return immediatly, I tried to do it using PostMessage (a no-blocking function) with hWnd param = Null (it posts the message to the thread message queue). I tried to get the message from the queue using PeekMessage (another function that returns immediatly) but it can't try the message. I'm able to post and retrieve a message from a window message queue (using GUIRegisterMsg, it would be useful to know its source code) but it would be better if I could use the thread message queue. I really don't understand why PeekMessage doesn't retrieve the message posted. $iMsg = 0x8000 $tagPOINT = "struct; long x; long y; endstruct" $tagMSG = "hwnd Hwnd;uint message;wparam wParam;lparam lParam;dword time;" & $tagPOINT $tMSG = DllStructCreate($tagMSG) $pMSG = DllStructGetPtr($tMSG) $hwnd = GUICreate("GUI") $aResult = DllCall("user32.dll", "bool", "PostMessage", "hwnd", Null, "uint", $iMsg, "wparam", "some", "lparam", "thing") ;$aResult[0] = 1 -----> the message is posted to the thread message queue $aResult = DllCall("user32.dll", "bool", "PeekMessage", "ptr", $pMSG, "hwnd", Null, "uint", $iMsg, "uint", $iMsg, "uint", 1) ;@error = 0 -----> DllCall doesn't fail ;$aResult[0] = 0 ----> PeekMessage doesn't retrieve the message If $aResult[0] <> 0 Then ConsoleWrite(DllStructGetData($tMSG, "wParam") & @CRLF) Exit Else For $i = 1 To 4 Beep(800, 250) Next EndIf Edited September 25, 2014 by j0kky Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs Link to comment Share on other sites More sharing options...
j0kky Posted September 26, 2014 Author Share Posted September 26, 2014 up Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs Link to comment Share on other sites More sharing options...
j0kky Posted September 27, 2014 Author Share Posted September 27, 2014 (edited) Hi guys, I think I've solved my issue. The answer is not simple and really not clear. I think in Autoit executables there is some functionality that removes istantly the message from message queue. The only way to get the messages with PeekMessage is intercepting them in the same millisecond they are sent. I searched on the forum for a way to run successfully PeekMessage but NOBODY in these years do it!!!! So I've decided to do it by myself: there is the first script that launches the second script (with its thread ID as parameter) and enters in a PeekMessage loop, the second script just send the message to the first one. First script: Global Const $iMsg = 0x8000 Global Const $tagPOINT = "struct; long x; long y; endstruct" Global Const $tagMSG = "hwnd Hwnd;uint message;wparam wParam;lparam lParam;dword time;" & $tagPOINT Global $tMSG = DllStructCreate($tagMSG) Local $aResult = DllCall("kernel32.dll", "dword", "GetCurrentThreadId") $threadId = $aResult[0] Run("AutoIt3.exe d.au3 " & $threadId) For $i = 1 To 10000 Local $aResult = DllCall("user32.dll", "bool", "PeekMessage", "ptr", DllStructGetPtr($tMSG), "hwnd", -1, "uint", $iMsg, "uint", $iMsg, "uint", 1) If $aResult[0] <> 0 Then ConsoleWrite(@ScriptName & " " & DllStructGetData($tMSG, "wparam") & " " & @MIN & ":" & @SEC & ":" & @MSEC & @CRLF) Beep(800, 100) EndIf Next Second script: Global $threadId = Int($CmdLine[1]) $hfile = FileOpen("log.txt", 2) Global Const $iMsg = 0x8000 $aResult = DllCall("user32.dll", "bool", "PostThreadMessage", "dword", $threadId, "uint", $iMsg, "wparam", 567, "lparam", "thing") FileWrite($hfile, @ScriptName & " " & $aResult[0] & " " & @MIN & ":" & @SEC & ":" & @MSEC & @CRLF) FileClose($hfile) ShellExecute("log.txt") In this way the first script can receive and process the message. Otherwise, if I try to send the message by the same script, the PeekMessage loop is not already active and you can't intercept the message. And what about if you need to get a message sent by the same thread? It can be done in an unorthodox way: we need to install an hook procedure via SetWindowsHookEx. #include <WinAPI.au3> Global Const $iMsg = 0x8000 Global Const $tPOINT = "struct; long x; long y; endstruct" Global Const $tagMSG = "hwnd Hwnd;uint message;wparam wParam;lparam lParam;dword time;" & $tPOINT Global $tMSG = DllStructCreate($tagMSG) Global $threadId = _WinAPI_GetCurrentThreadId() Local $hCallback = DllCallbackRegister("_func", "LRESULT", "int;wparam;lparam") Global $hHook = _WinAPI_SetWindowsHookEx($WH_GETMESSAGE, DllCallbackGetPtr($hCallback), Null, $threadId) DllCall("user32.dll", "bool", "PostThreadMessage", "dword", $threadId, "uint", $iMsg, "wparam", 567, "lparam", 430) For $i = 1 To 10000 $aResult = DllCall("user32.dll", "bool", "PeekMessage", "ptr", DllStructGetPtr($tMSG), "hwnd", -1, "uint", $iMsg, "uint", $iMsg, "uint", 1) If $aResult[0] <> 0 Then ConsoleWrite(@ScriptName & " " & DllStructGetData($tMSG, "wparam") & " " & @MIN & ":" & @SEC & ":" & @MSEC & @CRLF) Beep(800, 100) EndIf Next Func _func($nCode, $wParam, $lParam) If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam) Local $ftMSG = DllStructCreate($tagMSG, $lParam ) Local $hwparam = DllStructGetData($ftMSG, "lParam" ) ConsoleWrite("Hwnd = " & DllStructGetData($ftMSG, "Hwnd") & @CRLF & _ "Message = " & Hex(DllStructGetData($ftMSG, "message"), 4) & @CRLF & _ "wParam = " & DllStructGetData($ftMSG, "wParam") & @CRLF & _ "lParam = " & DllStructGetData($ftMSG, "lParam") & @CRLF) Return 0 EndFunc I'm very curious to know if I'm right about the default Autoit executables behaviour on message queue and if there is some way to stop it. Maybe someone of Autoit developers will address me on the right way... Edited September 27, 2014 by j0kky Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs Link to comment Share on other sites More sharing options...
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