我正在尝试在DLL中创建一个TButton对象以在EXE Main Form中显示它。这是我的代码:
DLL:
library dlltest1;
{$mode objfpc}{$H+}
uses
Classes,sysutils,Forms,Interfaces,StdCtrls,Windows,Dialogs
{ you can add units after this };
function test(hand:TForm):HWND;
var
a:TButton;
begin
a:=TButton.Create(hand);
a.Show;
a.Caption:='a';
result:=a.Handle;
end;
exports test;
begin
end.
可执行程序:
procedure test(hand:HWND); external 'dlltest1.dll';
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
TIPropertyGrid1: TTIPropertyGrid;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
type TComp=function(Hand:HWND):HWND;
var
comps:array of TComp;
procedure TForm1.FormCreate(Sender: TObject);
begin
end;
procedure TForm1.Button1Click(Sender: TObject);
var
a:HWND;
begin
SetLength(comps,1);
a:=LoadLibrary('dlltest1.dll');
comps[0]:=TComp(GetProcAddress(a,'test'));
(FindControl(comps[0](Form1.Handle)) as TButton).Caption:='A';
end;
它使用命令
comps[0](Form1.Handle)
创建按钮成功,但是当我尝试执行此(FindControl(comps[0](Form1.Handle)) as TButton).Caption:='A';
时,它说INVALID TYPE CAST
。我也尝试使用RTTI TPropertyEditor Grid。当我像这样分配它时:TIPropertyEditor1.TIObject:=FindControl(comps[0](Form1.Handle))
TIPropertyEditor1像TButton一样正常工作,但我不知道为什么'as TButton'会导致类型转换无效。我的问题? 最佳答案
将对Form实例的引用发送到按钮创建调用是正确的决定,因为只有这样,它将调用所有子组件的析构函数。
您应该从test
函数返回,而不是Handle而是TButton实例,这是HWND和TButton之间的区别。 Delphi将OS GUI API封装在TButton,TForm和任何TWinControl实例中。在低级操作系统上,请使用HWND作为对操作系统低级对象的引用。
您不必担心由于将Form实例发送到TButton.Create构造函数而导致的内存泄漏。
function test(Owner: TForm): TButton;
begin
Result := TButton.Create(Owner);
Result.Show;
Result.Caption:='a';
end;
关于dll - 从DLL创建主要形式(EXE)的对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51264798/