CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  Windows SDK/API

这个全局钩子为什么只能钩住本程序的消息?

楼主wanggongqin(())2006-11-02 12:45:42 在 Delphi / Windows SDK/API 提问

{   钩子   DLL   源代码   }  
   
  library   HookDll;  
   
  {   Important   note   about   DLL   memory   management:   ShareMem   must   be   the  
      first   unit   in   your   library's   USES   clause   AND   your   project's   (select  
      Project-View   Source)   USES   clause   if   your   DLL   exports   any   procedures   or  
      functions   that   pass   strings   as   parameters   or   function   results.   This  
      applies   to   all   strings   passed   to   and   from   your   DLL--even   those   that  
      are   nested   in   records   and   classes.   ShareMem   is   the   interface   unit   to  
      the   BORLNDMM.DLL   shared   memory   manager,   which   must   be   deployed   along  
      with   your   DLL.   To   avoid   using   BORLNDMM.DLL,   pass   string   information  
      using   PChar   or   ShortString   parameters.   }  
   
  uses  
      SysUtils,  
      Classes,  
      Dllfunc   in   'Dllfunc.pas';  
   
  exports  
      StartHook,   StopHook;      
   
  {$R   *.res}  
   
  begin  
  end.  
   
  {--------------------------------------------------------}  
   
  unit   Dllfunc;  
   
  interface  
   
  uses  
      Windows,   SysUtils,   Classes,   Messages;  
   
  const  
      WM_Main_Accept   =   WM_User   +   1;      
   
  function   StartHook(AMainWnd:   HWND):   Boolean;   stdcall;   {开始钩子}  
  procedure   StopHook;   stdcall;   {停止钩子}  
   
  function   HookCallWndProc(nCode:   Integer;   wPar:   WParam;   lPar:   LParam):   LRESULT;   stdcall;  
  function   HookCallWndProcRet(nCode:   Integer;   wPar:   WParam;   lPar:   LParam):   LRESULT;   stdcall;  
  {   钩子响应函数   }  
   
  implementation  
   
  var  
      MainWnd:   HWND;  
      {   钩子消息发往这个窗体   }  
   
      hCallWndProc:   THandle;  
      hCallWndProcRet:   THandle;  
      {   钩子类型变量   }  
   
  const  
      MsgArea:   array[0..18]   of   UINT   =  
          (WM_NCPAINT,   WM_NCACTIVATE,   WM_CHAR,  
          WM_ENABLE,   WM_KEYUP,   WM_LBUTTONUP,   WM_MBUTTONUP,   WM_PALETTECHANGED,  
          WM_RBUTTONUP,   WM_SYSCOLORCHANGE,   WM_SETFOCUS,   WM_HSCROLL,  
          WM_VSCROLL,   WM_WINDOWPOSCHANGING,   WM_DESTROY,   WM_WINDOWPOSCHANGED,   WM_PAINT,  
          482,   485);  
      {   定义响应消息的范围   }  
   
  function   InMessageArea(const   Msg:   UINT):   Boolean;  
  var  
      i:   Integer;  
  begin  
      Result   :=   False;  
      for   i:=Low(MsgArea)   to   High(MsgArea)   do  
          if   MsgArea[i]   =   Msg   then  
          begin  
              Result   :=   True;  
              Break;  
          end;  
  end;  
   
  function   HookCallWndProc(nCode:   Integer;   wPar:   WParam;   lPar:   LParam):   LRESULT;   stdcall;  
  var  
      Cwp:   TCWPStruct;  
  begin  
      if   nCode   =   HC_ACTION   then  
      begin  
          Cwp   :=   (PCWPStruct(lPar))^;  
          if   InMessageArea(Cwp.message)   then  
              PostMessage(MainWnd,   WM_Main_Accept,   Cwp.hwnd,   Cwp.message);  
          {   向主窗体发送发生消息的窗口句柄   }  
      end;  
      Result   :=   CallNextHookEx(hCallWndProc,   nCode,   wPar,   lPar);  
  end;  
   
  function   HookCallWndProcRet(nCode:   Integer;   wPar:   WParam;   lPar:   LParam):   LRESULT;   stdcall;  
  var  
      CwpRet:   TCWPRetStruct;  
  begin  
      if   nCode   =   HC_ACTION   then  
      begin  
          CwpRet   :=   (PCWPRetStruct(lPar))^;  
          if   InMessageArea(CwpRet.message)   then  
              PostMessage(MainWnd,   WM_Main_Accept,   CwpRet.hwnd,   CwpRet.message);  
          {   向主窗体发送发生消息的窗口句柄   }  
      end;  
      Result   :=   CallNextHookEx(hCallWndProcRet,   nCode,   wPar,   lPar);  
  end;  
   
  function   StartHook(AMainWnd:   HWND):   Boolean;   stdcall;  
  begin  
      MainWnd   :=   AMainWnd;  
      hCallWndProc   :=   SetWindowsHookEx(WH_CALLWNDPROC,   HookCallWndProc,   HInstance,   0);  
      hCallWndProcRet   :=   SetWindowsHookEx(WH_CALLWNDPROCRET,   HookCallWndProcRet,   HInstance,   0);  
  {   钩子的目标线程是   0   ,应该对所有线程有效   }  
      Result   :=   (hCallWndProc   <>   0)   and   (hCallWndProcRet   <>   0);  
      if   not   Result   then   StopHook;  
  end;  
   
  procedure   StopHook;   stdcall;  
  begin  
      if   hCallWndProc   <>   0   then   UnhookWindowsHookEx(hCallWndProc);  
      if   hCallWndProcRet   <>   0   then   UnhookWindowsHookEx(hCallWndProcRet);  
  end;  
   
  end.  
   
  {----------------------------------------------------------------}  
  {   主程序源代码   }  
   
  unit   Unit1;  
   
  interface  
   
  uses  
      Windows,   Messages,   SysUtils,   Variants,   Classes,   Graphics,   Controls,   Forms,  
      Dialogs,   StdCtrls,   IniFiles;  
   
  const  
      WM_Main_Accept   =   WM_User   +   1;      
   
  type  
      TForm1   =   class(TForm)  
          btnBegin:   TButton;  
          btnStop:   TButton;  
          mmMessage:   TMemo;  
          procedure   btnBeginClick(Sender:   TObject);  
          procedure   btnStopClick(Sender:   TObject);  
      private  
          procedure   WMAcceptMessage(var   AMessage:   TMessage);   message   WM_Main_Accept;  
      public  
          {   Public   declarations   }  
      end;  
   
  function   StartHook(AMainWnd:   HWND):   Boolean;   stdcall;   external   'HookDll.dll';  
  procedure   StopHook;   stdcall;   external   'HookDll.dll';  
   
  var  
      Form1:   TForm1;  
      RecFile:   TIniFile;  
   
  implementation  
   
  {$R   *.dfm}  
   
  {   TForm1   }  
   
  procedure   TForm1.WMAcceptMessage(var   AMessage:   TMessage);  
  var  
      WinText:   array[0..254]   of   Char;  
  begin  
      GetWindowText(AMessage.WParam,   WinText,   255);  
      RecFile.WriteString('HookRec',DateTimeToStr(Now),  
          WinText+'   消息值:'+IntToStr(AMessage.LParam));  
      {   把发生消息的信息记录到   Ini   文件中   }  
  end;  
   
  procedure   TForm1.btnBeginClick(Sender:   TObject);  
  begin  
      StartHook(Self.Handle);  
      RecFile   :=   TIniFile.Create(ExtractFilePath(Application.ExeName)+'Rec.txt');  
  end;  
   
  procedure   TForm1.btnStopClick(Sender:   TObject);  
  begin  
      RecFile.Free;  
      StopHook;  
  end;  
   
  end.  
   
  {----------------------------------------------------------}  
   
  程序运行后,只有本程序发生事件后,才响应钩子函数。  
  按照全局钩子的要求,我已经将钩子函数单独放到了   Dll   中,  
  为什么还是不能响应其它程序的消息。 问题点数:50、回复次数:3Top

1 楼coffee36(咖啡)回复于 2006-11-02 13:19:11 得分 40

关注,我也遇到同样问题Top

2 楼wanggongqin(())回复于 2006-11-03 09:48:27 得分 0

我已经解决了。  
   
  解决的办法是使用共享内存!  
   
  因为钩子回调函数是供所有被插入线程调用的,所以函数内的全局变量必须是共享的才行。Top

3 楼linzhengqun(风。我回来了)回复于 2006-11-03 22:54:23 得分 10

具看这里:  
  http://blog.csdn.net/linzhengqun  
  找   钩子及其应用  
  Top

相关问题

关键词

得分解答快速导航

  • 帖主:wanggongqin
  • coffee36
  • linzhengqun

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo