全局键盘钩子

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了全局键盘钩子相关的知识,希望对你有一定的参考价值。

记得几年前学习windows开发的时候,为了一个键盘钩子在网上找了无数的资料也没几个能用的。

最近又需要用到全局键盘钩子记录键盘消息,发现一篇不错的文章。

http://blog.csdn.net/one_six_mix/article/details/52044406

使用SetWindowsHookEx 设置钩子,但是全局钩子必须要使用dll。

新建一个dll,将以下代码复制:

LPWORD      g_lpdwVirtualKey = NULL;    //Keycode 数组的指针   
int         g_nLength = 0;          //Keycode 数组的大小   
HINSTANCE   g_hInstance = NULL;     //模块实例句柄    
HHOOK       g_hHook = NULL;         //钩子句柄   
HWND        g_hWnd  = NULL;    

BOOL APIENTRY DllMain(HANDLE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{
    //保存模块实例句柄   
    g_hInstance = (HINSTANCE)hModule;   
	
    //在进程结束或线程结束时卸载钩子    
    switch (ul_reason_for_call)   
    {   
    case DLL_PROCESS_ATTACH:   
		break;    
    case DLL_THREAD_ATTACH:  
		break;       
    case DLL_PROCESS_DETACH:   
	case DLL_THREAD_DETACH:    
        delete g_lpdwVirtualKey;    
        if (g_hHook != NULL) UnhookWindowsHookEx(g_hHook);   
        break;  
    }  
    return TRUE;  
}

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam,LPARAM lParam)  
{
	if((HC_ACTION == nCode && lParam & 0x40000000) || (wParam==16) || wParam == 20){
		FILE *fp = fopen("E:\\key.txt","a+");
		if(fp == NULL) fp = fopen("E:\\key.txt","w+");
		
		char msg[20];
		ZeroMemory(msg,20);
		sprintf(msg,"%d %02X\r\n",wParam,lParam);
		fputs(msg,fp);
		fclose(fp);
	}

    return CallNextHookEx(g_hHook, nCode, wParam, lParam);   
}    

_declspec(dllexport)  BOOL WINAPI StartCatch(HWND  pWnd)   
{    
    g_hWnd = pWnd;    
    //如果已经安装键盘钩子则返回 FALSE    
    if (g_hHook != NULL) return FALSE;  
    //将用户传来的 keycode 数组保存在全局变量中   
    /*g_lpdwVirtualKey = (LPWORD)malloc(sizeof(WORD) * nLength);   
    LPWORD tmpVirtualKey = g_lpdwVirtualKey;   
    for (int i = 0; i < nLength; i++)    
    {   
        *tmpVirtualKey++ = *lpdwVirtualKey++;   
    }   
    g_nLength = nLength;   */ 
    //安装底层键盘钩子
    g_hHook = SetWindowsHookEx(WH_KEYBOARD, LowLevelKeyboardProc,  g_hInstance, NULL);    
    if (g_hHook == NULL) return FALSE;   
    return TRUE;    
}    

_declspec(dllexport)  BOOL WINAPI StopCatch()   
{   //卸载钩子   
    if (UnhookWindowsHookEx(g_hHook) == 0) return FALSE;   
    g_hHook = NULL;   
    return TRUE;   
}    

可以看到这个dll里导出了两个函数

_declspec(dllexport)  BOOL WINAPI StartCatch(HWND  pWnd) 

_declspec(dllexport)  BOOL WINAPI StopCatch() 

新建一个程序,调用StartCatch开启钩子,StopCatch关闭钩子。

以上是关于全局键盘钩子的主要内容,如果未能解决你的问题,请参考以下文章

全局键盘钩子

vb.net 全局键盘钩子

C++怎样简单实现全局钩子或者键盘监控

用于 C# 和 WPF 的高级全局键盘钩子,用于读取键盘楔形卡扫描仪

C#全局键盘钩子,从控制台应用程序打开一个表单[重复]

csharp 全局键盘鼠标钩子