Windows 日记本播放挂钩 (WH_JOURNALPLAYBACK) 忽略 EVENTMSG HWND 参数
Windows Journal playback hook (WH_JOURNALPLAYBACK) ignores EVENTMSG HWND parameter
>我正在开发一个程序来以编程方式模拟键盘和鼠标单击。它需要将单击发送到目标窗口句柄(例如:记事本编辑控件)。我正在获取记事本窗口的句柄并为该窗口生成生成WM_KEYDOWN、WM_SYSKEYDOWN、WM_KEYUP WM_SYSKEYUP消息。事件存储在队列中,稍后使用WH_JOURNALPLAYBACK钩子播放。
对于下面的代码片段,播放过程中的目标 hwnd 虽然设置正确,但消息永远不会到达目标句柄。如果我将记事本放在前台,它确实会收到消息。
我不确定为什么WH_JOURNALPLAYBACK忽略句柄参数。我本来想为各种句柄生成一系列自动化消息并播放它,以便即使没有使窗口成为焦点,我们也可以发送键盘和鼠标事件。
请让我知道
- 如果可以使用日记将消息发送到各种目标句柄播放挂钩
- 为什么在下面的代码中忽略 hwnd
..
#include <queue>
#include <iostream>
#include <windows.h>
using std::cout;
using std::endl;
using std::error;
struct Event
{
UINT msg;
UINT wparam;
UINT lparam;
HWND hwnd;
Event(UINT m, UINT wp, UINT lp, HWND h)
:msg(m),
wparam(wp),
lparam(lp),
hwnd(h)
{}
};
HHOOK jhook= NULL;
std::queue<Event> events;
bool gotoNextMsg = false;
LRESULT CALLBACK JournalPlaybackProc(int code, WPARAM wParam, LPARAM lParam)
{
switch( code )
{
case HC_SKIP:
cout<<"skip: "<<endl;
if(!events.empty())
{
events.pop();
}
break;
case HC_GETNEXT:
{
cout<<"next: "<<events.size()<<endl;
gotoNextMsg = true;
EVENTMSG * evm = (EVENTMSG*) lParam;
Event e = events.front();
switch(e.msg)
{
case WM_KEYDOWN:
cout<<"WM_KEYDOWN"<<endl;
break;
case WM_KEYUP:
cout<<"WM_KEYUP"<<endl;
break;
case WM_SYSKEYDOWN:
cout<<"WM_SYSKEYDOWN"<<endl;
break;
case WM_SYSKEYUP:
cout<<"WM_SYSKEYUP"<<endl;
break;
}
cout<<"handle: "<<e.hwnd<<endl;
cout<<"handle1:"<<evm->hwnd<<endl;
evm->message = e.msg;
evm->paramL = e.wparam;
evm->paramH = e.lparam;
evm->hwnd = e.hwnd;
evm->time = ::GetTickCount();
}
break;
default:
if( code < 0 )
::CallNextHookEx(jhook, code, wParam, lParam);
break;
}
if(events.empty())
{
cout<<"uinstalled"<<endl;
::UnhookWindowsHookEx(jhook);
::PostMessage(NULL, WM_USER+100, 0, 0);
}
return 0;
}
日志挂钩将事件注入系统消息队列。 对于键盘和鼠标消息,系统会将它们调度到当前焦点窗口,就像用户手动输入它们一样。 您在事件中指定的 HWND 未使用,它会在调度期间被替换。
而且,如果您考虑到录制的日志可以多次播放,并且其数据可以跨应用程序实例甚至重新启动而持久保存,并且 HWND 可以随着时间的推移重用于不同的事情,那么即使不涉及系统消息队列,日志播放也不能利用事件的 HWND 应该是有意义的。
因此,不能使用 WH_JOURNALPLAYBACK
来定位不在前台的特定窗口。您必须自己发送录制的消息。 但请注意Raymond Chen在博客中提到的一些警告:
您无法使用帖子消息模拟键盘输入
通过WM_CHAR消息模拟输入可能会伪造收件人,但不会伪造输入系统