本来一直打算做个APM计数器的,所谓APM计数器,就是一个全局的计算键盘鼠标平均时间下的操作量啦。如果玩过星际争霸或者魔兽争霸的一定知道APM的意义。
为了实现全局的统计键盘和鼠标操作,我采用了HOOK的方法进行了实现,具体如下。
首先建立一个DLL得工程,这个工程的主要目的就是进行钩子并且通过函数指针对主程序进行通知。
其头文件如下:
Code
#ifdef _COMPILING_44E531B1_14D3_11d5_A025_006067718D04
#define LIBSPEC __declspec(dllexport)
#else
#define LIBSPEC __declspec(dllimport)
#endif
LIBSPEC BOOL setMouseHook();
LIBSPEC BOOL setKeyBoardHook();
LIBSPEC BOOL setMsgHook();
LIBSPEC BOOL clearAllHook();
typedef int (*FucOnMouse)(int mousex,int mousey) ;
LIBSPEC void setHookFuncMouse(FucOnMouse ptFuc);
typedef int (*FucOnKeyBoard)(long code, long scancode,long flags);
LIBSPEC void setHookFuncKeyBoard(FucOnKeyBoard ptFuc);
typedef int (*FucOnMsg)(WPARAM wParam, LPARAM lParam);
LIBSPEC void setHookFuncMsg(FucOnMsg ptFuc);
#undef LIBSPEC
而后是源文件:#ifdef _COMPILING_44E531B1_14D3_11d5_A025_006067718D04
#define LIBSPEC __declspec(dllexport)
#else
#define LIBSPEC __declspec(dllimport)
#endif
LIBSPEC BOOL setMouseHook();
LIBSPEC BOOL setKeyBoardHook();
LIBSPEC BOOL setMsgHook();
LIBSPEC BOOL clearAllHook();
typedef int (*FucOnMouse)(int mousex,int mousey) ;
LIBSPEC void setHookFuncMouse(FucOnMouse ptFuc);
typedef int (*FucOnKeyBoard)(long code, long scancode,long flags);
LIBSPEC void setHookFuncKeyBoard(FucOnKeyBoard ptFuc);
typedef int (*FucOnMsg)(WPARAM wParam, LPARAM lParam);
LIBSPEC void setHookFuncMsg(FucOnMsg ptFuc);
#undef LIBSPEC
Code
HINSTANCE hInst;
HHOOK hookkeyboard = NULL;
static LRESULT WINAPI KeyBoardProc(int nCode,WPARAM wparam,LPARAM lparam) ;
BOOL APIENTRY DllMain( HINSTANCE hInstance,
DWORD Reason,
LPVOID Reserved
)
{
switch(Reason)
{ /* reason */
case DLL_PROCESS_ATTACH:
hInst = hInstance;
return TRUE;
case DLL_PROCESS_DETACH:
return clearAllHook();
} /* reason */
return TRUE;
}
//主程序如果要对键盘消息进行截获就调用这个函数
__declspec(dllexport) BOOL setKeyBoardHook()
{
if (hookkeyboard!=NULL)
{
return TRUE;
}
hookkeyboard = SetWindowsHookEx(WH_KEYBOARD_LL,KeyBoardProc,hInst,0);
if(hookkeyboard!=NULL)
{ /* success */
return TRUE;
}
return FALSE; // failed to set hook
}
//然后在主程序中设置一个函数指针来处理键盘消息。
static FucOnMouse g_ptfucmouse = NULL;
__declspec(dllexport) void setHookFuncMouse(FucOnMouse ptFuc)
{
g_ptfucmouse = ptFuc;
}
//这部分就是HOOK的时候传入的处理函数啦
static LRESULT WINAPI KeyBoardProc(int nCode,WPARAM wparam,LPARAM lparam)
{
if(nCode>=0)
{
LPKBDLLHOOKSTRUCT pKeyBoardHook =(LPKBDLLHOOKSTRUCT)lparam;
//如果截获到键盘消息就利用函数指针传递
if(g_ptfuckeyboard)
{
g_ptfuckeyboard(pKeyBoardHook->vkCode,pKeyBoardHook->scanCode,pKeyBoardHook->flags);
}
}
return CallNextHookEx(hookkeyboard,nCode,wparam,lparam);
}
到这里就完成了HOOK.HINSTANCE hInst;
HHOOK hookkeyboard = NULL;
static LRESULT WINAPI KeyBoardProc(int nCode,WPARAM wparam,LPARAM lparam) ;
BOOL APIENTRY DllMain( HINSTANCE hInstance,
DWORD Reason,
LPVOID Reserved
)
{
switch(Reason)
{ /* reason */
case DLL_PROCESS_ATTACH:
hInst = hInstance;
return TRUE;
case DLL_PROCESS_DETACH:
return clearAllHook();
} /* reason */
return TRUE;
}
//主程序如果要对键盘消息进行截获就调用这个函数
__declspec(dllexport) BOOL setKeyBoardHook()
{
if (hookkeyboard!=NULL)
{
return TRUE;
}
hookkeyboard = SetWindowsHookEx(WH_KEYBOARD_LL,KeyBoardProc,hInst,0);
if(hookkeyboard!=NULL)
{ /* success */
return TRUE;
}
return FALSE; // failed to set hook
}
//然后在主程序中设置一个函数指针来处理键盘消息。
static FucOnMouse g_ptfucmouse = NULL;
__declspec(dllexport) void setHookFuncMouse(FucOnMouse ptFuc)
{
g_ptfucmouse = ptFuc;
}
//这部分就是HOOK的时候传入的处理函数啦
static LRESULT WINAPI KeyBoardProc(int nCode,WPARAM wparam,LPARAM lparam)
{
if(nCode>=0)
{
LPKBDLLHOOKSTRUCT pKeyBoardHook =(LPKBDLLHOOKSTRUCT)lparam;
//如果截获到键盘消息就利用函数指针传递
if(g_ptfuckeyboard)
{
g_ptfuckeyboard(pKeyBoardHook->vkCode,pKeyBoardHook->scanCode,pKeyBoardHook->flags);
}
}
return CallNextHookEx(hookkeyboard,nCode,wparam,lparam);
}
主程序部分:
Code
//首先记得加上HOOK工程的头文件,并且连接下库文件
#include "MsgTracker.h"
#pragma comment(lib, "MsgTracker.lib")
//声明一个用于处理键盘信息的函数指针
int KeyboardRecord(long code,long scancode,long flags);
//处理键盘消息的函数主体 --- 把截获的消息存放到 文本文件
int KeyboardRecord(long code,long scancode,long flags)
{
notifyOtherProc();
std::ofstream outfile("C:\\KEYBOARDinfo.txt",ofstream::out|ofstream::app);
SYSTEMTIME sys;
GetLocalTime( &sys );
outfile<<"Time:"<<sys.wHour<<":"<<sys.wMinute<<":"<<sys.wSecond;
outfile<<" Key Code="<<code;
outfile<<"\r\n";
return 0;
}
//程序的主函数
void WINAPI ServiceMain()
{
//就这点代码 就可以进行消息截获啦
BOOL bKeyboard;
if((bKeyboard=setKeyBoardHook())==TRUE)
setHookFuncKeyBoard(KeyboardRecord);
//让他自己循环去吧
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
if(msg.message == WM_CLOSE)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//最后一定要记得清除钩子
clearAllHook();
}
//首先记得加上HOOK工程的头文件,并且连接下库文件
#include "MsgTracker.h"
#pragma comment(lib, "MsgTracker.lib")
//声明一个用于处理键盘信息的函数指针
int KeyboardRecord(long code,long scancode,long flags);
//处理键盘消息的函数主体 --- 把截获的消息存放到 文本文件
int KeyboardRecord(long code,long scancode,long flags)
{
notifyOtherProc();
std::ofstream outfile("C:\\KEYBOARDinfo.txt",ofstream::out|ofstream::app);
SYSTEMTIME sys;
GetLocalTime( &sys );
outfile<<"Time:"<<sys.wHour<<":"<<sys.wMinute<<":"<<sys.wSecond;
outfile<<" Key Code="<<code;
outfile<<"\r\n";
return 0;
}
//程序的主函数
void WINAPI ServiceMain()
{
//就这点代码 就可以进行消息截获啦
BOOL bKeyboard;
if((bKeyboard=setKeyBoardHook())==TRUE)
setHookFuncKeyBoard(KeyboardRecord);
//让他自己循环去吧
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
if(msg.message == WM_CLOSE)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//最后一定要记得清除钩子
clearAllHook();
}
最后放上代码:
/Files/oplusx/截获消息MsgTracker.rar