1. 程式人生 > >HOOK使用:全域性鍵盤鉤子

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_KEYUPWM_KEYDOWN兩個訊息,
這兩個訊息都會被hook,所以如此。

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