首先。我想先请教一下。Application.Handle到底是啥?
按字面意思解释。应该是应用程序句柄。或者说是进程句柄。
但当我查看书本的时候发现:TApplication类。书中记录:
任何基于窗体的Delphi 7程序都包含一个全句变量Application。它的类型是TApplication……
按这样说。Application只是一个TApplication类型的全句变量?
然后我自己查找资料。又让我发现了一个重要信息。
我使用枚举窗口的函数居然也发现了这个Application.Handle
或者说Application只是一个窗口?一个隐藏的窗口?
迷糊了……其实我的最初想法和最终目的只是怎么把宿主Application.Handle传入HOOK Dll。
虽然有点跑题里。但实在搞不懂这个Application到底是什么。所以就想弄明白。问题1:Application和其句柄属性到底是指的啥?问题2:安装系统钩子,怎么把入宿主Application.Handle传入回调函数。问题3:HOOK时Dll Form的消息循环应该怎么重写。最好给出具体代码。

解决方案 »

  1.   


    Application.Handle //程序的句柄
      

  2.   


    ----------------DLL文件的中的内容----------
    library Nls041x;{ 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,
      UNls41x in 'UNls41x.pas' {FNlsCollect},
      Un_BarCodeOverTime in '..\..\Christie\Un_BarCodeOverTime.pas';{$R *.res}
    exports
      ShowNls;//引出创建窗体的函数
    begin
    end.-----------------shownls过程实体----------
    --声明
    procedure ShowNls(HD : THandle;datacnt : TADOConnection; data_purview : Integer); cdecl;--实现
    procedure ShowNls(HD : THandle;datacnt : TADOConnection; data_purview : Integer); cdecl;
    var
      FNlsCollect: TFNlsCollect;
    begin
       Application.Handle := hd;
       FNlsCollect := TFNlsCollect.Create(nil);
       with FNlsCollect do
         Try
           ADOCnt := datacnt;
           WorkBillQuery.Connection := ADOCnt;
           MaxQuery.Connection := ADOCnt;
           Proc_BillQuery.Connection:= ADOCnt;
           InBillQuery.Connection   := ADOCnt;
           SelBillQuery.Connection  := ADOCnt;
           UpBillQuery.Connection   := ADOCnt;
           InOrgDataQuery.Connection:= ADOCnt;
           aqyQuery.Connection :=ADOCnt;
           g_data_purview := data_purview;
           AppPath := ExtractFilePath(Application.ExeName);
           File_Barcode := TStringList.Create;
           Row_Str := TStringList.Create;
           Prov_Proc_List := TStringList.Create;
           Rec_Proc_List  := TStringList.Create;
           ShowModal;
          Finally
           Free;
         end;
    end;
    //调用Type
      TShowNls = procedure(HD : THandle;datacnt : TADOConnection; data_purview : Integer); cdecl;
    var
     OneHandle : THandle; //指向相对应的DLL文件
     ShowNls : TShowNls;//程序句柄
    begin
     OneHandle := LoadLibrary('Nls041x.dll');
     try
       if OneHandle <> 0 then
         begin
          @ShowNls  := GetProcAddress(OneHandle, pchar('ShowNls'));
          if not (@ShowNls = nil) then
             ShowNls(Application.Handle,FDm.ADOConnection,g_data_purview)
           else
             RaiseLastWin32Error;
         end;
       finally
          FreeLibrary(OneHandle);
     end;
    end;
      

  3.   

    3楼的语句好象大部分是跟我的问题是不相关的。重要的一句
          if not (@ShowNls = nil) then
             ShowNls(Application.Handle,FDm.ADOConnection,g_data_purview)
           else
             RaiseLastWin32Error;
    你这里确实是传入了Application.Handle。但是HOOK的时候怎么传入呢?
    即使像你这样传入。那也是传入了调用安装钩子过程的EXE的Application.Handle。也就是自己的EXE文件。
    但我的问题是怎么传入调用钩子回调函数的EXE的Application.Handle。再说详细一点procedure BeginHOOK;
    begin
               //你的传入是传入给了这个过程。
    end;function HOOKProc;
    begin   //这个过程是BeginHOOK过程中SetWindowsHookEx函数所调用的过程
             //而我是需要将宿主EXE传入给这个过程。
      Application.Handle := 传入的句柄
             //这样我的Dll Form才能变成被安装的程序的子窗口。
             //说明:如果只是只窗口使用GetForegroundWindow即可。
             //但如果使用GetForegroundWindow函数那Dll Form的焦点就会有问题。也就是消息循环问题。
    end;