一个DLL中的FMX表单(firemonkey / delphi) [英] FMX form in a DLL (firemonkey/delphi)

查看:389
本文介绍了一个DLL中的FMX表单(firemonkey / delphi)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在一个dll中制作一个FMX表单,大约17个小时(尝试不同程度的审批)后,我开始工作,除了我得到一个异常,尝试卸载dll 。我不知道如何使它工作,也许有人可以帮助我,并指出我做错了什么?



旁注:
i不能有一个FMX表单在我的VCL应用程序中,因为AA绘图,我只需要在我的文本上绘制画布上,同时在VCL应用程序上有一个FMX表单,我不会得到这个cleartype的文本:(我试图做一些OSD / HUD。



项目显示我的问题:



exe unit1.pas

  unit Unit1; 

界面

使用
Winapi .Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,
Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls;

type
TForm1 = class(TForm)
Button1:TButton;
Button2:TButton;
过程Button1Click(Sender:TObject);
过程Button2Click(Sender:TObject );
private
{私人声明}
public
{公开声明}
end;

var
Form1:TForm1;

实现

{$ R * .dfm}

使用
unitLoadDLL,Winapi.GDIPOBJ;

procedure TForm1.Button1Click(Sender:TObject);
begin
showme();
结束

procedure TForm1.Button2Click(Sender:TObject);
begin
closeme();
结束

结束。

exe unitLoadDll.pas

  unit unitLoadDLL; 

界面

使用Windows,Dialogs;

type
TShowme = procedure();
TCloseme = procedure();

var
showme:TShowme = nil;
closeme:TCloseme = nil;
DllHandle:THandle;

实现

初始化

如果DllHandle = 0然后开始
DllHandle:= LoadLibrary('C:\Users\Ja \Desktop\dupa\dll\Win32\Debug\Project1.dll');
如果DllHandle> 0然后开始
@showme:= GetProcAddress(DllHandle,'showme');
@closeme:= GetProcAddress(DllHandle,'closeme');
end
else begin
MessageDlg('选择图像功能不可用',mtInformation,[mbOK],0);
结束
结束

finalization
如果DLLHandle<> 0然后
FreeLibrary(DLLHandle);
结束。

dll project1.dpr

 库Project1; 


使用
FMX.Forms,
System.SysUtils,
System.Classes,
Unit1 in'Unit1.pas'{Form1 };

{$ R * .res}

procedure showme(); stdcall出口;
begin
TForm1.showme;
结束

procedure closeme(); stdcall出口;
begin
TForm1.closeme;
结束

export
showme,closeme;

开始
结束。

dll unit1.pas


$ b单位Unit1; $ b

  

接口

使用
System.SysUtils,System.Types,System.UITypes,System.Classes,System.Variants,
FMX.Types, FMX.Controls,FMX.Forms,FMX.Dialogs;

type
TForm1 = class(TForm)
Label1:TLabel;
private
{私有声明}
public
类程序showme();
class procedure closeme();
结束

var
Form1:TForm1;

实现

{$ R * .fmx}

类过程TForm1.showme();
begin
Form1:= TForm1.Create(Application);
Form1.Show;
结束

类程序TForm1.closeme();
begin
Form1.Free;
结束

结束。






编辑(FIX) strong>



所有答案都有帮助,但是我所做的是,在dll卸载之前,GDI +被关闭,这显示出了问题。 / p>

new unitLoadDll.pas

  unitLoadDLL; 

界面

使用Windows,Dialogs;

type
TShowme = procedure();
TCloseme = procedure();

var
showme:TShowme = nil
closeme:TCloseme = nil;
DllHandle:THandle;

函数LoadLib:Boolean;
程序UnloadLib;

实现

函数LoadLib:Boolean;
begin
如果DllHandle = 0,则开始
DllHandle:= LoadLibrary('C:\Users\Ja\Desktop\dupa\dll\Win32\Debug\ Project1.dll');
如果DllHandle> 0然后开始
@showme:= GetProcAddress(DllHandle,'showme');
@closeme:= GetProcAddress(DllHandle,'closeme');
end
else begin
MessageDlg('选择图像功能不可用',mtInformation,[mbOK],0);
结束
结束
结果:= DllHandle<> 0;
结束

程序UnloadLib;
begin
如果DLLHandle<> 0然后开始
FreeLibrary(DLLHandle);
DllHandle:= 0;
结束
结束

初始化
LoadLib;

finalization
UnloadLib;
结束。

new unit1.pas


$ b单位Unit1; $ b

  

接口

使用
Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,
Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls,Winapi.GDIPOBJ;

type
TForm1 = class(TForm)
Button1:TButton;
Button2:TButton;
procedure Button1Click(Sender:TObject);
程序Button2Click(发件人:TObject);
private
{私人声明}
public
{公开声明}
end;

var
Form1:TForm1;

实现

{$ R * .dfm}

使用
unitLoadDLL;

procedure TForm1.Button1Click(Sender:TObject);
begin
showme();
结束

procedure TForm1.Button2Click(Sender:TObject);
begin
closeme();
结束

结束。

在unit1.pas中,我将Winapi.GDIPOBJ移动到interface命令后使用工作...



感谢大家的答案!再见!很快...

解决方案

Embarcadero的Stephen Ball制作了这篇文章演示了如何做你正在努力做的事情


Im trying to make a FMX form in a dll, after about 17 hours (of trying diffrent approches) i got it working, except i get a exception trying to unload the dll. I have no idea how to make it work, maybe someone could help me and point out what im doing wrong?

side note: i cant have a FMX form in my VCL application becouse of the AA drawing, i just need it on my text while drawing on a canvas and while having a FMX form on a VCL application, i dont get that cleartype on text :( im trying to make a some sort of OSD/HUD.

Project showing my problem:

exe unit1.pas

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  unitLoadDLL, Winapi.GDIPOBJ;

procedure TForm1.Button1Click(Sender: TObject);
begin
  showme();
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  closeme();
end;

end.

exe unitLoadDll.pas

unit unitLoadDLL;

interface

uses Windows, Dialogs;

type
  TShowme = procedure();
  TCloseme = procedure();

var
  showme : TShowme = nil;
  closeme : TCloseme = nil;
  DllHandle : THandle;

implementation

initialization

  if DllHandle = 0 then begin
    DllHandle := LoadLibrary('C:\Users\Ja\Desktop\dupa\dll\Win32\Debug\Project1.dll');
    if DllHandle > 0 then begin
      @showme := GetProcAddress(DllHandle,'showme');
      @closeme := GetProcAddress(DllHandle,'closeme');
    end
    else begin
      MessageDlg('Select Image functionality is not available', mtInformation, [mbOK], 0);
    end;
  end;

finalization
  if DLLHandle <> 0 then
    FreeLibrary(DLLHandle);
end.

dll project1.dpr

library Project1;


uses
  FMX.Forms,
  System.SysUtils,
  System.Classes,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

procedure showme(); stdcall export;
begin
  TForm1.showme;
end;

procedure closeme(); stdcall export;
begin
  TForm1.closeme;
end;

exports
  showme, closeme;

begin
end.

dll unit1.pas

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs;

type
  TForm1 = class(TForm)
    Label1: TLabel;
  private
    { Private declarations }
  public
    class procedure showme();
    class procedure closeme();
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

class procedure TForm1.showme();
begin
  Form1 := TForm1.Create(Application);
  Form1.Show;
end;

class procedure TForm1.closeme();
begin
  Form1.Free;
end;

end.


EDIT (FIX):

All answers ware helpfull, but what i've done is, that the GDI+ was shutdown BEFORE the dll unload... that appear's to be the problem.

new unitLoadDll.pas

unit unitLoadDLL;

interface

uses Windows, Dialogs;

type
  TShowme = procedure();
  TCloseme = procedure();

var
  showme : TShowme = nil;
  closeme : TCloseme = nil;
  DllHandle : THandle;

  function LoadLib : Boolean;
  procedure UnloadLib;

implementation

function LoadLib : Boolean;
begin
  if DllHandle = 0 then begin
    DllHandle := LoadLibrary('C:\Users\Ja\Desktop\dupa\dll\Win32\Debug\Project1.dll');
    if DllHandle > 0 then begin
      @showme := GetProcAddress(DllHandle,'showme');
      @closeme := GetProcAddress(DllHandle,'closeme');
    end
    else begin
      MessageDlg('Select Image functionality is not available', mtInformation, [mbOK], 0);
    end;
  end;
  Result := DllHandle <> 0;
end;

procedure UnloadLib;
begin
  if DLLHandle <> 0 then begin
    FreeLibrary(DLLHandle);
    DllHandle := 0;
  end;
end;

initialization
  LoadLib;

finalization
  UnloadLib;
end.

new unit1.pas

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Winapi.GDIPOBJ;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  unitLoadDLL;

procedure TForm1.Button1Click(Sender: TObject);
begin
  showme();
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  closeme();
end;

end.

in unit1.pas i moved the Winapi.GDIPOBJ to "uses" just after interface directive, and it worked...

Thank you all for your answers! See you soon! very soon...

解决方案

Embarcadero's Stephen Ball has produced this article demonstraitng how to do exactly what you're trying to do

这篇关于一个DLL中的FMX表单(firemonkey / delphi)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆