1,184
社区成员
发帖
与我相关
我的任务
分享
//结构体定义:
type
TKeyboardHook = packed record
hwnd: HWND; { 按键接收窗口 }
vk_code: Integer; { 虚拟码 }
repart_count: Integer; { 按键重复次数 }
scan_code: Integer; { 扫描码 }
is_extkey: Boolean; { 是否扩展键,比如:F1/F2/Insert }
alt_down: Boolean; { Alt 是否按下 }
prev_keystate: Boolean; { 上一个按键的状态是按下(True)还是释放 }
state: Boolean; { 当前按键的状态:0: 按下; 1: 释放 }
processid: Cardinal; { 当前进程 ID }
wParam: WPARAM; { 原 wParam }
lParam: LPARAM; { 原 lParam }
end;
PKeyboardHook = ^TKeyboardHook;
//钩子响应函数:
function KeyboardFilterProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT;
var
lpKeyInfo: PKeyboardHook;
begin
if nCode = HC_ACTION then
begin
GetMem(lpKeyInfo, Sizeof(TKeyboardHook));
lpKeyInfo.hwnd := GetFocus;
lpKeyInfo.vk_code := wParam;
lpKeyInfo.repart_count := $FFFF and lParam;
lpKeyInfo.scan_code := (lParam shr 16) and $FF;
lpKeyInfo.is_extkey := GetBitState(lParam, 24) = 1;
lpKeyInfo.alt_down := GetBitState(lParam, 29) = 1;
lpKeyInfo.prev_keystate := GetBitState(lParam, 30) = 1;
lpKeyInfo.state := GetBitState(lParam, 31) = 0;
lpKeyInfo.processid := GetCurrentProcessId;
lpKeyInfo.wParam := wParam;
lpKeyInfo.lParam := lParam;
SendMessage(PShare.hMasterWnd, WM_HOOK_Keyboard, Integer(lpKeyInfo), 0);
{ PShare.hMasterWnd 主窗体句柄 }
{ lpKeyInfo 虽然是局部变量,但是指针,按说这个过程执行完了,lpKeyInfo 指向的内存不会被释放
而且 SendMessage 是等主窗口消息响应过程执行完了,才会继续往下执行,lpKeyInfo 也不会被释放
为什么主程序老是读地址错误呢? }
end;
Result := CallNextHookEx(PShare.hKeyboardHook, nCode, wParam, lParam);
end;
//主窗体钩子消息响应过程:
procedure TMainForm.WMHookKeyboard(var Message: TMessage);
var
lpKeyName: array[0..255] of WideChar;
lpKeyInfo: PKeyboardHook;
begin
lpKeyInfo := PKeyboardHook(Message.WParam);
GetKeyNameTextW(lpKeyInfo.lParam, lpKeyName, Length(lpKeyName));
{ 读地址错误 }
mmHooklog.Lines.Add('按下按键:' + StrPas(lpKeyName));
CloseHandle(hSnapShot);
end;