10

I'm trying to simulate a mouse click on a window. I currently have success doing this as follows (I'm using Python, but it should apply to general win32):

win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0)

This works fine. However, if the click happens while I'm moving the mouse manually, the cursor position gets thrown off. Is there any way to send a click directly to a given (x,y) coordinate without moving the mouse there? I've tried something like the following with not much luck:

nx = x*65535/win32api.GetSystemMetrics(0)
ny = y*65535/win32api.GetSystemMetrics(1)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN | \
                     win32con.MOUSEEVENTF_ABSOLUTE,nx,ny)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP | \
                     win32con.MOUSEEVENTF_ABSOLUTE,nx,ny)
rcs
  • 67,191
  • 22
  • 172
  • 153
Claudiu
  • 224,032
  • 165
  • 485
  • 680

2 Answers2

11

Try WindowFromPoint() function:

POINT pt;
    pt.x = 30; // This is your click coordinates
    pt.y = 30;

HWND hWnd = WindowFromPoint(pt);
LPARAM lParam = MAKELPARAM(pt.x, pt.y);
PostMessage(hWnd, WM_RBUTTONDOWN, MK_RBUTTON, lParam);
PostMessage(hWnd, WM_RBUTTONUP, MK_RBUTTON, lParam);
Andrew
  • 3,696
  • 3
  • 40
  • 71
  • 1
    The coordinates I have are absolute coordinates, though, not coordinates relative to the window position.. will PostMessage transmit them as absolute ones or as ones relative to the window? I actually could get the hwnd already, but just translating my coords to `(x - left, y - top)`, where I got `left` and `top` from `GetWindowRect` didn't click in the right spot. – Claudiu Sep 15 '10 at 19:39
  • Ah, really. You need to convert an absolute click position into the relative. Use ScreenToClient(hWnd, lpPoint) before PostMessage – Andrew Sep 15 '10 at 20:26
  • ah ty, i'll try that! is there any diff between postmessage and sendmessage in this case? – Claudiu Sep 15 '10 at 22:41
  • I think there is no difference between postmessage and sendmessage in this case. – Andrew Sep 20 '10 at 16:50
  • 4
    Hey, where is `MAKELPARAM` come from? – Lai32290 Jul 11 '18 at 00:58
5

This doesn't answer the question, but it does solve my problem:

win32api.ClipCursor((x-1,y-1,x+1,y+1))
win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN| \
                     win32con.MOUSEEVENTF_ABSOLUTE,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP| \
                     win32con.MOUSEEVENTF_ABSOLUTE,0,0)
win32api.ClipCursor((0,0,0,0))

The result is that any movements I'm making won't interfere with the click. The downside is that my actual movement will be messed up, so I'm still open to suggestions.

Claudiu
  • 224,032
  • 165
  • 485
  • 680