想找个朋友讨论一下Delphi中如何把MDI子窗体放在Dll中的问题???
QQ157355095

解决方案 »

  1.   

    最近老是看到问怎么将控件/组件放到dll的帖子。这样当然是可以的,但是有必要吗?有吗?
    将你的这些代码放到一个公用的unit就完了,实在喜欢用动态连接库也可以使用Delphi的运行时包阿,怎么老是喜欢dll?将VCL放到dll本身就有很多问题(否则Borland也不会提出包的概念了)。其实包也就是一个类似dll的库阿。—————————————————————————————————
    宠辱不惊,看庭前花开花落,去留无意;毁誉由人,望天上云卷云舒,聚散任风。
    —————————————————————————————————
      

  2.   

    网络上有很多的例子啊!
    并且我也在作的一个小软件里用这种方法。我这有个修改过的例子,在d6+sp2上成功。
    要得话留个Mail。
      

  3.   

    把MDI放到DLL和一般的窗体放到DLL是一样的啊!!!!只不过就是做的时候设为mdichinld就可以呀...创建的时候再接到主窗口的handle...
      

  4.   

    给你一个例子吧主程序调用代码:
    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.
      

  5.   

    上面的
          AnyiClientDog.Free;
          AnyiClientDog := nil;
        可不要
      

  6.   

    在动态连接库中的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;
      

  7.   

    你应在主程序有一个用来维护子窗体的列表,记录所有已打开的子窗体的名字,还得定义一个全局变量记录当前子窗体(即你要关闭的子窗体)的名字。接收到DLL的消息后,把列表中该窗体的名字删掉,之后在装载下一个动态库时先检查该窗体列表中时候有全局变量对应的窗体名字,如果没有则把这个窗体对应的动态库释放,接着装载下一个DLL,意思就是让你延后释放动态库。