-1

I am working on a program that is supposed to simulate basic mouse input for a program while it stays in the background (meaning, I want to do other things in other windows with the actual mouse and keyboard while the target receives input). One thing I need to be able to do is move the mouse to a specific (x,y) point.

It seems to work for the most part, but in a certain region of the screen the message only works correctly some of the time. Other times, it moves to a consistent but wrong other point within the region. I am reading that sometimes it is relative, but if I spam the message repeatedly, it does seem to work consistently. Also, reading in Spy++, the messages that are sent by me actually moving my mouse are using what seem to be absolute coordinates.

My function is here:

void mouseMove(short x, short y) {
    PostMessage(wnd, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
}

Preferably, I'd like for any (x,y) to be absolute so I can have the region treated as any other. But it would also be fine to set the position to a coordinate relative to the top left corner of the region.

I have tried just about all of the messages I've seen sent to the window in Spy++ before the WM_MOUSEMOVE but nothing is helping.

How might I approach this?

Edit, since details might not prove enough info:

I am sending these messages in this order:

  • WM_ACTIVATE 2 0
  • WM_MOUSEMOVE 0 MAKELPARAM(x,y)
  • WM_LBUTTONDOWN MK_LBUTTON MAKELPARAM(x,y)
  • WM_LBUTTONUP 0 MAKELPARAM(x,y)

I think what I initially thought (bad WM_SETCURSOR area) is wrong because Spy++ consistently shows HTCLIENT being used.

I have found a lot of people trying to do this (background input) and most seem to be told it's impossible. It's not impossible, and I think if someone can answer how to do this correctly once and for all it would be doing quite a few people a big favor.

Lupe
  • 319
  • 1
  • 3
  • 16
  • Is [this SO question of interest?](http://stackoverflow.com/questions/3645281/c-win32-set-cursor-position) – Weather Vane Mar 31 '17 at 18:11
  • @WeatherVane I did try that and the Point x and y even in the region were what they were before the call. I am still very convinced it's somewhat related, though. – Lupe Mar 31 '17 at 18:21
  • do you have particularly problem with you (x,y)? I think I know some reason and workaround , but before I sound dumb would you give me some more info on what you doing exactly. also the returned values of ScreenToClient can be same in some situation like you put your window in corner then 0,0 of screen and client can be the same. – nullqube Mar 31 '17 at 18:50
  • Basically I have `HWND window;` which I want to send input to from a separate application. I am using PostMessage to change the mouse's position, but WM_MOUSEMOVE seems to work strangely (puts mouse in wrong position) in one particular region (2D square) of the window. As far as I can tell, it only behaves strangely in this one region (there may be others but it works fine in some, at least). – Lupe Mar 31 '17 at 19:00
  • Why aren't you using automation API – David Heffernan Apr 02 '17 at 04:51
  • @DavidHeffernan The target application isn't mine. Doesn't that rule that out? If it can be used to send any input to arbitrary windows without taking control of the input stream then it would be perfect but from all I've heard that is not the case. – Lupe Apr 02 '17 at 05:24
  • 1
    I think you should understand UI Automation before you reject it. – David Heffernan Apr 02 '17 at 05:25
  • @DavidHeffernan Fair point. I recognize I am being biased simply because I haven't heard of it in all I've read about this. I will read about it. But, there should also be a way to do it correctly with messages. – Lupe Apr 02 '17 at 05:27
  • No, sending input messages is not robust. Might work for some targets. We see tens of questions a day here from people labouring under this misapprehension. – David Heffernan Apr 02 '17 at 05:29

1 Answers1

1

Synthesizes keystrokes, mouse motions, and button clicks.

   UINT WINAPI SendInput(
      _In_ UINT    nInputs,
      _In_ LPINPUT pInputs,
      _In_ int     cbSize
    );

PostMessage function. Places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.

For PostMessage to work you need to be in the process as the target that you can achieve with SetWindowHook but the these links will do the jobs:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/ms171542(v=vs.110).aspx

nullqube
  • 2,959
  • 19
  • 18
  • Note "while it stays in the background." Unless I'm mistaken the *only way at all* to do this is using Send/PostMessage. – Lupe Mar 31 '17 at 18:19
  • The process isn't a windows form and ScreenToClient in the region outputs the same (x,y) as before the call. It is very possible it's doing something very hacky but I'm confused as to what would even be possible to do. – Lupe Mar 31 '17 at 18:24
  • 1
    http://stackoverflow.com/questions/7492529/how-to-simulate-a-mouse-movement – nullqube Mar 31 '17 at 18:26
  • All of those cannot send input to a background application. I need this to work while the window is in the background and while I am doing other things. I haven't seen the DirectX way before so there may be ways to make it pass to a window (will look into) but I am assuming you meant the earlier answers. – Lupe Mar 31 '17 at 18:31
  • also there is another approach too that with considering hacky stuffs, like you attach your app to the target's process and main GUI thread with SetWindowsHookEx and you should do all that in a separate .dll then you can use PostMessage and for sending messages to your own app you can then use RegisterWindowMessage ,... but this is a long off-road way – nullqube Mar 31 '17 at 18:34
  • I really don't want to do that :(. Especially since this program has protection. I am PostMessage-ing from an external process and it works with all messages but this one all the time perfectly, and this one all of the time in all times but one region, and in one region some of the time. I would be very very surprised if there isn't a clean way to fix this. – Lupe Mar 31 '17 at 18:37