まずキーボードの低レベルフックに必要な定義を行います。
uses Windows; type LPKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT; {$EXTERNALSYM LPKBDLLHOOKSTRUCT} tagKBDLLHOOKSTRUCT = record vkCode: DWORD; scanCode: DWORD; flags: DWORD; time: DWORD; dwExtraInfo: Pointer; end; {$EXTERNALSYM tagKBDLLHOOKSTRUCT} KBDLLHOOKSTRUCT = tagKBDLLHOOKSTRUCT; {$EXTERNALSYM KBDLLHOOKSTRUCT} TKbDllHookStruct = KBDLLHOOKSTRUCT; PKbDllHookStruct = LPKBDLLHOOKSTRUCT; const WH_KEYBOARD_LL = 13; {$EXTERNALSYM WH_KEYBOARD_LL} LLKHF_EXTENDED = KF_EXTENDED shr 8; {$EXTERNALSYM LLKHF_EXTENDED} LLKHF_INJECTED = $00000010; {$EXTERNALSYM LLKHF_INJECTED} LLKHF_ALTDOWN = KF_ALTDOWN shr 8; {$EXTERNALSYM LLKHF_ALTDOWN} LLKHF_UP = KF_UP shr 8; {$EXTERNALSYM LLKHF_UP}
次にフック関数を用意します。
type TSystemKeyCombination = (skLWin, // [WIN] (Left) - Open Start menu skRWin, // [WIN] (Right) - Open Start menu skCtrlEsc, // [CTRL] + [ESC] - Open Start menu skAltTab, // [ALT] + [TAB] - Switch programs skAltEsc, // [ALT] + [ESC] - Next program skCtrlShiftEsc, // [CTRL] + [SHIFT] + [ESC] - Open task manager skAltF4); // [ALT] + [F4] - Quit program TSystemKeyCombinations = set of TSystemKeyCombination; var hh: HHOOK; InvalidCombinations: TSystemKeyCombinations; function LowLevelKeyboardProc(nCode: Integer; wP: WPARAM; lP: LParam): LRESULT; stdcall; export; var pkbhs: PKbDllHookStruct; CtrlKey: Boolean; ShiftKey: Boolean; begin pkbhs := PKbDllHookStruct(lP); case nCode of HC_ACTION: begin case pkbhs^.vkCode of VK_LWIN: begin if skLWin in InvalidCombinations then begin { LWIN } Result := 1; Exit; end; end; VK_RWIN: begin if skRWin in InvalidCombinations then begin { RWIN } Result := 1; Exit; end; end; VK_TAB: begin if ((pkbhs^.flags and LLKHF_ALTDOWN) <> 0) and (skAltTab in InvalidCombinations) then begin { ALT + TAB } Result := 1; Exit; end; end; VK_ESCAPE: begin CtrlKey := ((GetAsyncKeyState(VK_CONTROL) and $8000) <> 0); ShiftKey := ((GetAsyncKeyState(VK_SHIFT) and $8000) <> 0); if ((pkbhs^.flags and LLKHF_ALTDOWN) <> 0) and (skAltEsc in InvalidCombinations) then begin { ALT + ESC } Result := 1; Exit; end; if ShiftKey = False then begin if (CtrlKey = True) and (skCtrlEsc in InvalidCombinations) then begin { CTRL + ESC } Result := 1; Exit; end; end else begin if (CtrlKey = True) and (skCtrlShiftEsc in InvalidCombinations) then begin { CTRL + SHIFT + ESC } Result := 1; Exit; end; end; end; VK_F4: begin if ((pkbhs^.flags and LLKHF_ALTDOWN) <> 0) and (skAltF4 in InvalidCombinations) then begin { ALT + F4 } Result := 1; Exit; end; end; end; end; end; Result := CallNextHookEx(hh,nCode,wP,lP); end;
ここでは集合型のInvalidCombinationsに含まれるキーコンビネーションであればResultを1にしてそのままリターン、そうでなければCallNextHookExでフックチェーンの呼び出しを行うようにしています。
最後にキーボードの低レベルフックを設定、解除する関数は
procedure HookKeyboardLL; begin if hh <> 0 then begin Exit; end; hh := SetWindowsHookEx(WH_KEYBOARD_LL,LowLevelKeyboardProc,HInstance,0); end; procedure UnhookKeyboardLL; begin if hh = 0 then begin Exit; end; UnhookWindowsHookEx(hh); hh := 0; end;
と単にSetWindowsHookExおよびUnhookWindowsHookExを呼び出すだけです。
なお[Ctrl]+[ALT]+[Del]のキーストロークだけはキーボードの低レベルフックでも捕捉できません(GINAの置き換えが必要になります)。
0 件のコメント:
コメントを投稿