天天看點

HOOK使用:全局鍵盤鈎子

// CatchKey.cpp : Defines the entry point for the DLL application.
//

#define _WIN32_WINNT  0x0500        //設定系統版本,可以使用底層鍵盤鈎子
#define WM_MY_SHORTS (WM_USER + 105)
#include "windows.h"
//全局變量 
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 (nCode >= HC_ACTION && wParam==WM_KEYDOWN) 
	{ 
		BOOL bctrl = GetAsyncKeyState(VK_CONTROL)>>((sizeof(SHORT) *8)-1);   
		KBDLLHOOKSTRUCT* pStruct = (KBDLLHOOKSTRUCT*)lParam;  
		LPWORD tmpVirtualKey = g_lpdwVirtualKey;  
		if (pStruct->vkCode == 80 && bctrl)  
			PostMessage(g_hWnd,WM_MY_SHORTS,0,1);  
        return TRUE;  
	} 
    //傳給系統中的下一個鈎子 
	return CallNextHookEx(g_hHook, nCode, wParam, lParam); 
}  

 _declspec(dllexport)
BOOL WINAPI StartCatch(LPWORD lpdwVirtualKey, int nLength,  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_LL, 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; 
 }  
           

利用底層的鍵盤鈎子

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam,LPARAM lParam)

來攔截 按鍵的時候

鍵盤的鍵按下和彈起時候會發生WM_KEYUP 和 WM_KEYDOWN兩個消息,

這兩個消息都會被hook,是以如此。

是以需要對 wParam 進行判斷  是 WM_KEYDOWN 還是 WM_KEYUP