自己做了一个动态连接库,要求另一个应用程序调用连接库时传入一个窗体form的Handle,使调用后Dll中生成的窗体成为传入窗体form的子窗体,如何实现,谢谢!

解决方案 »

  1.   

    function   LoadModule(ALibraryName:   String;   AFunc_ID:   ShortString;   AImplementType:   String;     AConnect:   TSocketConnection):   Boolean;   
      var   
              CallModule:   TAiCallModule;   
              sFilePath   :   string;   
              sFuncVersion:   string;   
        
              strExePath,sFileName:string;iPos:   Integer;   
      begin   
          if   not   ExistLibraryHandle(ALibraryName)   then   
          begin   
              LibHandle   :=   LoadLibrary(PChar(ALibraryName));   
              if   LibHandle   <>   0   then   
                  LibHandleList.Add(ALibraryName   +   ':'   +   IntToStr(LibHandle));   
          end;   
            
          @CallModule   :=   GetProcAddress(LibHandle,'AiCallModule');   
          if   @CallModule   <>   nil   then   
          begin   
              if   not   CallModule(AFunc_ID,Application)   then   
              begin   
                  Result   :=   False;   
                  Exit;   
              end;   
          end;   
          Result   :=   True;   
      end;   
        
        
        
      DLL代码:   
        
      procedure   DLLEntryPoint(dwReason:   DWord);   
      begin   
          case   dwReason   of   
              DLL_PROCESS_ATTACH:   
              begin   
                  GAppSave   :=   Application;   
              end;   
              DLL_PROCESS_DETACH:   
              begin   
                  Application   :=   GAppSave;   
                  AnyiClientDog.Free;   
                  AnyiClientDog   :=   nil;   
              end;   
          end;   
      end;   
        
        
      function   AiCallModule(AFunc_ID:   ShortString;   AppHandle:   TApplication):   Boolean;   stdcall;export;   
      begin   
              Result   :=   False;   
              Application   :=   AppHandle;   
              if   AFunc_ID   =   AFunc_ID_Log   then   
              begin   
                      if   Application.FindComponent('FormLog')   =   nil   then   
                      begin   
                          FormLog   :=   TFormLog.Create(Application);   
                      end;   
                      FormLog.Show;   
                      Result   :=   True;   
              end;   
      end;   
        
      procedure   AiFreeModule(AFunc_ID:   ShortString);   stdcall;   export;   
      begin   
              if   AFunc_ID   =   AFunc_ID_Log   then   
              begin   
                    if   Application.FindComponent('FormLog')   <>   nil   then   
                              FormLog.Close;   
              end;   
      end;   
        
        
      exports   
              AiCallModule,   
              AiFreeModule;   
      begin   
              DllProc   :=   @DLLEntryPoint;   
              DLLEntryPoint(DLL_PROCESS_ATTACH);   
      end. Top
    7楼  Liusp   (夜深千帐灯)   回复于 2003-01-10 09:02:23  得分 0 
    上面的   
                  AnyiClientDog.Free;   
                  AnyiClientDog   :=   nil;   
              可不要 Top
    8楼  cg1120   (代码最优化-§惟坚韧者始能遂其志§)   回复于 2003-01-10 09:06:21  得分 0 
    在动态连接库中的MDI子窗体:   
        
      library   MDIDll;   
      var     
          SaveDLLApp:TApplication;   
        
      procedure   ShowMDIChildForm(MainApp:TApplication);   
      var     
          Child:TMDIForm;   
      begin   
          if   not   Assigned(SaveDllApp)   then   
          begin   
              SaveDllApp:=Application;   
              Application:=MainApp;   
          end;   
          Child:=TMDIForm.Create(Application.MainForm);   
          Child.Show;   
      end;   
        
      procedure   MyLibraryProc(Reason:integer);   
      begin   
          if   Reason=DLL_PROCESS_DETACH   then   
              if   Assinged(SaveDllApp)   then   
                  Application:=SaveDllApp;   
      end;   
        
      export   ShowMDIChildForm;   
        
      begin   
          DllProc:=@MyLibraryProc;   
      end.                         
        
      在调用dll的应用中,用下述方法生MDI窗体;   
          procedure   Form1.Button1Click(Sender:Tobject);   
          begin   
              ShowMDIChildForm(Application);   
          end;   
      是这个吗?
      

  2.   

     function  AiCallModule(AFunc_ID:  ShortString;  AppHandle:  TApplication):  Boolean;  stdcall;export;接入函数的参数AppHandle不是  TApplication类型,而是THandle,它是传入的父窗体的Handle,该怎么处理啊?
      

  3.   


    procedure TForm1.Button2Click(Sender: TObject);
    type 
      TIntFunc=function(i,j:integer):integer;stdcall;
    var 
      Th:Thandle;
      Tf:TIntFunc;
      Tp:TFarProc;
    begin 
      Th:=LoadLibrary('E:\动态载入Dll\D2\DTK2.dll'); {装载DLL}
      if Th>0 then
      try
        Tp:=GetProcAddress(Th,PChar('Max2'));
        if Tp<>nil then
        begin
          Tf:=TIntFunc(Tp);
          Edit1.Text:=IntToStr(Tf(66,77)); {调用函数}
        end
        else
          ShowMessage('函数没有找到');
      finally
        FreeLibrary(Th); {释放DLL}
      end
      else
      ShowMessage('dll没有找到');   
    end;
      

  4.   

    kampan
    amdwinter 
    你们的回答我看不懂
    我再描述一下我的问题,比方说DLL中的接入函数为
    function DllFunc(aHandle: THandle; aOther: Integer): THandle; external
    aHandle为外部调用此函数的窗体的Handle,要求DllFunc函数中生成一个Form,使它为外部调用此函数的窗体的子窗体外部调用为:
    procedure TForm1.bbb1Click(Sender: TObject);
    var
      aInterRec: Integer;
    begin
      
      DllFunc(Form1.Handle, aInterRec);
    end;
      

  5.   

    你怎么搞得这么啰嗦啊(我不知道你传一大堆参数都是干嘛的),你在动态库里动态创建一个窗体,设置FormStyle 为fsMDIChild ,关闭时别忘了释放,然后生成一个Dll动态库,接着程序直接调用应该就行了吧,我自己没试,你自己试试吧
      

  6.   

    Dll的功能:传入指定窗体Form1的Handle,生成一个Form1的子窗体上面这段
    procedure TForm1.Button2Click(Sender: TObject);
    type 
      TIntFunc=function(i,j:integer):integer;stdcall;
    var 
      Th:Thandle;
      Tf:TIntFunc;
      Tp:TFarProc;
    begin 
      Th:=LoadLibrary('E:\动态载入Dll\D2\DTK2.dll'); {装载DLL}
      if Th>0 then
      try
        Tp:=GetProcAddress(Th,PChar('Max2'));
        if Tp<>nil then
        begin
          Tf:=TIntFunc(Tp);
          Edit1.Text:=IntToStr(Tf(66,77)); {调用函数}
        end
        else
          ShowMessage('函数没有找到');
      finally
        FreeLibrary(Th); {释放DLL}
      end
      else
      ShowMessage('dll没有找到');   
    end;
    和我的问题有什么关系!
      

  7.   

    1樓已經給出答案了,不過,你要傳主程序application的handle
      

  8.   

    Avan_Lau :
    可是我要使之成为某个窗体的子窗体,
    接入函数的参数aHandle: THandle; aHandle实际上是要生成的子窗体的父窗体的Handle
    传主程序application的handle,这样的话怎么才能生成主程序的某个窗体的子窗体呢?谢谢!
    这个问题可以概括为
    1、procedure  ShowMDIChildForm(MainApp:TApplication);  
    如果参数是MainApp:TApplication,用一楼的方法没错,实际上它是生成了主程序application的主窗体MainForm的子窗体,如果主程序application还有其它窗体Form2,我想生成Form2的子窗体该怎么办呢?
    2、procedure  ShowMDIChildForm(pForm:THandle);
    如果参数是pForm:THandle,调用的时候用ShowMDIChildForm(Form1.Handle),生成Form1的子窗体该怎么做呢?
    Dll里的函数procedure  ShowMDIChildForm(pForm:THandle);怎么写呢?
    最好帖出代码,谢谢大家了不知我这样描述算不算清楚?
      

  9.   

    了解你的意思了。
    採用1方法,可以避免任務欄出現兩個兩個圖標,然後可以調用api: setparent,就可以達到你的目的了。不知是否符合你的要求?
      

  10.   

    我觉得关键在setparent,给它指定父窗体,谢谢!