sosad Posted February 6, 2014 Share Posted February 6, 2014 Hello guys, about three years back I wrote a script to help me change model parameters quickly in my CAD-Software. It was neccessary to use simulated input for updating values and selecting certain parts of the model. There are several different windows that require input (including the 3D-preview which I can not target using controlsend()). In order to get the job done I used DllCalls to post window messages to the different windows an the compiled script still works like a charm. Recently I tried to add some new functionality to the script but the simulating input part no longer works. Even recompiling the old code won't work, while the already compile script works just fine. I spend some time trying to find out whats wrong and managed to narrow it down to the DllCall and PostMessage e.g.: DllCall("user32.dll", "int", "PostMessage", "HWND", $GUI_Main, "UINT", $WM_LBUTTONDOWN, "WPARAM", 0, "LPARAM", BitOR( 75 * 0x10000, BitAND(150, 0xFFFF))) Long story short, I think the Message is posted to the target window, but not recognized as a Keyboard / Mouse event. I've made an example to demonstrate my problem: expandcollapse popup;change EventMode Opt("GUIOnEventMode", 1) ;set constants myself to make sure they are correct Static $GUI_Event_Close = -3 Static $WM_LBUTTONDOWN = 0x0201 ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms645607%28v=vs.85%29.aspx Static $WM_LBUTTONUP = 0x0202 ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms645608%28v=vs.85%29.aspx ;create a sample GUI Global $GUI_Main = GUICreate("PostMessage Testscript", 300, 100) Global $GUI_Button1 = GUICtrlCreateButton("press this to initate a click", 5, 5, 290, 42) Global $GUI_Button2 = GUICtrlCreateButton("this should be clicked automatically", 5, 53, 290, 42) ;register events GUISetOnEvent($GUI_Event_Close, "EventHandler") GUICtrlSetOnEvent($GUI_Button1, "EventHandler") GUICtrlSetOnEvent($GUI_Button2, "EventHandler") ;Custom Events - uncomment these to check if Events occure ;GUIRegisterMsg($WM_LBUTTONDOWN, "CatchWindowMessage") ;GUIRegisterMsg($WM_LBUTTONUP, "CatchWindowMessage") ;show the gui GUISetState() ;wait for input While 1 Sleep(250) WEnd ;...^^ Func EventHandler() Switch @GUI_CtrlId Case $GUI_Button1 ;Send a MouseButtonDown Event followed by ButtonUp at coords x = 150, y = 75 (relative to client area): ;PostMessage http://msdn.microsoft.com/en-us/library/windows/desktop/ms644944%28v=vs.85%29.aspx DllCall("user32.dll", "int", "PostMessage", "HWND", $GUI_Main, "UINT", $WM_LBUTTONDOWN, "WPARAM", 0, "LPARAM", BitOR( 75 * 0x10000, BitAND(150, 0xFFFF))) Sleep(50) DllCall("user32.dll", "int", "PostMessage", "HWND", $GUI_Main, "UINT", $WM_LBUTTONUP, "WPARAM", 0, "LPARAM", BitOR( 75 * 0x10000, BitAND(150, 0xFFFF))) Case $GUI_Button2 MsgBox(0,"PostMessage Testscript","Button 2 was clicked") Case $GUI_Event_Close Exit EndSwitch EndFunc ;just to log incomming window events Func CatchWindowMessage($a_HWnD, $a_MsgID, $a_wParam, $a_lParam) ConsoleWrite("Event occured:" & @CRLF & "MsgID: " & $a_MsgID & @CRLF & "wParam: " & $a_wParam & @CRLF & "lParam: " & $a_lParam & @CRLF & @CRLF) EndFunc In this example, if the first button is clicked I would expect the second button to be clicked automatically, too. However this is not the case (neither in x64 nor in x86 mode). Still, the message is posted, which can be prooven by uncommenting the custom events. I'm totally lost on this one, can anybody tell me what's going wrong here? I'm running the latest version of autoit on a win7 64bit machine. Thanks in advance Link to comment Share on other sites More sharing options...
JohnOne Posted February 6, 2014 Share Posted February 6, 2014 Have you tried using the standard _WinAPI_PostMessage() UDF? AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Solution sosad Posted February 6, 2014 Author Solution Share Posted February 6, 2014 (edited) Have you tried using the standard _WinAPI_PostMessage() UDF? Yes, sadly the result doesn't change. I do believe my DllCall is correct, since the event is recognized if i register it. However since those are standard events they should be handled by default (by windows itself) or at least they were in the past. The code worked just fine when I compiled it 3 years ago... I'm lost. Edit: No I'm not lost, I'm stupid. Turns Out I need to use the handle of the control I want to postMessages to, not the parent window. I should have known that. In case anyone is interested, the example above works correctly if recoded like this: expandcollapse popup;change EventMode Opt("GUIOnEventMode", 1) ;set constants myself to make sure they are correct Static $GUI_Event_Close = -3 Static $WM_LBUTTONDOWN = 0x0201 ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms645607%28v=vs.85%29.aspx Static $WM_LBUTTONUP = 0x0202 ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms645608%28v=vs.85%29.aspx ;create a sample GUI Global $GUI_Main = GUICreate("PostMessage Testscript", 300, 100) Global $GUI_Button1 = GUICtrlCreateButton("press this to initate a click", 5, 5, 290, 42) Global $GUI_Button2 = GUICtrlCreateButton("this should be clicked automatically", 5, 53, 290, 42) ;register events GUISetOnEvent($GUI_Event_Close, "EventHandler") GUICtrlSetOnEvent($GUI_Button1, "EventHandler") GUICtrlSetOnEvent($GUI_Button2, "EventHandler") ;Custom Events - uncomment these to check if Events occure GUIRegisterMsg($WM_LBUTTONDOWN, "CatchWindowMessage") GUIRegisterMsg($WM_LBUTTONUP, "CatchWindowMessage") ;show the gui GUISetState() ;wait for input While 1 Sleep(250) WEnd ;...^^ Func EventHandler() Switch @GUI_CtrlId Case $GUI_Button1 ;Send a MouseButtonDown Event followed by ButtonUp at coords x = 150, y = 75 (relative to client area): ;PostMessage http://msdn.microsoft.com/en-us/library/windows/desktop/ms644944%28v=vs.85%29.aspx DllCall("user32.dll", "int", "PostMessage", "HWND", GUICtrlGetHandle($GUI_Button2), "UINT", $WM_LBUTTONDOWN, "WPARAM", 1, "LPARAM", BitOR( 25 * 0x10000, BitAND(150, 0xFFFF))) Sleep(50) DllCall("user32.dll", "int", "PostMessage", "HWND", GUICtrlGetHandle($GUI_Button2), "UINT", $WM_LBUTTONUP, "WPARAM", 0, "LPARAM", BitOR( 25 * 0x10000, BitAND(150, 0xFFFF))) Case $GUI_Button2 MsgBox(0,"PostMessage Testscript","Button 2 was clicked") Case $GUI_Event_Close Exit EndSwitch EndFunc ;just to log incomming window events Func CatchWindowMessage($a_HWnD, $a_MsgID, $a_wParam, $a_lParam) ConsoleWrite("Event occured:" & @CRLF & "MsgID: " & $a_MsgID & @CRLF & "wParam: " & $a_wParam & @CRLF & "lParam: " & $a_lParam & @CRLF & @CRLF) EndFunc thx anyway Edited February 6, 2014 by sosad Link to comment Share on other sites More sharing options...
jaberwacky Posted February 6, 2014 Share Posted February 6, 2014 Looks like your posting the message back to the window which generated the message. Did you want to post it to another window? Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? 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