Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Help with Simulating mouse clicks using postmessage


  • Please log in to reply
9 replies to this topic
BlueAnon
  • Members
  • 10 posts
  • Last active: Aug 13 2009 11:07 AM
  • Joined: 10 Aug 2009
Hi Guys, Just started using autohot key a week ago. So, please excuse my noobishness. I need to accomplish a simple task. I have a window which has no controls at all. I keep it minimized and wish to simulate mouse clicks at a particular coordinate inside it using PostMessage. I used winspector and recorded data on a simple action: Moving the mouse across the window and clicking the left mouse button.

This is the recorded data
(Please ignore second and third images, they are just repetitions. I added them for continuity of message numbers)

Posted Image
followed by
Posted Image
followed by
Posted Image
and finally
Posted Image

Well, you can see that, there are only a few mesages being repeated here.
WM_NCHITTEST,WM_SETCURSOR,WM_MOUSEMOVE - to move the mouse

WM_LBBUTTONDOWN,WM_LBUTTONUP - clicking the mouse


To simulate this in a window , this is my script
+q::
WinSetTitle,GridCal v1.0, ,GRIDCAL1

WinID := WinActive("GRIDCAL1")

SetFormat,integer,h
HexWinId := WinID

;Post MouseMove Message -- 0x021901AF is the x,y coordinate relative to window,no tscreen coordinates. -- position is 431,537
PostMsg("0x200","0x00000000","0x021901AF",WinID)

;Post MouseActivate Msg -- the WParam has to be true - i think it is 0x00000001
PostMsg("0x21",HexWinId,"0x00000001",WinID)

;Activate App -- the WParam has to be true - i think it is 0x00000001
PostMsg("0x1C","0x00000001","0x00000000",WinID)

;Activate -- here Wparam is HTCLIENT -- I read somewhere that its integer val is 2
PostMsg("0x06","0x00000002","0x00000000",WinID)

;Set Cursor -- hit-test code.is HTCLIENT and mouse mesage ID is 513
PostMsg("0x20",HexWinId,"0x02010001",WinID)

;Button Down -- position is 431,537
PostMsg("0x201","0x00000000","0x021901AF",WinID)

;Button Up -- position is 431,537
PostMsg("0x202","0x00000000","0x021901AF",WinID)

Return

+w::Reload


PostMsg(msg,Wparameter,LParameter,WindowID)
{
	PostMessage,%msg%,%Wparameter%,%LParameter%,,ahk_id %WindowID%
	Sleep,200	
}

Here, if i keep the window focussed with the mouse inside it, then it works only so far that it clicks. not at the intended spot but where the mouse is present. i.e if the said window is in focus and the mouse is inside the window, then the script clicks the mouse at that spot, not where the coordinates are.But if i minimize the window or if it is not active, then nothing happens.

So clearly , the button up and down messages are being passed but the mousemove messages are not being processed

Any suggestions on which direction i should go. Please excuse such a lengthy post.

Edit: also , ignore the PostMsg() function. It doesn't work if i use the postmessage function directly

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Have you tried ControlClick?
Btw, as far as I know it will not work when windows is minimized but will work if windows is out of working area or hidden or in background.

sinkfaze
  • Moderators
  • 6367 posts
  • Last active: Nov 30 2018 08:50 PM
  • Joined: 18 Mar 2008
AFAIK, WM_MOUSEMOVE messages are not made to actually move the mouse but only to record a position at which the mouse has been moved after it has stopped for an amount of time or after a mouse button has been pressed.

In addition, if you're using the WM_LBUTTONDOWN and WM_LBUTTONUP messages I believe they should prevent WM_MOUSEMOVE messages from being generated since their action does not physically move the mouse as it were.

And you don't have to get the actual hex code for the x/y click coordinates either, you can have those converted within the function itself:

PostClick(x,y,win="A") { ; assumes 'win' is the active window if no window title is specified

  lParam := [color=red]x & 0xFFFF | (y & 0xFFFF) << 16 [/color]
  PostMessage, 0x201, , %lParam%, , %win% ;WM_LBUTTONDOWN 
  PostMessage, 0x202, , %lParam%, ,  %win% ;WM_LBUTTONUP 
  
}


BlueAnon
  • Members
  • 10 posts
  • Last active: Aug 13 2009 11:07 AM
  • Joined: 10 Aug 2009
Thanks sinkfaze & HotKeyIt. First, My window has no controls at all and i want to use it minimized. So, Is there no way to simulate clicks inside a minimized window at pred defined coordinates.

BlueAnon
  • Members
  • 10 posts
  • Last active: Aug 13 2009 11:07 AM
  • Joined: 10 Aug 2009

Have you tried ControlClick?
Btw, as far as I know it will not work when windows is minimized but will work if windows is out of working area or hidden or in background.


Does control click work if the said window has no controls at all. I have an idea.i just hide the window away and use control click.It is as good as minimize.Is it possible

I will definitely try it once i am home but am trying to get as much info on it as possible.

BlueAnon
  • Members
  • 10 posts
  • Last active: Aug 13 2009 11:07 AM
  • Joined: 10 Aug 2009

PostClick(x,y,win="A") { ; assumes 'win' is the active window if no window title is specified

  lParam := [color=red]x & 0xFFFF | (y & 0xFFFF) << 16 [/color]
  PostMessage, 0x201, , %lParam%, , %win% ;WM_LBUTTONDOWN 
  PostMessage, 0x202, , %lParam%, ,  %win% ;WM_LBUTTONUP 
  
}


Do you mean, i do not need WM_MOUSEMOVE to click at a particular coordinate. when i use WM_LBUTTONDOWN & WM_LBUTTONUP, it clicks where ever the mouse is present at that moment regardless of what coordinates i pass. so, i thought may be i should first simulate a mousemove action to tell the window that the mouse now is at (x,y) position and then send LBUTTONDOWN/UP to click at that coordinate

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

AFAIK, WM_MOUSEMOVE messages are not made to actually move the mouse but only to record a position at which the mouse has been moved after it has stopped for an amount of time or after a mouse button has been pressed.

"The WM_MOUSEMOVE message is posted to a window when the cursor moves." If the cursor is still moving, WM_MOUSEMOVE will be sent repeatedly with the new co-ordinates. Whether the mouse button is pressed is irrelevant; if an application is only interested in the co-ordinates of the mouse when you press a button, it can inspect the parameters of the WM_xBUTTONDOWN message.

The point of posting WM_MOUSEMOVE to a window would not be to actually move the mouse, but to make the window think that the mouse has moved. Some applications would require this: e.g. drawing a line in Paint without activating the window or actually moving the mouse. Btw, I've written an interactive example. :D

In addition, if you're using the WM_LBUTTONDOWN and WM_LBUTTONUP messages I believe they should prevent WM_MOUSEMOVE messages from being generated since their action does not physically move the mouse as it were.

Sending those messages does not in any way prevent WM_MOUSEMOVE from being generated. In fact, WM_MOUSEMOVE has nothing to do with pressing buttons.

PostClick(x,y,win="A")

That is essentially a less powerful version of ControlClick.

So, Is there no way to simulate clicks inside a minimized window at pred defined coordinates.

Try ControlClick. It posts WM_xBUTTONDOWN messages according to the parameters you specify. Whether the target window actually reads the messages when it is minimized is entirely up to the application/game.

Does control click work if the said window has no controls at all.

Yes. Leave the "Control-or-Pos" parameter blank, or specify a position instead of a control.

i just hide the window away and use control click.

That should work, just remember to enable DetectHiddenWindows.

Do you mean, i do not need WM_MOUSEMOVE to click at a particular coordinate.

Right, you do not need WM_MOUSEMOVE. In fact, ControlClick does not use it at all as each WM_xBUTTONDOWN/UP message contains the co-ordinates of the "click". Most applications use those co-ordinates, not the co-ordinates of a previous WM_MOUSEMOVE.

* When I say "WM_xBUTTON", "x" may be substituted for L, R, M or X.

sinkfaze
  • Moderators
  • 6367 posts
  • Last active: Nov 30 2018 08:50 PM
  • Joined: 18 Mar 2008
Thanks for the insight into WM_MOUSEMOVE, Lex. That example is wicked.

That is essentially a less powerful version of ControlClick.


I suspected as much, but what are the other differences within the ControlClick command aside of the PostMessage commands? I've had situations working with ControlClick where it was very unreliable when used for clicking on buttons within an application, where a PostMessage sequence similar to the above function operates almost perfectly. I've also had situations where I could not use ControlClick to click at coordinates in a given window but I could use a PostMessage function like the above and it would click at coordinates fine in the same window. I'm sure it could just be that I've come across exceptions to the rule but I was just curious if there was any internal difference in ControlClick that might lead to that unreliability that raw PostMessage commands seems to bypass.

BlueAnon
  • Members
  • 10 posts
  • Last active: Aug 13 2009 11:07 AM
  • Joined: 10 Aug 2009
Hi Lexikos,
Your post overwhelmed me. That you took so much time for my query and for such a neat and clear reply made me wish this forum had a rep system.I would have spammed and pumped up ur rep through the sky.I am very much thankful to you

Regarding controlclick, i used it and had similar results to what i had with post message,i.e, it works only when the window is in focus(active) and the mouse is inside the window.Even then it does not click at the specified coordinates but only where the mouse is.I guess the developers made ti so that it ignores mouse events if window is not active.

Anyway thanks everybody for all the replies

guest3456
  • Guests
  • Last active:
  • Joined: --
would anyone know why PostMessage / ControlClick wouldn't work on a window. a search has brought this old thread with the same problem:
http://www.autohotke...topic50955.html

basically, MouseClick or Click work fine, but ControlClick or PostMessage just will not click on the coordinates specified. is it a problem with the application?