dll文件中:TFrameClass = class of TFrame   ;
function GetDllFrameClass(App:THandle;frm:THandle):TFrameClass;stdcall;
implementation{$R *.dfm}
function GetDllFrameClass(App:THandle;frm:THandle):TFrameClass;stdcall;
begin
  Result:=TFrame1;
end;主程序调用:  type
  TFrameClass = class of TFrame;
  //注意   必须是class of TFrame而不是 class(TFrame)
  //class of TFrame  声明的是类类型   f:TFrameClass是一个类
  //class(TFrame) 是声明一个类, 这个类继承了TFrame类 f: TFrame; 是一个对象
 TGetDllFrameClass = function (App:THandle;frm:THandle):TFrameClass;stdcall;
var
 TMP:TFrameClass;
 tmp2:TFrame;procedure TForm1.btn1Click(Sender: TObject);
begin
DLLHandle := LoadLibrary('DLL.dll');
     try
      @GetDllFrameClass := GetProcAddress(DLLHandle, 'GetDllFrameClass');
      if @GetDllFrameClass = nil then
        Abort;
        tmp:=GetDllFrameClass(application.Handle,Self.Handle);
       tmp2:=TMP.Create(self);
       tmp2.Parent:=pnl1;
      tmp2.Show;
   except
         raise;
    end;
end;

解决方案 »

  1.   

    运行时总是提示:
    ---------------------------
    Project Main.exe raised exception class EInvalidOperation with message 'Control 'Frame1' has no parent window'.什么原因,Frame1的parent是panel呀.
      

  2.   

    问题好像处在红色部分:
    tmp:=GetDllFrameClass(application.Handle,Self.Handle);
    TFrame不能成为window类.
      

  3.   

    将这里tmp2:=TMP.Create(self); 
    改为tmp2:=TMP.Create(nil);试试 
      

  4.   

            tmp:=GetDllFrameClass(application.Handle,Self.Handle); //tmp已经获取了指针,被创建
           tmp2:=TMP.Create(self); //tmp又创建了一次
      

  5.   

    将这里tmp2:=TMP.Create(self);  
    改为tmp2:=TMP.Create(nil);试试  我改了,还是提示这个错误呀
      

  6.   

    这一句:'Control 'Frame1' has no parent window',意为:控件'Frame1'没有父窗口.
    我是了一下:procedure TForm2.btn2Click(Sender: TObject);
    var
      fm: TFrame;
    begin
      fm:= TFrame.Create(nil);
      fm.Parent:= Form2;
      edt1.Text:=  fm.Parent.ClassName
    end;
    没有问题.
    当然,我没用到动态链接库.
      

  7.   

    Dll.dll文件内容:
    library Dll;uses
      SysUtils,
      Classes,
      Unit2 in 'Unit2.pas' {Frame1: TFrame},{$R *.res}exports  GetDllFrameClass;
    begin
    end.其中Unit2文件:
    unit Unit2;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
      Dialogs, StdCtrls, ExtCtrls;type
      TFrame1 = class(TFrame)
        lbl1: TLabel;
        btn1: TButton;
        mmo1: TMemo;
      private
        { Private declarations }
      public
        { Public declarations }
      end;TFrameClass = class of TFrame   ;
    function GetDllFrameClass(App:THandle;frm:THandle):TFrameClass;stdcall;
    //function GetDllFrameClass(App:THandle;frm:TPanel):TFrameClass;stdcall;
    implementation{$R *.dfm}
    function GetDllFrameClass(App:THandle;frm:THandle):TFrameClass;stdcall;
    begin
    //传进来的参数原来是为了和主程序沟通,不是必要的,这里就不管它了
    Result:=TFrame1;
    end;end.
      

  8.   

    主文件Main.dpr
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, StdCtrls;  type
      TFrameClass = class of TFrame;
      //注意   必须是class of TFrame而不是 class(TFrame)
      //class of TFrame  声明的是类类型   f:TFrameClass是一个类
      //class(TFrame) 是声明一个类, 这个类继承了TFrame类 f: TFrame; 是一个对象
     TGetDllFrameClass = function (App:THandle;frm:THandle):TFrameClass;stdcall;
    //TGetDllFrameClass = function (App:THandle;frm:TPanel):TFrameClass;stdcall;
    type
      TForm1 = class(TForm)
        btn1: TButton;
        pnl1: TPanel;
        btn2: TButton;
        procedure btn1Click(Sender: TObject);
      private
        { Private declarations }
        DLLHandle: THandle;
        GetDllFrameClass: TGetDllFrameClass;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation
    var
     TMP:TFrameClass;
     tmp2:TFrame;{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
    begin
    DLLHandle := LoadLibrary('DLL.dll');
         try
          @GetDllFrameClass := GetProcAddress(DLLHandle, 'GetDllFrameClass');
          if @GetDllFrameClass = nil then
            Abort;
            tmp:=GetDllFrameClass(application.Handle,self.handle);       tmp2:=TMP.Create(nil);      // tmp2.Parent:=pnl1;
           // tmp2.Show;
            tmp2.Parent:=Form1.pnl1;
          tmp2.Show;
       except
             raise;
        end;
    end;
      

  9.   

    点击按钮后,运行时总是提示: 
    --------------------------- 
    Project Main.exe raised exception class EInvalidOperation with message 'Control 'Frame1' has no parent window'. 什么原因,Frame1的parent是panel呀.
      

  10.   

    我一般不直接从DLL中引出对象,而是通过接口。
      

  11.   

    建议使用Form代替Frame; 
    使用接口导出DLL中的类; -----------------------DLL Project------------------ unit uIDllTest;  //接口单元 interface uses 
      Windows; type { IDllTest }   IDllTest = interface 
      ['{A9E86459-F169-4C3F-AE9B-94CD7B4700F3}'] 
        procedure mergeTo(parentWin: THandle; rect: TRect); stdcall; 
      end; implementation end. 
    unit uDllTest;  //实现IDllTest接口 interface uses 
      SysUtils, DllFrm, uIDllTest, Windows, Controls, Forms; type { TDllTest }   TDllTest = class(TInterfacedObject, IDllTest) 
      private 
        FDllFrm: TfrmDll; 
      protected 
        procedure mergeTo(parentWin: THandle; rect: TRect); stdcall; 
      public 
        constructor Create; 
        destructor Destroy; override; 
      end; function CreateDllTest: IDllTest; stdcall;  //Dll导出函数 exports 
      CreateDllTest;   implementation function CreateDllTest: IDllTest; stdcall; 
    begin 
      Result := TDllTest.Create; 
    end; { TDllTest } constructor TDllTest.Create; 
    begin 
      inherited Create; 
      FDllFrm := TfrmDll.Create(nil); 
      with FDllFrm do 
      begin 
        BorderStyle := bsNone;         
      end; 
    end; destructor TDllTest.Destroy; 
    begin 
      FDllFrm.Free; 
      inherited Destroy; 
    end; procedure TDllTest.mergeTo(parentWin: THandle; rect: TRect); 
    begin 
      FDllFrm.ParentWindow := parentWin; 
      FDllFrm.SetBounds(0, 0, rect.Right - rect.Left, rect.Bottom - rect.Top); 
    end; end. 
    -------------------------调用------------------------ unit Unit1; interface uses 
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
      Dialogs, uIDllTest, ExtCtrls; type 
      TForm1 = class(TForm) 
        pnl1: TPanel; 
        procedure pnl1Resize(Sender: TObject); 
      private 
        { Private declarations } 
        FDllTest: IDllTest; 
      public 
        { Public declarations } 
        constructor Create(AOwner: TComponent); override; 
        destructor Destroy; override; 
      end; var 
      Form1: TForm1; function NewDllTest: IDllTest; stdcall; implementation function NewDllTest; external 'dllTest.dll' name 'CreateDllTest'; {$R *.dfm} { TForm1 } constructor TForm1.Create(AOwner: TComponent); 
    begin 
      inherited Create(AOwner); 
      FDllTest := NewDllTest;   FDllTest.mergeTo(pnl1.Handle, pnl1.ClientRect); 
    end; destructor TForm1.Destroy; 
    begin 
      FDllTest := nil; 
      inherited Destroy; 
    end; procedure TForm1.pnl1Resize(Sender: TObject); 
    begin 
      FDllTest.mergeTo(pnl1.Handle, pnl1.ClientRect); 
    end; end.