我正在尝试在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/

10-12 07:05