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;
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;
---------------------------
Project Main.exe raised exception class EInvalidOperation with message 'Control 'Frame1' has no parent window'.什么原因,Frame1的parent是panel呀.
tmp:=GetDllFrameClass(application.Handle,Self.Handle);
TFrame不能成为window类.
改为tmp2:=TMP.Create(nil);试试
tmp2:=TMP.Create(self); //tmp又创建了一次
改为tmp2:=TMP.Create(nil);试试 我改了,还是提示这个错误呀
我是了一下:procedure TForm2.btn2Click(Sender: TObject);
var
fm: TFrame;
begin
fm:= TFrame.Create(nil);
fm.Parent:= Form2;
edt1.Text:= fm.Parent.ClassName
end;
没有问题.
当然,我没用到动态链接库.
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.
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;
---------------------------
Project Main.exe raised exception class EInvalidOperation with message 'Control 'Frame1' has no parent window'. 什么原因,Frame1的parent是panel呀.
使用接口导出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.