Python在非激活MacromediaFlashPlayerActiveX窗口模拟鼠标点击失败求助
非激活窗口模拟Flash控件鼠标点击无效问题排查
问题描述
尝试在非激活窗口中模拟鼠标点击,目标是窗口内的MacromediaFlashPlayerActiveX控件。使用win32api.PostMessage发送WM_LBUTTONDOWN和WM_LBUTTONUP消息后,能看到按钮悬停阴影,点击位置已验证正确,但无法触发按钮点击;模拟键盘操作正常。相关代码如下:
# -*- coding:utf-8 -*- import time import win32api, win32gui, win32con def click_minimize(hwnd, x, y): long_position = win32api.MAKELONG(x, y) win32api.PostMessage(hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, long_position) time.sleep(0.3) win32api.PostMessage(hwnd, win32con.WM_LBUTTONUP, 0000, long_position) def flash_button_pos(child_hwnd): # Calculate mouse click position x1, y1, x2, y2 = win32gui.GetWindowRect(child_hwnd) if (x2 - x1) / (y2 - y1) < 1.4: length = x2 - x1 hight = length / 1.4 x = 0 y = (y2 - y1 - hight) / 2 else: hight = y2 - y1 length = hight * 1.4 x = (x2 - x1 - length) / 2 y = 0 x0 = int(0.171 * length + x) y0 = int(0.493 * hight + y) return x0, y0 if __name__ == '__main__': hwld = win32gui.FindWindow(None, "MyGamePython") hwnd_child_list = [] win32gui.EnumChildWindows(hwld, lambda hWnd, param: param.append(hWnd), hwnd_child_list) child_hwnd = None for i in hwnd_child_list: if win32gui.GetClassName(i) == "MacromediaFlashPlayerActiveX": child_hwnd = i x0, y0 = flash_button_pos(child_hwnd) print(x0, y0) click_minimize(child_hwnd, x0, y0)
排查与解决建议
修正坐标系统:
WM_LBUTTON系列消息要求坐标为控件客户区的相对坐标,当前代码基于控件外框计算,需改为基于客户区尺寸:def flash_button_pos(child_hwnd): # 获取控件客户区大小(而非窗口外框) client_rect = win32gui.GetClientRect(child_hwnd) cx, cy = client_rect[2], client_rect[3] if cx / cy < 1.4: length = cx hight = length / 1.4 x = 0 y = (cy - hight) / 2 else: hight = cy length = hight * 1.4 x = (cx - length) / 2 y = 0 x0 = int(0.171 * length + x) y0 = int(0.493 * hight + y) return x0, y0补充鼠标移动消息:Flash控件可能需要先感知鼠标进入,再响应点击,在点击前添加
WM_MOUSEMOVE消息:def click_minimize(hwnd, x, y): long_position = win32api.MAKELONG(x, y) # 先发送鼠标移动到目标位置的消息 win32api.PostMessage(hwnd, win32con.WM_MOUSEMOVE, 0, long_position) time.sleep(0.05) win32api.PostMessage(hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, long_position) time.sleep(0.05) # 缩短延迟,模拟真实点击间隔 win32api.PostMessage(hwnd, win32con.WM_LBUTTONUP, 0, long_position)修正消息参数:
WM_LBUTTONUP的wParam应为0,原代码的0000写法不规范,虽然Python会解析为0,但建议直接写0避免潜在问题。改用同步消息发送:
PostMessage是异步发送,控件可能未处理完前序消息就收到后续消息,改用SendMessage同步发送确保消息被处理:win32api.SendMessage(hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, long_position) time.sleep(0.05) win32api.SendMessage(hwnd, win32con.WM_LBUTTONUP, 0, long_position)尝试硬件级输入模拟:若Flash控件过滤非系统消息,可使用
mouse_event模拟真实硬件输入(需转换为屏幕坐标):def click_with_hardware(child_hwnd, client_x, client_y): # 转换客户区坐标为屏幕坐标 screen_x, screen_y = win32gui.ClientToScreen(child_hwnd, (client_x, client_y)) # 移动鼠标到目标位置(绝对坐标需转为0-65535范围) win32api.mouse_event(win32con.MOUSEEVENTF_MOVE | win32con.MOUSEEVENTF_ABSOLUTE, int(screen_x / win32api.GetSystemMetrics(0) * 65535), int(screen_y / win32api.GetSystemMetrics(1) * 65535)) time.sleep(0.05) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) time.sleep(0.05) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) # 主函数中调用 click_with_hardware(child_hwnd, x0, y0)
内容的提问来源于stack exchange,提问作者Guf
相关产品推荐
相关产品推荐

