delphi2007 教程

delphi2007 教程

首页 新随笔 联系 聚合 管理
  1013 Posts :: 0 Stories :: 28 Comments :: 0 Trackbacks
拦截EDIT控件中的消息问题(上次提问过,我自己找了些资料,虽然拦截到消息,可得到的是空白字符) Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiAPI/html/delphi_20061117131358209.html
接上次的问题,这里我在简单说说  
  单位有一程序,其中有一个Edit控件  
  该控件是用来显示我们执行操作命令返回的消息  
  我的目的是拦截该控件中的消息,主要是为了获取该控件中显示的字符  
  消息为EM_RSPLACESEL  
  下面我给出我根据别人的人个代码写的Hook程序,和我写的主程序

Hook.dll文件一  
   
  library   hook;  
   
  {   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,  
      wdSpyCommon   in   'wdSpyCommon.pas',  
      wdMsgSpy   in   'wdMsgSpy.pas';  
   
  {$R   *.res}  
   
  exports  
      StartSpyMessage,  
      StopSpyMessage;  
   
  begin  
  end.

Hook.dll文件二  
   
  unit   wdSpyCommon;  
  {*******************************************  
    *   brief:   消息Spy用到的数据结构等的声明文件  
    *   autor:   linzhenqun  
    *   date:   2005-9-25  
    *   email:   linzhengqun@163.com  
    *   blog:   http://blog.csdn.net/linzhengqun  
  ********************************************}  
  interface  
  uses  
      Windows,   Messages;  
  resourcestring  
    err_ProcInvalid   =   'the   Message   spy   procedure   are   invalid.';  
      err_ShareMem   =   'could   not   create   share   memory.';  
  const  
      Msg_Null_Value   =   0;  
      Msg_Type_Sent   =   1;  
      Msg_Type_Post   =   2;  
      Msg_Type_Return   =   3;  
  type  
      {   受监察的消息结构   }  
      PMsgInfo   =   ^TMsgInfo;  
      TMsgInfo   =   packed   record  
          hwnd:   HWND;  
          message:   UINT;  
          wParam:   WPARAM;  
          lParam:   LPARAM;  
          time:   DWORD;  
          pt:   TPoint;  
          lResult:   LRESULT;  
          MsgType:   UINT;  
      end;  
  implementation  
  end.

Hook.dll文件三 钩子就在这里设置的  
   
  unit   wdMsgSpy;  
  {*******************************************  
    *   brief:   消息Spy的SDK  
    *   autor:   linzhenqun  
    *   date:   2005-9-24  
    *   email:   linzhengqun@163.com  
    *   blog:   http://blog.csdn.net/linzhengqun  
  ********************************************}  
  interface  
  uses  
      Messages,   Windows,   Classes,   SysUtils,   wdSpyCommon;  
  const  
      MApingFile_Name   =   'MsgSpy_FC819A73-2718-47E2-BF78-6810562CDA65';  
  type  
      //共享内存  
      PShareMem   =   ^TShareMem;  
      TShareMem   =   record  
          HRevWnd:   THandle;   //存放接收消息的窗口句柄  
          HWndSpy:   THandle;   //被监察的窗口句柄  
      end;  
  {   开始监察消息,AHSpyWnd为受监察的窗口,AHRevWnd为接收监察到的消息的窗口   }  
  function   StartSpyMessage(AHSpyWnd,   AHRevWnd:   THandle):   Boolean;   stdcall;  
  {   停止监察消息   }  
  procedure   StopSpyMessage;   stdcall;  
  var  
      HMsgProc,   HWndProc,   HWndRetProc:   THandle;   //相应钩子的句柄  
      PSMem:   PShareMem;   //共享内存块  
      hMApFile:   THandle;   //内存映射文件的句柄。  
  implementation  
   
  //将截获的消息结构发送到目标窗口  
  procedure   SendData(AMsgInfo:   PMsgInfo);   stdcall;  
  var  
      pcds:   PCopyDataStruct;  
  begin  
      New(pcds);  
      pcds^.cbData   :=   SizeOf(TMsgInfo);  
      pcds^.lpData   :=   AMsgInfo;  
      SendMessage(PSMem^.HRevWnd,   WM_COPYDATA,   0,   LongInt(pcds));  
      Dispose(pcds);  
  end;  
  {   WH_GETMESSAGE的钩子过程   }  
  function   GetMsgProc(code:   Integer;   wP:   WPARAM;   lP:   LPARAM):   LRESULT;   stdcall;  
  var  
      LMsgInfo:   PMsgInfo;  
  begin  
  {只有截获的消息的窗口句柄等于被监察的窗口句柄,才进行下一步,  
  接着,当被监察的窗口不是接收消息的窗口时执行下一步操作;或者当被监察窗口  
  就是接收消息的窗口时,截获的消息不是WM_CopyData,执行下一步。  
  这么做是为了避免进入发送消息与截获消息的死循环}  
      if   code   =   HC_ACTION   then  
          if   (PMsg(lp)^.hwnd   =   PSMem^.HWndSpy)   then  
              if   ((PSMem^.HWndSpy   =   PSMem^.HRevWnd)   and   (PMsg(lp)^.message   <>   WM_COPYDATA))  
                  or   (PSMem^.HWndSpy   <>   PSMem^.HRevWnd)   then  
              begin  
                  New(LMsgInfo);  
                  LMsgInfo.hwnd   :=   PMsg(lp)^.hwnd;  
                  LMsgInfo.message   :=   PMsg(lp)^.message;  
                  LMsgInfo.wParam   :=   PMsg(lp)^.wParam;  
                  LMsgInfo.lParam   :=   PMsg(lp)^.lParam;  
                  LMsgInfo.pt   :=   PMsg(lp)^.pt;  
                  LMsgInfo.time   :=   PMsg(lp)^.time;  
                  LMsgInfo.lResult   :=   Msg_Null_Value;  
                  LMsgInfo.MsgType   :=   Msg_Type_Post;  
                  SendData(LMsgInfo);  
                  Dispose(LMsgInfo);  
              end;  
      Result   :=   CallNextHookEx(HMsgProc,   code,   wP,   lP);  
  end;  
   
  {   WH_CALLWNDPROC的钩子过程   }  
  function   CallWndProc(code:   Integer;   wP:   WPARAM;   lP:   LPARAM):   LRESULT;   stdcall;  
  var  
      LMsgInfo:   PMsgInfo;  
  begin  
      if   code   =   HC_ACTION   then  
          if   (PCWPStruct(lp)^.hwnd   =   PSMem^.HWndSpy)   then  
              if   ((PSMem^.HWndSpy   =   PSMem^.HRevWnd)   and   (PCWPStruct(lp)^.message   <>   WM_COPYDATA))  
                  or   (PSMem^.HWndSpy   <>   PSMem^.HRevWnd)   then  
              begin  
                  New(LMsgInfo);  
                  LMsgInfo^.hwnd   :=   PCWPStruct(lp)^.hwnd;  
                  LMsgInfo^.message   :=   PCWPStruct(lp)^.message;  
                  LMsgInfo^.wParam   :=   PCWPStruct(lp)^.wParam;  
                  LMsgInfo^.lParam   :=   PCWPStruct(lp)^.lParam;  
                  LMsgInfo^.pt   :=   Point(0,   0);  
                  LMsgInfo^.time   :=   Msg_Null_Value;  
                  LMsgInfo^.lResult   :=   Msg_Null_Value;  
                  LMsgInfo^.MsgType   :=   Msg_Type_Sent;  
                  SendData(LMsgInfo);  
                  Dispose(LMsgInfo);  
              end;  
      Result   :=   CallNextHookEx(HWndProc,   code,   wP,   lP);  
  end;  
   
  {   WH_CALLWNDPROCRET的钩子过程   }  
  function   CallWndRetProc(code:   Integer;   wP:   WPARAM;   lP:   LPARAM):   LRESULT;   stdcall;  
  var  
      LMsgInfo:   PMsgInfo;  
  begin  
      if   code   =   HC_ACTION   then  
              if   (PCWPRetStruct(lp)^.hwnd   =   PSMem^.HWndSpy)   then  
                  if   ((PSMem^.HWndSpy   =   PSMem^.HRevWnd)   and   (PCWPRetStruct(lp)^.message   <>   WM_COPYDATA))  
                      or   (PSMem^.HWndSpy   <>   PSMem^.HRevWnd)   then  
                  begin  
                      New(LMsgInfo);  
                      LMsgInfo^.hwnd   :=   PCWPRetStruct(lp)^.hwnd;  
                      LMsgInfo^.message   :=   PCWPRetStruct(lp)^.message;  
                      LMsgInfo^.wParam   :=   PCWPRetStruct(lp)^.wParam;  
                      LMsgInfo^.lParam   :=   PCWPRetStruct(lp)^.lParam;  
                      LMsgInfo^.pt   :=   Point(0,   0);  
                      LMsgInfo^.time   :=   Msg_Null_Value;  
                      LMsgInfo^.lResult   :=   PCWPRetStruct(lp)^.lResult;  
                      LMsgInfo^.MsgType   :=   Msg_Type_Return;  
                      SendData(LMsgInfo);  
                      Dispose(LMsgInfo);  
              end;  
      Result   :=   CallNextHookEx(HWndRetProc,   code,   wP,   lP);  
  end;  
   
  function   StartSpyMessage(AHSpyWnd,   AHRevWnd:   THandle):   Boolean;  
  begin  
      Result   :=   False;  
      try  
          if   (HMsgProc   <>   0)   or   (HWndProc   <>   0)   or   (HWndRetProc   <>   0)   then  
              Exit;  
          PSMem^.HWndSpy   :=   AHSpyWnd;  
          PSMem^.HRevWnd   :=   AHRevWnd;  
          HMsgProc   :=   SetWindowsHookEx(WH_GETMESSAGE,   @GetMsgProc,   HInstance,   0);  
          HWndProc   :=   SetWindowsHookEx(WH_CALLWNDPROC,   @CallWndProc,   HInstance,   0);  
          HWndRetProc   :=   SetWindowsHookEx(WH_CALLWNDPROCRET,   @CallWndRetProc,   HInstance,   0);  
          if   (HMsgProc   =   0)   or   (HWndProc   =   0)   or   (HWndRetProc   =   0)   then  
          begin  
              StopSpyMessage;  
              Exit;  
          end;  
      except  
          Exception.Create(err_ProcInvalid);  
      end;  
      Result   :=   True;  
  end;  
   
  procedure   StopSpyMessage;  
  begin  
      UnhookWindowsHookEx(HMsgProc);  
      UnhookWindowsHookEx(HWndProc);  
      UnhookWindowsHookEx(HWndRetProc);  
      HMsgProc   :=   0;  
      HWndProc   :=   0;  
      HWndRetProc   :=   0;  
  end;  
   
  initialization  
    //创建共享内存块  
      hMApFile   :=   OpenFileMApping(FILE_MAP_ALL_ACCESS,   False,   MApingFile_Name);  
      if   hMApFile   =   0   then  
          hMApFile   :=   CreateFileMApping($FFFFFFFF,   nil,   PAGE_READWRITE,   0,  
              SizeOf(TShareMem),   MApingFile_Name);  
      PSMem   :=     MApViewOfFile(hMApFile,   FILE_MAP_WRITE   or   FILE_MAP_READ,   0,   0,   0);  
      if   PSMem   =   nil   then  
      begin  
          CloseHandle(hMApFile);  
          Exception.Create(err_ShareMem);  
      end;  
   
  finalization  
    //释放共享内存块  
      UnMApViewOfFile(PSMem);  
      CloseHandle(hMApFile);  
  end.  
 

友情接分;;;;;;;;

问题解决了,其实在这个Hook.dll代码里修改一下即可了  
   
  因为拦截上的问题,所以,我在dll代码里修改了一下,拦截到消息以后,我直接用  
  SendMessage把消息发送到我的程序中即可  
   
  具体修改为  
   
  {   WH_CALLWNDPROCRET的钩子过程   }  
  function   CallWndRetProc(code:   Integer;   wP:   WPARAM;   lP:   LPARAM):   LRESULT;   stdcall;  
  var  
      LMsgInfo:   PMsgInfo;  
  begin  
     //if   code   =   HC_ACTION   then     这条也可以不要  
              if   (PCWPRetStruct(lp)^.hwnd   =   PSMem^.HWndSpy)   then  
                  if   ((PSMem^.HWndSpy   =   PSMem^.HRevWnd)   and   (PCWPRetStruct(lp)^.message   <>   WM_COPYDATA))  
                      or   (PSMem^.HWndSpy   <>   PSMem^.HRevWnd)   then  
                  begin  
                      New(LMsgInfo);  
                      LMsgInfo^.hwnd   :=   PCWPRetStruct(lp)^.hwnd;  
                      LMsgInfo^.message   :=   PCWPRetStruct(lp)^.message;  
                      LMsgInfo^.wParam   :=   PCWPRetStruct(lp)^.wParam;  
                      LMsgInfo^.lParam   :=   PCWPRetStruct(lp)^.lParam;  
                      LMsgInfo^.pt   :=   Point(0,   0);  
                      LMsgInfo^.time   :=   Msg_Null_Value;  
                      LMsgInfo^.lResult   :=   PCWPRetStruct(lp)^.lResult;  
                      LMsgInfo^.MsgType   :=   Msg_Type_Return;  
   
                      //SendData(LMsgInfo);     这条不要  
                      SendMessage(PSMem^.HRevWnd,PCWPRetStruct(lp)^.message,PCWPRetStruct(lp)^.wParam,PCWPRetStruct(lp)^.lParam)     //修改中添加了这条  
                      Dispose(LMsgInfo);  
              end;  
      Result   :=   CallNextHookEx(HWndRetProc,   code,   wP,   lP);  
  end;  
   
  然后,把其他的两个钩子函数都可以去掉,包括安装钩子,只留第三个钩子,  
  呵呵,现在,我在那个单位的程序里输入命令以后,返回的消息,包括字符  
  全部在我的程序中显示了,虽然我没弄明白这些参数的用途,不过也算解决了一个问题  
   
  在我的程序里还得在用消息机制拦截自己进程的消息并处理消息,  
  虽然复杂点,现在也只能这样了

呵呵,分还是我自己拿吧,等以后在有问题在问大家

不要啊,楼主,给偶一点也好嘛,呵呵~~

路过。

路过~~~

楼主不要这么小气嘛

呵呵,分还是我自己拿吧,等以后在有问题在问大家  
  ----------------------------------------------  
  把他性欲给降低!!!!!!!!!!!!!!!

posted on 2009-02-03 09:52 delphi2007 阅读(530) 评论(0)  编辑 收藏 引用
只有注册用户登录后才能发表评论。