Unit Send_U;InterfaceUses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls;Type
   TForm1 = Class(TForm)
      Button_Post: TButton;
      Procedure Button_PostClick(Sender: TObject);
      Procedure FormCreate(Sender: TObject);
   Private
      { Private declarations }
   Public
      { Public declarations }
   End;Var
   Form1: TForm1;
   Ohwnd: hwnd; //要挂接钩子的窗口的句柄
   Othreadid: dword; //要挂接钩子的线程id
   MyMessage: Uint;
   HookHandle: HHook; //钩子句柄Const
   Key = '计算器';
Implementation{$R *.dfm}//钩子子程
Function TestHookProcfunction(Code: Integer; wParam: longint; lParam: longint): longint; Stdcall;
Begin
   If Code >= 0 Then
   Begin
      If pmsg(lParam)^.message = MyMessage Then
      Begin
         showmessage('已经截获自定义消息');
      End;
   End;
   //挂钩下一个函数
   result := CallNextHookEx(HookHandle, Code, wParam, lParam);
End;Procedure TForm1.Button_PostClick(Sender: TObject);
Begin
   postmessage(Ohwnd, MyMessage, 0, 0);
End;Procedure TForm1.FormCreate(Sender: TObject);
Begin
   MyMessage := RegisterWindowMessage('自定义消息');
   Ohwnd := findwindow(Nil, Key);
   If Ohwnd = 0 Then
   Begin
      showmessage('未找到窗口句柄');
      exit;
   End;
   Othreadid := GetWindowThreadProcessId(Ohwnd, Nil);
   HookHandle := SetWindowsHookEx(WH_GetMessage, @TestHookProcfunction, Hinstance, Othreadid);
End;End.我将这个钩子其挂在xp下的计算器上,但是运行后计算器报错,然后就退出了,请问下是什么原因?

解决方案 »

  1.   

    具我所知應該在DLL裡實現掛鉤.
      

  2.   

    想跨进程Hook, hook部分应该放到dll中
      

  3.   

    呵呵,消息钩子怎么这么用啊!给一个你看看:library Mhook;uses
    Main in 'Main.pas',windows,
    messages,
    Classes,
    sysutils;procedure DLLEntryPoint(dwReason: DWORD);
    begin
    case dwReason of
      DLL_PROCESS_ATTACH: OpenShareData;
      DLL_PROCESS_DETACH: CloseShareData;
    end;
    end;
    exports
    EnableHook,
    DisableHook;
    beginprocExit := ExitProc;
    ExitProc := @HookExit;
    DLLProc := @DLLEntryPoint;
    DLLEntryPoint(DLL_PROCESS_ATTACH);
    end.
    =======================================================================unit Main;interface
    uses
    windows,
    messages,
    Classes,
    sysutils;typePServerData = ^ServerData;
    ServerData = record
      Wnd: HWND;
      UniqueMsgID: Cardinal;
      hHk: HHOOK;
    end;varprocExit: pointer;
    SData: PServerData;
    MapServerHandle: THandle;
    constcMMServerData: PChar = 'ServerMapData';
    function EnableHook(h: HWND): Boolean; stdcall;
    function DisableHook(): Boolean; stdcall;procedure HookExit; far;
    procedure OpenShareData();
    procedure CloseShareData();function GetMsgProc(nCode: integer; wParam, lParam: longint): LRESULT; stdcall;implementationprocedure OpenShareData();
    var
    Size: integer;
    begin
    Size := Sizeof(SData);
    MapServerHandle := CreateFileMapping(DWORD(-1), nil, PAGE_READWRITE, 0, Size,
      cMMServerData);
    SData := MapViewOfFile(MapServerHandle, FILE_MAP_ALL_ACCESS, 0, 0, Size);
    end;
    procedure CloseShareData();
    begin
    UnmapViewOfFile(SData);
    CloseHandle(MapServerHandle);
    end;function EnableHook(h: HWND): Boolean; stdcall;
    begin
    if SData.hHk <> 0 then
    begin
      Result := false;
      exit;
    end;
    SData.Wnd := h;
    SData.UniqueMsgID := RegisterWindowMessage('RWM1');SData.hHk := SetWindowsHookEx(WH_GETMESSAGE, @GetMsgProc, hInstance, 0);Result := SData.hHk <> 0;
    end;function DisableHook(): Boolean; stdcall;
    begin
    //注销挂钩
    Result := false;
    if UnhookWindowsHookEx(SData.hHk) then
    begin
      SData.hHk := 0;
      Result := true;
    end;
    end;procedure HookExit;
    begin
    if SData.hHk <> 0 then
      DisableHook;
    ExitProc := procExit;
    end;
    function GetMsgProc(nCode: integer; wParam, lParam: longint): LRESULT;
    stdcall;
    var
    pInfo: TMsg;
    begin
    if nCode < 0 then
    begin
      Result := CallNextHookEx(hhk, nCode, wParam, lParam);
      exit;
    end;if (nCode = HC_ACTION) and (wParam = PM_REMOVE) then
     begin
      pInfo := TMsg(PMsg(lparam)^);
        if pInfo.message = WM_CLOSE then
        begin
          //做你想做的,不过一般是使用sendmessage来发送消息的
         SendMessage(SData.Wnd, SData.UniqueMsgID, 0, 0);   
        end;
      end;
    Result := CallNextHookEx(hhk, nCode, wParam, lParam);
    end;=======================================================================
    主程序:unit Unit1;interfaceuses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls, ExtCtrls;type
    TForm1 = class(TForm)
      Label1: TLabel;
      Button1: TButton;
      Edit1: TEdit;
      procedure FormCreate(Sender: TObject);
      procedure FormDestroy(Sender: TObject);
    private
      { Private declarations }
      procedure WndProc(var Msg: TMessage); override;
    public
      { Public declarations }
    end;function EnableHook(h: HWND): Boolean; stdcall;
    function DisableHook(): Boolean; stdcall;var
    Form1: TForm1;
    UniqueMsgID: Cardinal;implementation
    function EnableHook; external 'MHook.dll' name 'EnableHook';
    function DisableHook; external 'MHook.dll' name 'DisableHook';
    {$R *.dfm}procedure TForm1.WndProc(var Msg: TMessage);
    var
    ptMousePos: Tpoint;
    begin
    if Msg.msg = UniqueMsgID then
    begin
      GetCursorPos(ptMousePos);
      label1.Caption := 'X:' + inttostr(ptMousePos.X) + '  Y:' + inttostr(ptMousePos.Y);
    end;
    inherited WndProc(Msg); ;
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
    h: HWND;
    begin
    UniqueMsgID := RegisterWindowMessage('RWM1');
    EnableHook(Handle);
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
    DisableHook;
    end;end.