views:

128

answers:

2

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)
+2  A: 

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
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
Ah, really. You need to convert an absolute click position into the relative. Use ScreenToClient(hWnd, lpPoint) before PostMessage
Andrew
ah ty, i'll try that! is there any diff between postmessage and sendmessage in this case?
Claudiu
I think there is no difference between postmessage and sendmessage in this case.
Andrew
A: 

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