// 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