Note that there are some explanatory texts on larger screens.

plurals
  1. POFMX form in a DLL (firemonkey/delphi)
    text
    copied!<p>Im trying to make a FMX form in a dll, after about 17 hours (of trying diffrent approches) i got it working, <strong>except i get a exception trying to unload the dll</strong>. I have no idea how to make it work, maybe someone could help me and point out what im doing wrong?</p> <p>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.</p> <p>Project showing my problem:</p> <p><strong>exe unit1.pas</strong></p> <pre><code>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. </code></pre> <p><strong>exe unitLoadDll.pas</strong></p> <pre><code>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 &gt; 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 &lt;&gt; 0 then FreeLibrary(DLLHandle); end. </code></pre> <p><strong>dll project1.dpr</strong></p> <pre><code>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. </code></pre> <p><strong>dll unit1.pas</strong></p> <pre><code>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. </code></pre> <hr> <p><strong>EDIT (FIX):</strong></p> <p>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.</p> <p><strong>new unitLoadDll.pas</strong></p> <pre><code>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 &gt; 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 &lt;&gt; 0; end; procedure UnloadLib; begin if DLLHandle &lt;&gt; 0 then begin FreeLibrary(DLLHandle); DllHandle := 0; end; end; initialization LoadLib; finalization UnloadLib; end. </code></pre> <p><strong>new unit1.pas</strong></p> <pre><code>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. </code></pre> <p>in unit1.pas i moved the Winapi.GDIPOBJ to "uses" just after interface directive, and it worked...</p> <p>Thank you all for your answers! See you soon! very soon...</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload