Solved

Problems in integrating VCL & FireMonkey via a FM DLL

Posted on 2014-09-12
4
595 Views
Last Modified: 2014-09-14
I have written a Fire Monkey (mobile phone) application that also runs on Windows. So far so good.

Although it is not recommended by Embarcadero, I also have been able to compile the Fire Monkey into a VCL project. They don't interact, apart from the VCL calling the main frame of the Fire Monkey app, and then receiving back control when all is complete.

It is a little ugly at the user interface end, in that the Fire Monkey app also appears on the windows task bar, even when it is not running.

Also when I tested it on Vista I get an exception on closing the VCL.

Therefore, following Embarcadero's recommendation, I have written a DLL interface that embodies the Fire Monkey component. However I am doing something wrong, because as soon as I carry out a task in a sub-unit referencing the main form I get a data exception.

library LangDLL;

uses
  FMX.Forms,
  System.SysUtils,
  System.Classes,
  uMMain in 'uMMain.pas',
  uMAccess in 'uMAccess.pas',
  uUnique in 'uUnique.pas';

{$R *.res}

procedure ShowMobile; stdcall export;
var
  MM: TfMMain;
  test: string;
begin
  test := 'OK';
try
  MM := TfMMain.Create(application);
  MM.FormActivate(application);
  MM.Free;
except
  test := 'Failed';
end;
end;
exports
  ShowMobile;
begin
end.

Open in new window


It passes through the above code without a worry, and in the main part of the App it works OK.

I have a couple of units that are called by the program. When the logic flows to those units in the DLL style operation the form fMMain is now nil to them. (It is OK when it runs as a stand-alone program.)

The simple work-around would be eliminate those units, but why is fMMain = nil in this situation?
0
Comment
Question by:GrahamDLovell
  • 2
  • 2
4 Comments
 
LVL 26

Expert Comment

by:Sinisa Vuk
ID: 40321261
fMMain  is defined as TfMMain in uMMain unit? Why do you mix fmx/vcl code?
0
 

Author Comment

by:GrahamDLovell
ID: 40321370
I just gave the form the name fMMain (form, mobile, main)

The default for a new form in fmx is Form1. The IDE adds the T prefix for a type. The same pattern is followed here.

How have I mixed fmx / vcl code?
0
 
LVL 26

Accepted Solution

by:
Sinisa Vuk earned 500 total points
ID: 40322113
I build small example with some success:

Dll part  (delph->new library):
library test1;

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

{$R *.res}

procedure ShowMobile; stdcall;
var
  MM: TForm1;
  test: string;
begin
  test := 'OK';
try
  MM := TForm1.Create(nil);
  try
    MM.ShowModal;
  finally
    MM.Free;
  end;
except
  test := 'Failed';
end;
end;
exports
  ShowMobile;

begin

end.

Open in new window


...calling part:
uses ..., Unit3;

procedure TForm2.Button1Click(Sender: TObject);
begin
  StartForm;
end;

Open in new window


... unit3 where dll is loading dynamically ... and main thing here is to not call FreeLibrary by yourself:
unit Unit4;

interface

uses Winapi.Windows, System.SysUtils, Vcl.Forms;

type
  //user dll
  TFMXDllForm = procedure; stdcall;

function StartForm: Boolean;

var
  hDLLHandle: Cardinal = 0;  //global dll handle for reusing....

implementation

function StartForm: Boolean;
var
  sFileName: String;
  frm: TFMXDllForm;
begin
  Result := False;
  sFileName:=IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName))+'test1.dll';

  if hDLLHandle = 0 then //reuse dll handle
    hDLLHandle:=LoadLibrary(PChar(sFileName));
  if hDLLHandle <> 0 then
  begin
    try
      frm:=GetProcAddress(hDLLHandle, 'ShowMobile');

      if Assigned(frm) then
      begin
        frm;  //show dll form
        Result := True;
      end;
    except
    end;
  end;
end;

initialization

finalization
  //if hDLLHandle <> 0 then //do not free by own
  //  FreeLibrary(hDLLHandle);

end.

Open in new window

0
 

Author Closing Comment

by:GrahamDLovell
ID: 40322152
Brilliant. Works a charm.

For anyone else who tries this, here are some other things I learnt about FireMonkey DLLs:

This process instantiates the FireMonkey form, and so you have to do everything inside the form (no calls to functions or procedures that are not part of that form). - that is the answer to my original question.

Make sure you don't double reference the form, e.g. in a function TfMMain.GetList, don't reference a value as "fMMain.NewList", just use "NewList". While the former works in a standalone FireMonkey app, the DLL doesn't like it.

I also had to abandon using TFileStream in the DLL, but that is a matter for another question (but not from me, since I just used TClientDataSet.LoadFromFile instead).
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Rave Reports - Adding a Data Band 1 998
Creating a blank copy of a TClientDataSet 1 1,145
default value in Delphi component 2 507
Virtuailstring tree compare node issue 14 103
Build an array called $myWeek which will hold the array elements Today, Yesterday and then builds up the rest of the week by the name of the day going back 1 week.   (CODE) (CODE) Then you just need to pass your date to the function. If i…
Note: This is the second blog post in a series on email clearinghouses (https://www.xmatters.com/alert-management/blog-email-has-failed-us?utm_campaign=70138000000ydLoAAI&utm_source=exex&utm_medium=article&utm_content=blog-post).   Every month t…
Need to grow your business through quality cloud solutions? With everything required to build a cloud platform and solution, you may feel like the distance between you and the cloud is quite long. Help is here. Spend some time learning about the Con…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

939 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now