请问为什么我的程序就只能是局部hook,不能全局。我写dll了,也建共享内存了。function MsgHookProc(xiCode: Integer;xwParam: WPARAM;xlParam: LPARAM): LRESULT; stdcall;
var
  LMsgInfo: PMsgInfo;
begin
  if xiCode < 0 then
    Result:=CallNextHookEx(MsgHookHandle,xiCode,xwParam,xlParam)
  else
  if (xiCode = HC_ACTION) then
  begin
    if (PCWPRetStruct(xlParam)^.hwnd = pSharedMem^.HWndSpy) then
    begin
      //走不到这里。
    end;
    Result:=CallNextHookEx(MsgHookHandle,xiCode,xwParam,xlParam);
  end;
end;

解决方案 »

  1.   

     if (xiCode = HC_ACTION) then 
      

  2.   

    那应该是你挂的钩子的问题,而且全局HOOK必须写在DLL里才会管用。
      

  3.   

    function LoadDestroyWndHook: BOOL;   external 'HookMsg.dll';
    function UnLoadDestroyWndHook: BOOL; external 'HookMsg.dll';procedure TForm1.Button1Click(Sender: TObject);
    begin
    LoadDestroyWndHook;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
    UnLoadDestroyWndHook;
    end;
    一般全局HOOK调用dll就行了吧,应该不用写这么复杂……
    DLL反正是这么写的
    library HookMsg;uses
           //SysUtils,       //引用这个后编译40KB,不引用15KB
           //Classes,        //引用这个编译后86KB,不引用40KB
           windows,
           Sysinit;{$R *.res}var           //定义全局变量
    hHook:integer;
    function HookProc(iCode: Integer;    //处理系统钩子的函数
    wParam: WPARAM;
    lParam: LPARAM): LRESULT; stdcall; export; //书写调用规则,记得加 stdcall
    begin
       Result := 0;//注意返回值必须为0,允许对窗口的操作
         try
         if iCode = HCBT_DESTROYWND then begin//捕获关闭窗口的消息
           Winexec('notepad.exe',SW_SHOW);    //预处理消息前执行的代码 ,可自定义
         end;    except
    end;
    end;procedure LoadDestroyWndHook;    //设置系统挂钩
    begin
    hHook:=SetWindowsHookEx(WH_CBT,HookProc,Hinstance,0);   //[Error] HookMsg.dpr(65): Incompatible types: 'Calling conventions differ'
    end;                                                      //函数呼叫约定不一致-->出错procedure UnLoadDestroyWndHook; //注销系统挂钩
    begin
        UnHookWindowsHookEx(hHook);
        hHook := 0;
    end;exports                           //输出函数
        LoadDestroyWndHook,
        UnLoadDestroyWndHook;
    end.
      

  4.   

    to coolbeboy
      我已经把钩子写dll里了,也内存共享了。
      

  5.   

    to gyk120
      很感谢你的例子,但是这个跟我的有点出入。我想要WH_CALLWNDPROCRET的例子。以下是我挂钩函数。
    function StartHook(AHSpyWnd,AHRevWnd: THandle;MessageID: Word): BOOL; stdcall;
    begin
      Result:=False;
      if MsgHookHandle <> 0 then
        Exit;
      pSharedMem^.HWndSpy:=AHSpyWnd;
      pSharedMem^.HRevWnd:=AHRevWnd;
      //pSharedMem^.MessageID:=MessageID;
      MsgHookHandle:=SetWindowsHookEx(WH_CALLWNDPROCRET,@MsgHookProc,HInstance,0);
      Result:=MsgHookHandle<>0;
    end;