最近需要做个跟按键精灵类似的软件,模仿键盘鼠标的动作,然后重播一次,最开时候的时候用键盘钩子和鼠标钩子做的,虽然实现了功能,但是鼠标移动速度非常快,所以换成WH_JOURNALPLAYBACK 和WH_JOURNALRECORD 钩子来做
WH_JOURNALPLAYBACK
使应用程序可以插入消息到系统消息队列。可以使用这个Hook回放通过使用WH_JOURNALRECORD Hook记录下来的连续的鼠标和键盘事件。只要WH_JOURNALPLAYBACK Hook已经安装,正常的鼠标和键盘事件就是无效的。
是全局Hook,它不能象线程特定Hook一样使用。 WH_JOURNALPLAYBACK Hook返回超时值,这个值告诉系统在处理来自回放Hook当前消息之前需要等待多长时间(毫秒)。这就使Hook可以控制实时事件的回放。
是system-wide local hooks,它们不会被注射到任何行程位址空间。
WH_JOURNALRECORD
用来监视和记录输入事件。典型的,可以使用这个Hook记录连续的鼠标和键盘事件,然后通过使用WH_JOURNALPLAYBACK Hook来回放。
具体原理就是定义两个全局钩子 一个用来记录 一个用来回放 话不多说 看代码
void CKMHookDll::InstallHook(bool bIsKeyDown,bool bIsMouseDown,bool bIsMouseMove/*HWND hwnd*/)
{if (!m_pVecAction->empty()){m_pVecAction->clear();}m_bIsKeyDown = bIsKeyDown;m_bIsMouseDown = bIsMouseDown;m_bIsMouseMove = bIsMouseMove;m_hRecHook = SetWindowsHookEx(WH_JOURNALRECORD,(HOOKPROC)RecHook,m_hInst,0);
}
这段代码会开启WH_HOURANLRECORD钩子,会记录键盘 鼠标事件 我把它们保存在vector中,
钩子过程如下
LRESULT CALLBACK RecHook(int code,WPARAM wParam,LPARAM lParam)
{static int recOK = 1;if(code<0){return CallNextHookEx(CKMHookDll::GetInstance()->GetRecHook(),code,wParam,lParam);}else if(code==HC_SYSMODALON){recOK = 0;}else if(code==HC_SYSMODALOFF){recOK = 1;}else if(recOK && (code==HC_ACTION)){EVENTMSG action = *(EVENTMSG*)lParam;CKMHookDll::GetInstance()->AddEvent(action);}return 0;
}
每个键盘 鼠标事件都被保存在vector中,等待回放,开启回放的钩子代码如下
void CKMHookDll::RunScript()
{m_nPlayedEvent = 0;m_hPlayHook = SetWindowsHookEx(WH_JOURNALPLAYBACK,(HOOKPROC)PlayHook,m_hInst,0);
}
回调过程如下:
LRESULT CALLBACK PlayHook(int code,WPARAM wParam,LPARAM lParam)
{static BOOL fDelay;static int playOK = 1;if(code<0){return CallNextHookEx(CKMHookDll::GetInstance()->GetPlayHook(),code,wParam,lParam);}else if(code==HC_SYSMODALON){playOK = 0;}else if(code==HC_SYSMODALOFF){playOK = 1;}else if(playOK && (code==HC_GETNEXT)){if(fDelay){fDelay = FALSE;return 50;}*((EVENTMSG*)lParam) = CKMHookDll::GetInstance()->GetVecAt(CKMHookDll::GetInstance()->GetPlayedEvent());}else if(playOK && (code==HC_SKIP)){fDelay = TRUE;CKMHookDll::GetInstance()->IncPlayedEvent();}if(CKMHookDll::GetInstance()->GetPlayedEvent()>=CKMHookDll::GetInstance()->GetVecSize()){UnhookWindowsHookEx(CKMHookDll::GetInstance()->GetPlayHook());}return 0;
}
整个工程下载:
http://download.csdn.net/detail/mrxiao95/9471394