问题 win32:模拟点击而不模拟鼠标移动?


我正试图在窗口上模拟鼠标点击。我目前的成功如下(我使用的是Python,但它应该适用于一般的win32):

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

这很好用。但是,如果在我手动移动鼠标时发生单击,则光标位置会被抛弃。有没有办法直接发送一个点击给定的 (x,y) 没有移动鼠标那么坐标?我尝试了类似下面的东西并没有太多运气:

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)

13032
2017-09-15 19:12


起源



答案:


试试WindowFromPoint()函数:

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);

8
2017-09-15 19:23



我的坐标是绝对坐标,但不是相对于窗口位置的坐标.. PostMessage会将它们作为绝对坐标或相对于窗口的坐标传输吗?我实际上已经可以获得hwnd,但只是将我的coords转换为 (x - left, y - top)我在哪里 left 和 top 从 GetWindowRect 没有点击正确的位置。 - Claudiu
啊,真的。您需要将绝对点击位置转换为相对位置。在PostMessage之前使用ScreenToClient(hWnd,lpPoint) - Andrew
啊ty,我会试试的!在这种情况下,postmessage和sendmessage之间有什么区别吗? - Claudiu
我认为在这种情况下postmessage和sendmessage之间没有区别。 - Andrew
嘿,在哪里 MAKELPARAM 来自? - Lai32290


答案:


试试WindowFromPoint()函数:

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);

8
2017-09-15 19:23



我的坐标是绝对坐标,但不是相对于窗口位置的坐标.. PostMessage会将它们作为绝对坐标或相对于窗口的坐标传输吗?我实际上已经可以获得hwnd,但只是将我的coords转换为 (x - left, y - top)我在哪里 left 和 top 从 GetWindowRect 没有点击正确的位置。 - Claudiu
啊,真的。您需要将绝对点击位置转换为相对位置。在PostMessage之前使用ScreenToClient(hWnd,lpPoint) - Andrew
啊ty,我会试试的!在这种情况下,postmessage和sendmessage之间有什么区别吗? - Claudiu
我认为在这种情况下postmessage和sendmessage之间没有区别。 - Andrew
嘿,在哪里 MAKELPARAM 来自? - Lai32290


这不能回答这个问题,但它确实解决了我的问题:

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))

结果是我正在进行的任何动作都不会干扰点击。缺点是我的实际动作会搞砸,所以我仍然愿意接受建议。


3
2017-09-15 19:41