最近在做游戏窗口的自动化时,踩过一个很具体的坑:截图线程和输入线程抢同一个 HWND,焦点一丢,SendInput 就打到别的窗口上。
比较稳的做法是把“找窗口、截图、发输入”拆开,不要在截图回调里直接发键。我现在的顺序是:
- 用 EnumWindows 配窗口标题和类名做一次定位,缓存 HWND,但每次操作前用 IsWindow + GetWindowThreadProcessId 复核,窗口重建就重新找。
- 截图走 PrintWindow 或 DXGI desktop duplication,不要用前台 BitBlt。这样窗口被挡住时画面还在,焦点丢了也不影响识别。
- 输入单独排队。发键前先 AttachThreadInput 到目标线程,再 SetForegroundWindow,失败就退回 PostMessage(WM_KEYDOWN/WM_KEYUP),不要混用两套。
- 识别结果和输入之间加一个短的状态机:只有连续两帧目标框稳定,才允许发一次点击,避免识别抖动连点。
这样做之后,窗口被切到后台时识别还在跑,输入要么明确失败,要么打到正确的线程,不会再出现“截到了、点偏了”。 |