hook在什么时候会被撤消? (50分)

  • 主题发起人 主题发起人 hhbs
  • 开始时间 开始时间
H

hhbs

Unregistered / Unconfirmed
GUEST, unregistred user!
我正在学习Delphi。我的一个程序中,通过dll文件挂上WH_KEYBOARD钩子,然后通过指针调用我的主程序中的函数,把WPARAM和LPARAM传回主程序。完成后调试,当我的程序被激活时一切正常,但激活别的程序时按一个键,我的Hook就失效了,不再响应键盘消息。但如果激活别的程序后不按键,再激活我的程序,还是正常的。这是为什么?Hook在什么情况下会失效?
dll文件:
代码:
library Keyboard; 

uses 
  Windows, 
  Messages; 

type 
  c=function(iCode:Integer;wParam:WPARAM;lParam:LPARAM):boolean; //回调函数 

var 
  hNextHookProc:HHook;//保存SetWindowsHookEx的返回值 
  procSaveExit:Pointer; 
  proc:c;//回调函数指针 

function KeyBoardHookHandler(iCode:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;export; 
begin 
//------------------------按sdk中的说明,若iCode小于0,调用CallNextHookEx并返回 
  if iCode<0 then 
begin 
Result:=CallNextHookEx(hNextHookProc,iCode,wParam,lParam); 
Exit; 
end; 
//------------------------ 
if proc(iCode,wParam,lParam) then Result:=1 else Result:=0;//调用主程序并取得返回值 
end; 

function EnableHotKeyHook(hP:c):BOOL;export; 
begin 
proc:=hP;//保存回调函数指针 
result:=False;//初始化返回值 
if hNextHookProc<>0 then Exit;//如果已经注册,直接退出 
 hNextHookProc:=SetWindowsHookEx(WH_KEYBOARD,KeyboardHookHandler,HInstance,0);//注册hook 
 Result:=hNextHookProc<>0;//通过返回值确定是否注册成功 
end; 

function DisableHotKeyHook:BOOL;export; 
begin 
 Result:=false;//初始化返回值 
 if hNexthookProc<>0 then//如果没有注册,直接退出 
 begin 
  UnhookWindowshookEx(hNextHookProc);//注销hook 
  hNextHookProc:=0;//恢复标志 
  Result:=hNextHookProc=0;返回是否注销成功 
 end; 
end; 

procedure HotKeyHookExit; 
begin 
 if hNextHookProc<>0 then DisableHotKeyHook;//如果忘记注销,代为注销 
 ExitProc:=procSaveExit;//调用原结束函数 
end; 

exports //发布函数 
 EnableHotKeyHook, 
 DisableHotKeyHook; 

begin//初始化dll 
 hNextHookProc:=0; 
 procSaveExit:=ExitProc; 
 ExitProc:=@HotKeyHookExit; 
end.

主程序:
代码:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
type 
 HookProc=function(iCode:integer;wParam:WPARAM;lParam:LPARAM):boolean;//Hook回调函数 
var
  Pr:HookProc; //回调函数指针
  Form1: TForm1;

implementation

{$R *.dfm}
function EnableHotKeyHook(hP:HookProc):BOOL;external 'Key.dll'; //dll中注册hook的函数,传递参数为回调函数的指针
function DisableHotKeyHook:BOOL;external 'Key.dll';//dll中注销hook的函数

function HookPro(iCode:integer;wParam:WPARAM;lParam:LPARAM):boolean;//dll的回调函数
var Item:TListItem; 
begin
 result:=false;  //返回值 
//-----------------------------------在ListView中显示相关信息
 Item:=Form1.ListView1.Items.Add; 
 Item.Caption:=IntToStr(iCode);
 Item.SubItems.Add(IntToStr(wParam));
 Item.SubItems.Add(IntToStr(lParam));
//------------------------------------ 
end; 

procedure TForm1.FormCreate(Sender: TObject);
begin
  Pr:=HookPro;
  if not EnableHotKeyHook(Pr) then ShowMessage('启动Hook错误!');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if not DisableHotKeyHook then ShowMessage('注销Hook错误!');
end;

end.
 
我在hook回调函数中
if proc(iCode,wParam,lParam) then Result:=1 else Result:=0;
前加入MessageBox(0,PChar('asd'),PChar('asd'),0);
在激活别的程序时按键,弹出两个窗口,ListView无反应
如果加入其后,则没有窗口弹出
这是不是说明函数没有正常返回?为什么会这样??
 
有什么办法可以实现dll与主程序之间的通讯啊?不要告诉我都要用SendMessage……有什么简单的方法吗?
 
后退
顶部