为什么我接收不到自定义的消息?(50分)

  • 主题发起人 主题发起人 djrj
  • 开始时间 开始时间
D

djrj

Unregistered / Unconfirmed
GUEST, unregistred user!
一个键盘钩子(放在DLL中),和一个主程序(主程序中重载WndProc来截获消息),
键盘钩子用于监视Ctrl+Shift+S按下时就向主程序发送自定义消息WM_SNAP,
DLL中和主程序中都注册了相同的消息。但主程序无法接收到自定义的消息,
且安装钩子时会有Access violation at address 00D93393, Write of address C74960F2.的错误提示。

程序如下:
library hook;

uses
Windows, Messages, Dialogs, SysUtils, Classes;

type //内存文件映象格式,用于保存调用窗口的句柄
TShareData = record
hCallback: THandle;
end;

const
VK_S = $53;
STR_MSG_SNAP: pchar = 'QUICKSNAP';
STR_FILEMAPPING: pchar = 'afdsafdr342fdcsafdsa';
var
hHook, hMapFile: THandle;
WM_SNAP: integer; //自定义的消息
PShareData: ^TShareData;

{$R *.res}

//钩子函数
function Hookproc(iCode: integer; wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall;
begin
if (iCode = HC_ACTION) and //按下Ctrl+Shift+S
(wParam = VK_S) and
((GetKeyState(VK_CONTROL) and $8000) <> 0) and
((GetKeyState(VK_SHIFT) and $8000) <> 0) then
begin
result:= 0;
postMessage(PShareData^.hCallback, WM_SNAP, 0, 0);//发送抓图消息
ShowMessage('Handle(in dll):' + INTTOSTR(PShareData^.hCallback));
ShowMessage('Have Scape Ok!');
end
else
result:=CallNextHookEx(hHook, iCode, wParam, lParam);
end;

//安装钩子
function EnableHook(h: THandle): Boolean; stdcall;
begin
result:= false;
PShareData^.hCallback:= h;//将主窗口句柄保存到内存文件映象中
if hHook<>0 then exit;
hHook:= SetWindowsHookEx(WH_KEYBOARD, Hookproc, Hinstance, 0);
result:= (hHook <> 0);
end;

//卸载钩子
function DisableHook: Boolean; stdcall;
begin
result:= false;
if hHook<>0 then result:= UnHookWindowsHookEx(hHook);
end;

//输出函数
exports
EnableHook, DisableHook;

//初始化
begin
hHook:= 0;
WM_SNAP:= RegisterWindowMessage(STR_MSG_SNAP);//注册自定义消息

hMapFile:= OpenFileMapping(PAGE_READWRITE,false,STR_FILEMAPPING);
if hMapFile=0 then
hMapFile:= CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
sizeof(TShareData), STR_FILEMAPPING);
PShareData:= MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 0);
end.
 
什么时候报的错?
 
function EnableHook(h: THandle): Boolean; stdcall; export;
~~~~~~~~
DisableHook: 同样。



 
to:zw84611
在主程序中调用EnableHook函数时产生报错。
我加了Export后还是报错,
 
在调用程序中是如何声明的?
 
function EnableHook(h: THandle): Boolean ...
->
function EnableHook(h: THandle): BOOL ...
 
参巧我这个代码:
http://delphibbs.com/delphibbs/dispq.asp?lid=1451312
 
去这里看看
http://suncw.y365.com/index1.html#
 
这个问题真的就这么难么?
 
把主程序的代码贴出来。
 
TO:zw84611,
主程序如下:
unit FrmMain;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, SUISkinForm, ExtCtrls, SUITitleBar, AppEvnts, StdCtrls;

type
TForm1 = class(TForm)
bttnEnableHook: TButton;
bttnDisableHook: TButton;
procedure FormCreate(Sender: TObject);
procedure bttnEnableHookClick(Sender: TObject);
procedure bttnDisableHookClick(Sender: TObject);
procedure WndProc(var Msg:TMessage);override;
private
{ Private declarations }
public
{ Public declarations }
end;

Const
STR_MSG_SNAP = 'QUICKSNAP';

var
Form1: TForm1;
WM_SNAP: Cardinal;

implementation

{$R *.dfm}
function EnableHook(h:THandle): Boolean; External 'hook.dll';
function DisableHook: Boolean;External 'hook.dll';

//窗口创建时注册消息
procedure TForm1.FormCreate(Sender: TObject);
begin
WM_SNAP:= RegisterWindowMessage(STR_MSG_SNAP);//注册自定义消息
end;

//安装钩子
procedure TForm1.bttnEnableHookClick(Sender: TObject);
begin
EnableHook(Form1.Handle);
end;

//卸载钩子
procedure TForm1.bttnDisableHookClick(Sender: TObject);
begin
DisableHook;
end;

//重载消息处理过程
procedure TForm1.WndProc(var Msg:TMessage);
begin
if Msg.Msg=WM_SNAP then
begin
ShowMessage('Recieve message OK!');//程序运行中此处对话框没有显示出来,表明收不到消息!!!!。
end;
inherited;
end;

end.
 
function EnableHook(h:THandle): Boolean; stdcall;External 'hook.dll';
~~~~~~~~~
function DisableHook: Boolean;stdcall;External 'hook.dll';
~~~~~~~~
 
To:zw84611,
非常感谢你,现在果然可以收到自定义消息,显示出对话框!
可当我把钩子卸掉又安装钩子后,就收不到消息了,只有重新把主程序关掉再启动才有效。
请你好事做到底,再帮我看看。
谢谢你
 
有没有报错?
 
刚刚看了zw84611富翁资料,
原来竟是DFW的元老级了,
得到你的指点真是感激啊。
(双手合十,向你致敬)
 
没有再报错了,但就是钩了装了后一卸掉再安装时就收不到消息了,
只有把主程序关掉后重新启动,才能收到消息。
 
找到原因了,
是在卸载钩时if hHook<>0 then result:= UnHookWindowsHookEx(hHook);
现在我加了一个卸载后把hHook:=0就可以了。
 

Similar threads

后退
顶部