まずキーボードの低レベルフックに必要な定義を行います。
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 件のコメント:
コメントを投稿