解决方案 »

  1.   

    将 panel 设置为 新窗体的父窗体。procedure  CreateNewFormClass(NewFormClass:TFormClass;
      var NewForm; Panel:TPanel);
    var
      frNewForm : TForm ;
    begin
      try
        if NewFormClass = nil then Exit ;
        Panel.Visible            := False ;
        Panel.Align              := alClient ;    IsPanelExistForm(Panel) ;  //检测下看panel里面是否有别的窗体,有就kill掉。    frNewForm                := TForm(NewForm) ;
        frNewForm                := NewFormClass.CreateParented(Panel.Handle);
        frNewForm.BorderStyle    := bsNone ;
        frNewForm.Parent         := Panel ;
        frNewForm.Align          := alClient ;
        frNewForm.Show ;    Panel.Visible            := True ;
      finally
      end;
    end;调用:CreateNewFormClass(Txxx,  xxx,  plShow);我使用以上方式创建新窗体到panel的。
    不知道换成DLL的窗体,能不能成,我没给你测试。
      

  2.   


    frNewForm.Parent         := Panel ;
    使用这种方法来用panel加载窗体,会导致窗体上的组件无法获得焦点,无法操作
    应该用windows.setparent函数来设置窗体的容器
      

  3.   


    windows.setparent函数 我没用过.不过我好像没发现窗体上组件无法获得焦点的问题額~我程序里面窗体这么申请后,  操作是正常的.   
      

  4.   

    直接显示我也能做,但是做成dll的我这不行呢。待会试试你这个方法
      

  5.   

    你做过dll窗体显示在panel中吗?给指导指导?
      

  6.   

    我的测试代码
    在主窗体中procedure TUnit_main.Button1Click(Sender: TObject);
    type
        mypointer=Procedure(ahand:THandle;panel1:TPanel);stdcall;
    var
        Handle:THandle;
        frm_p:mypointer;
    begin
        Handle:=loadlibrary('Project2.dll');
        if Handle>32 then
        begin
            @frm_p:=GetProcAddress(Handle,'ShowTest');
            if @frm_p<>nil then frm_p(Panel1.Handle,Panel1);
        end;
        Freelibrary(Handle);
    end;
    dll工程中
    procedure ShowTest(ahand:THandle;panel1:TPanel);stdcall;   //dll函数 用于显示窗体
    var
        f:TForm2;
    begin
        f:=TForm2.Create(nil);
        try
            f.ParentWindow:=ahand;
            f.ShowModal; //使用ShowModal 能在主窗体显示 但是处于有膜状态,不能操作。。
            f.Show;//使用show报内存错误
        except
            f.Free;
        end;
    end;
      

  7.   

    你在dll中的ShowTest使用show
    随后就在主程序中Freelibrary估计是这里释放正在加载的dll导致的错误
      

  8.   

    恩是的 就是这的问题,可以了。但是像这样的话,如果再加载其他dll窗体的话,怎么指导现在panel中显示的事哪个窗体 或者是加载的哪个dll  怎么释放相应的dll呢?  
      

  9.   

    恩是的 就是这的问题,可以了。但是像这样的话,如果再加载其他dll窗体的话,怎么指导现在panel中显示的事哪个窗体 或者是加载的哪个dll  怎么释放相应的dll呢?  用变量记录下当前显示的是哪个窗体
    如果窗体多,可以记录到数组或TStringlist里
    已加载的dll也同样需要记录释放dll要根据程序的需要来操作
    可以在关闭panel所在的窗体时释放所有已经记录的已加载的dll
      

  10.   

    用TStringlist保存? 只能保存字符串啊  怎么保存dll的句柄Handle呢?FreeLibrary(Handle) 这个free是需要句柄的呀
      

  11.   

    用TStringlist保存? 只能保存字符串啊  怎么保存dll的句柄Handle呢?FreeLibrary(Handle) 这个free是需要句柄的呀
    string类型与int类型可以互相转换的
      

  12.   

    记录Handle 和窗体 ,先把dll窗体逐个free  然后在逐个FreeLibrary(Handle)  dll?
      

  13.   

    在FormDestroy 中free的  提示内存错误呢, 不需要挨个free  调用的dll窗体吗?
    procedure TUnit_main.FormDestroy(Sender: TObject);
    var i:Integer;
    begin
        for I := 0 to dllHList.Count - 1 do
        begin
            FreeLibrary(strtoint(dllHList[i]));
        end;
    end;  最后报错
      

  14.   

    在FormDestroy 中free的  提示内存错误呢, 不需要挨个free  调用的dll窗体吗?
    procedure TUnit_main.FormDestroy(Sender: TObject);
    var i:Integer;
    begin
        for I := 0 to dllHList.Count - 1 do
        begin
            FreeLibrary(strtoint(dllHList[i]));
        end;
    end;  最后报错不能在dll自己的窗体内FreeLibrary
    要在主窗体中FreeLibrary
      

  15.   

    我就是在主窗体中FreeLibrary的
    你邮箱多少?我把测试代码发给你帮我看看?谢谢了啊