You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Windows最小化窗口中通过win32api实现无需最大化的模拟点击

解决最小化Windows应用窗口的点击操作问题

问题核心

你当前用mouse_event模拟物理鼠标点击的方式,依赖窗口在屏幕上的可见位置,所以窗口最小化时完全失效。要实现后台点击,必须直接向目标窗口发送鼠标消息,而非操作系统全局鼠标。

解决方案

使用Windows API的SendMessage函数,直接给目标窗口发送WM_LBUTTONDOWN和WM_LBUTTONUP消息。这种方式不依赖窗口的显示状态,即使最小化也能生效。

整合后的完整代码

将截图、图像识别和后台点击逻辑整合:

from ctypes import windll
import win32gui, win32ui, win32con
import numpy as np
from PIL import Image
import cv2
import time

# 配置参数
TARGET_WINDOW_TITLE = 'app title'
TEMPLATE_IMAGE_PATH = 'VI.jpg'
MATCH_THRESHOLD = 0.8

# 查找目标窗口句柄
hwnd = win32gui.FindWindow(None, TARGET_WINDOW_TITLE)
if not hwnd:
    print("未找到目标窗口")
    exit()

# 截图最小化窗口(保留原有有效逻辑)
left, top, right, bot = win32gui.GetWindowRect(hwnd)
w = right - left
h = bot - top

hwndDC = win32gui.GetWindowDC(hwnd)
mfcDC = win32ui.CreateDCFromHandle(hwndDC)
saveDC = mfcDC.CreateCompatibleDC()

saveBitMap = win32ui.CreateBitmap()
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
saveDC.SelectObject(saveBitMap)

# 执行截图
result = windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 3)
if result != 1:
    print("截图失败")
    exit()

# 转换为PIL图像
bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)
im = Image.frombuffer('RGB', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRX', 0, 1)

# 释放资源
win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hwnd, hwndDC)

# 图像识别匹配
template = Image.open(TEMPLATE_IMAGE_PATH)
template_np = np.array(template)
screenshot_np = np.array(im)

match_result = cv2.matchTemplate(screenshot_np, template_np, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(match_result)

if max_val >= MATCH_THRESHOLD:
    print(f"找到目标,坐标:{max_loc}")
    # 转换为Windows消息要求的坐标格式(高16位存y,低16位存x)
    client_x, client_y = max_loc
    l_param = (client_y << 16) | (client_x & 0xFFFF)
    
    # 发送左键按下消息
    windll.user32.SendMessageW(hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, l_param)
    # 模拟真实点击的短暂延迟
    time.sleep(0.05)
    # 发送左键抬起消息
    windll.user32.SendMessageW(hwnd, win32con.WM_LBUTTONUP, 0, l_param)
    print("已发送后台点击消息")
else:
    print("未匹配到目标图像")

关键细节说明

  • SendMessageW直接与窗口句柄交互,完全不影响前台操作,你可以同时用鼠标处理其他任务
  • 坐标无需转换:PrintWindow获取的截图坐标就是窗口客户区的相对坐标,直接打包成消息参数即可
  • 消息参数规范:WM_LBUTTONDOWN的wParam必须传入MK_LBUTTON标记,表示左键按下状态

内容的提问来源于stack exchange,提问作者Rhys

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 02:22:03