开发时需要用到第三方的DLL,其中封转了一些方法和事件,目前dll的方法可以调用,但事件不能调用。
我想问一下如何才能捕捉到dll中事件,用钩子么?

解决方案 »

  1.   

    如果dll提供事件参数的话,事件要用回调,自己定义一个相同参数类型的事件类型,然后把指针传递给dll
      

  2.   

    Delphi與dll中使用回呼函數示例.........
    interface uses 
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
      Dialogs, StdCtrls; type 
      TForm1 = class(TForm) 
        Button1: TButton; 
        ListBox1: TListBox; 
        Button2: TButton; 
        procedure Button1Click(Sender: TObject); 
        procedure Button2Click(Sender: TObject); 
      private 
        { Private declarations } 
      public 
        { Public declarations } 
      end; 
      type PFCALLBACK = function(Param1:integer;Param2:integer):integer;stdcall; 
    // 定義回呼函數的類型 
    var 
      Form1: TForm1; 
      gCallBack:PFCALLBACK; 
      function CBFunc(Param1:integer;Param2:integer):integer;stdcall; 
    implementation 
    //回呼函數需要定義為全域 
    {$R *.dfm} 
    ///實現回呼函數的功能 
    function CBFunc(Param1:integer;Param2:integer):integer; 
    var i:integer; 
    begin 
    //messagebox(application.Handle,'回呼函數','提示資訊',mb_ok); 
    for i:=0 to 100 do 
    begin 
    sleep(100); 
    self.ListBox1.Items.Add('回呼函數'); 
    end; 
    end; 
    /// 
    function MyThreadFunc(P:pointer):Longint;stdcall; 
    begin 
    gCallBack(0,1);//簡單傳個參數 
    end; 
    procedure testpro ; 
    var i:integer; 
      hThread:Thandle;//定義一個控制碼 
      ThreadID:DWord; 
    begin 
    for i:=0 to 4 do 
    begin 
    messagebox(application.Handle,'123','提示資訊',mb_ok); 
    if (i=2) then 
    begin 
    hthread:=CreateThread(nil,0,@MyThreadfunc,nil,0,ThreadID);//利用這種執行緒怎麼說呢,肯定方便啦,但是 
    //肯定功能上受到好多限制,所以啊,自己寫,下次貼個上來 
    end; 
    end; 
    end; 
    /// 
    function TestCallBack( Func:PFCALLBACK ):integer; 
    begin 
    gCallBack:=Func; 
    testpro; 
    end; 
    procedure TForm1.Button1Click(Sender: TObject); 
    begin 
    //testpro; 
    TestCallBack(@CBFunc); 
    end; 
    procedure TForm1.Button2Click(Sender: TObject); 
    begin 
    self.ListBox1.Clear; 
    end; 
    end. 
    使用回呼函數需要注意的地方: 
    type PFCALLBACK = function(Param1:integer;Param2:integer):integer;stdcall; 
    // 定義回呼函數的類型 
    function CBFunc(Param1:integer;Param2:integer):integer;stdcall; 
    //全域函式定義,指向函數的函數,指標!!!名字可以隨便取,但參數之類的需要與定義 
    //的函數類型一致。 
    function CBFunc(Param1:integer;Param2:integer):integer; 
    //寫該函數體就沒什麼好說拉 
    function TestCallBack( Func:PFCALLBACK ):integer; 
    //傳遞回呼函數的入口地址,最重要啦!
      

  3.   

    什麼也不說了,我直接上代碼
    unit Unit1;
    interface
    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls;
    type
    THDProcedure=procedure(s:string); stdcall;
    Tfsdajk = function (RecvBack:THDProcedure):integer;StdCall;
    TForm1 = class(TForm)
        Button2: TButton;
        procedure FormCreate(Sender: TObject);
        procedure Button2Click(Sender: TObject);
    private
        { Private declarations }
    public
        { Public declarations }
    end;var
    Form1: TForm1;
    DLLHandle:THandle;
    procedure HdProExample(sExam:string);stdcall;
    implementation
    {$R *.dfm}
    procedure HdProExample(sExam:string);stdcall; 
    begin
    ShowMessage(sExam);
    end;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    DLLHandle   :=   LoadLibrary(PChar('Project.dll'));
    end;
    procedure TForm1.Button2Click(Sender: TObject);
    var
    D:   String;
    Func:   Tfsdajk;
    begin
    @Func   :=   GetProcAddress(DLLHandle,   'loadDllA');
    if   Assigned(@Func)   then
    begin
        Func(@HdProExample);
    end;
    end;
    end.
    dll部分:
    library Project;
    { 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;
    type
    THDProcedure=procedure(s:string); stdcall;
    var
        fsda : THDProcedure;
    {$R *.res}
    function loadDllA(RecvBack:THDProcedure):integer;StdCall;
       begin
          @fsda := @RecvBack;
          fsda(PChar('fdasfd'));
       end;
    exports
    loadDllA Name 'loadDllA';
    begin
    end.
    如果想在主程序中的“HdProExample”使用主程序中的方法的話要加表單名哦例如:
    procedure HdProExample(sExam:string);stdcall;
    begin
       Form1.ExeSQL(sExam);//我傳回來的是SQL語句所以我用到了Fom1中的ExeSQL。
    end;
      

  4.   

    多谢kye_jufei啦,问题解决了。