我向我的dll程序里面传进一个tform类型的参数,
如果在钩子回调里面使用就会让钩子失效掉,这是为什么?应该怎么改?
代码如下:
unit QQTitleHook;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, CommCtrl, StrUtils;
  
var
  hkQQChat: HHOOK;
  hwQQChat: HWnd ;
  kid: Integer;
  hwQQChatChild: HWnd;
  hwQQChatChildNext: HWnd;
  tlQQChat: string;
  clsName: string;
  hGlobal: THandle; 
  msgBoxGlobal: THandle;
  msgSendButtonGlobal: THandle;
  pText,pGlobal: Pchar;
  ppText: array [0..255] of char;
  buf: array [0..1024] of char;
  OldProc:pointer;  mhandle,keyhandle:integer;
  Form1: TForm;
  
  const
    csQQ = '#32770';  Function showMsgF8Proc(iCode,wParam,lParam:Integer):LRESULT;stdcall;export;
  function EnableWheelHook(f: TForm) : Boolean; stdcall; export;
  function DisableWheelHook: Boolean; stdcall; export;implementation  Function showMsgF8Proc(iCode,wParam,lParam:Integer):LRESULT;stdcall;export;
  const
    _KeyPressMask=$80000000;
  begin
  if ((lParam and _KeyPressMask) = 0) and (wParam = Vk_F5) then
  begin
    Form1.Show;
    //SetWindowPos(Form1.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW or SWP_NOMOVE or SWP_NOSIZE);
    ShowMessage('F5');
    //Form1.Show;
    Result:=1;
    Exit;
  end;
  if ((lParam and _KeyPressMask) = 0) and (wParam = Vk_F6) then
  begin
    Form1.Hide;
    ShowMessage('F6');
    //Form1.Hide;
    Result:=1;
    Exit;
  end;
  if ((lParam and _KeyPressMask) = 0) and (wParam = Ord('0')) then
  begin
    ShowMessage('0');
    Result:=1;
    Exit;
  end;
  Result:= CallNextHookEx(keyhandle, iCode, wParam, lParam);
  end;
  function EnableWheelHook(f: TForm): Boolean; stdcall; export;
  begin
    if hkQQChat=0 then
    begin
      Form1 := f;
      keyhandle := SetWindowsHookEx(WH_KEYBOARD,@showMsgF8Proc, HINSTANCE,0);
      Result := True;
    end
    else
      Result := False;
    end;
  function DisableWheelHook: Boolean; stdcall; export;
  begin
    if keyhandle<>0 then
    begin
      UnHookWindowsHookEx(keyhandle);
      keyhandle := 0;
    end;
    Result := True;
  end;
  end.

解决方案 »

  1.   

    传Form不太好,你最好传HWND这样的类型参数.
      

  2.   

    如果传form的句柄要在dll内部修改form得用什么方法?
      

  3.   

    SendMessage
    或者PostMessage
    或者传递一个函数指针什么的.
    总之不要传递C中没有的类型.
    不然莫名其妙的问题谁也帮不了你.
      

  4.   

    我把之前的方式改成了在dll通过消息来控制form,但是现在问题也出来了,当不聚焦于MainForm那个窗体的时候,
    form.show是失效的,应该是传进去的handle有莫名其妙的东西,应该怎么办?
    我作了如下修改:
    **** dll ****unit QQTitleHook;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, CommCtrl, StrUtils;
    const
      MY_MOVE=WM_USER+100;
      MY_SHOW=WM_USER+101;
      MY_HIDE=WM_USER+102;
      
    var
      hkQQChat: HHOOK;
      hwQQChat: HWnd ;
      kid: Integer;
      hwQQChatChild: HWnd;
      hwQQChatChildNext: HWnd;
      tlQQChat: string;
      clsName: string;
      hGlobal: THandle; 
      msgBoxGlobal: THandle;
      msgSendButtonGlobal: THandle;
      pText,pGlobal: Pchar;
      ppText: array [0..255] of char;
      buf: array [0..1024] of char;
      OldProc:pointer;  mhandle,keyhandle:integer;
      Form1Handle: THandle;  const
        csQQ = '#32770';  function showMsgProc(icode:integer;wparam:wparam;lparam:lparam):LRESULT;stdcall;export;
      Function showMsgF8Proc(iCode,wParam,lParam:Integer):LRESULT;stdcall;export;
      function EnableWheelHook(f: THandle) : Boolean; stdcall; export;
      function DisableWheelHook: Boolean; stdcall; export;implementation
      function showMsgProc(icode:integer;wparam:wparam;lparam:lparam):LRESULT;stdcall;export;
      begin
        SendMessage(Form1Handle,MY_MOVE,mouse.CursorPos.X,mouse.CursorPos.Y);
        Result := CallNextHookEx(mhandle,iCode,wParam,lParam);
      end;
      Function showMsgF8Proc(iCode,wParam,lParam:Integer):LRESULT;stdcall;export;
      const
        _KeyPressMask=$80000000;
      begin
      if ((lParam and _KeyPressMask) = 0) and (wParam = Vk_F5) then
      begin
        SendMessage(Form1Handle,MY_SHOW,0,0);
        Result:=1;
        Exit;
      end;
      if ((lParam and _KeyPressMask) = 0) and (wParam = Vk_F6) then
      begin
        SendMessage(Form1Handle,MY_HIDE,0,0);
        Result:=1;
        Exit;
      end;
      Result:= CallNextHookEx(keyhandle, iCode, wParam, lParam);
      end;
      function EnableWheelHook(f: THandle): Boolean; stdcall; export;
      begin
        if hkQQChat=0 then
        begin
          Form1Handle := f;
          keyhandle := SetWindowsHookEx(WH_KEYBOARD,@showMsgF8Proc, HINSTANCE,0);
          mhandle := SetWindowsHookEx(WH_JOURNALRECORD,@showMsgProc, HINSTANCE ,0);
          Result := True;
        end
        else
          Result := False;
        end;
      function DisableWheelHook: Boolean; stdcall; export;
      begin
        if mhandle <>0 then
        begin
          UnHookWindowsHookEx(mhandle);
          mhandle := 0;
        end;
        if keyhandle<>0 then
        begin
          UnHookWindowsHookEx(keyhandle);
          keyhandle := 0;
        end;
        Result := True;
      end;
      end.
    *** 调用一方 ***unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls ,Ui;type
      TFormMain = class(TForm)
        Button1: TButton;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      FormMain: TFormMain;
      function EnableWheelHook(f: THandle):Boolean; stdcall; external 'Hookprj.dll' name 'EnableWheelHook';
      function DisableWheelHook:Boolean; stdcall; external 'Hookprj.dll' name 'DisableWheelHook';implementation{$R *.dfm}procedure TFormMain.Button1Click(Sender: TObject);
    begin
      if EnableWheelHook(Form1.Handle) then
      begin
        ShowMessage('启动钩子成功');
      end;
    end;procedure TFormMain.Button2Click(Sender: TObject);
    begin
      DisableWheelHook;
      Form1.Close;
    end;end.
    **** TForm1 类 *****unit Ui;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Menus, ComCtrls;
    const
      MY_MOVE=WM_USER+100;
      MY_SHOW=WM_USER+101;
      MY_HIDE=WM_USER+102;type
      TForm1 = class(TForm)
      Label1: TLabel;
      procedure onCreate(Sender: TObject);
    private
        { Private declarations }
      procedure MYMessageMove(var Msg:TMessage);message MY_MOVE;
      procedure MYMessageShow(var Msg:TMessage);message MY_SHOW;
      procedure MYMessageHide(var Msg:TMessage);message MY_HIDE;
    public
        { Public declarations }
      end;var
      Form1: TForm1;
    implementation{$R *.dfm}
    //自写函数procedure TForm1.onCreate(Sender: TObject);
    begin
        Label1.AutoSize := true;
        Form1.AlphaBlend := true;
        Form1.AlphaBlendValue := 150;
        Form1.BorderStyle := bsNone;
        Form1.Width := Label1.Width + 20;
        Form1.Height := Label1.Height + 10;
    end;
    procedure TForm1.MYMessageMove(var Msg:TMessage);
    begin
        Form1.Left := Msg.WParam+ 10;
        Form1.Top:= Msg.LParam - Form1.Height;
    end;
    procedure TForm1.MYMessageShow(var Msg:TMessage);
    begin
        Form1.Show;
        Form1.FormStyle := fsStayOnTop;
    end;
    procedure TForm1.MYMessageHide(var Msg:TMessage);
    begin
        Form1.Hide;
    end;end.
      

  5.   


    function showMsgProc(icode:integer;wparam:wparam;lparam:lparam):LRESULT;stdcall;export;
      begin
        SendMessage(Form1Handle,MY_MOVE,mouse.CursorPos.X,mouse.CursorPos.Y);
        Result := CallNextHookEx(mhandle,iCode,wParam,lParam);
      end;
      Function showMsgF8Proc(iCode,wParam,lParam:Integer):LRESULT;stdcall;export;
      const
        _KeyPressMask=$80000000;
      begin
      if ((lParam and _KeyPressMask) = 0) and (wParam = Vk_F5) then
      begin
        SendMessage(Form1Handle,MY_SHOW,0,0);
        Result:=1;
        Exit;
      end;
      if ((lParam and _KeyPressMask) = 0) and (wParam = Vk_F6) then
      begin
        SendMessage(Form1Handle,MY_HIDE,0,0);
        Result:=1;
        Exit;
      end;
      Result:= CallNextHookEx(keyhandle, iCode, wParam, lParam);
      end;失去焦点后Form1Handle的值变立马变成了0,因该怎么办?