键盘钩子 Dll 通过 SendMessage 向主程序传递指针参数

wgqcsdn 2011-03-11 09:59:54
我做了一个键盘钩子,记录按键信息,在钩子 dll 中通过 SendMessage 的 WParam 向主程序传送一个结构指针,为什么主程序读这个指针的时候老是地址错误呢?

//结构体定义:
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;



...全文
173 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
CaiBirdy 2011-03-11
  • 打赏
  • 举报
回复
内存空间是虚拟的。。不同进程不一样。。用OpenProcess你的主进程后VirtualAllocEx一块内存。。把地址传给主进程再处理。。
Lactoferrin 2011-03-11
  • 打赏
  • 举报
回复
使用WH_KEYBOARD_LL,无需使用dll,更加方便
wgqcsdn 2011-03-11
  • 打赏
  • 举报
回复
貌似明白了,多谢
bdmh 2011-03-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wgqcsdn 的回复:]
我看 Windows 的很多钩子响应函数的 wParam/lParam 都是结构指针,他们是怎么做到的?
比如:WH_CALLWNDPROC 的 lParam 就是 PCWPStruct 类型的
[/Quote]
除非是本进程传递,或者传递立即数,其他的不行
wgqcsdn 2011-03-11
  • 打赏
  • 举报
回复
我看 Windows 的很多钩子响应函数的 wParam/lParam 都是结构指针,他们是怎么做到的?
比如:WH_CALLWNDPROC 的 lParam 就是 PCWPStruct 类型的
bdmh 2011-03-11
  • 打赏
  • 举报
回复
不行,dll是注入到其他程序的,和你的程序不在同一进程空间,所以指针是无效的,你要用共享内存来做这个事情,你可以参考《Delphi 下深入windows核心编程》中的钩子代码,另外获取按键消息,参考下面钩子代码即可
http://blog.csdn.net/bdmh/archive/2011/01/08/6124127.aspx
wgqcsdn 2011-03-11
  • 打赏
  • 举报
回复
CloseHandle(hSnapShot); 应该删掉,忘了!

1,184

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧