How to embed a FireMonkey form in a VCL form seamlessly?
delphi, delphi-xe2, firemonkey, vcl
Solution
The cause of the behavior is that the window manager does not know you have made your firemonkey window a child, hence it is deactivating the previously active window when you activate the firemonkey window. As is documented in `SetParent function` you have to set the child flag manually. An example usage could be:
var
FMForm: TFMForm1;
FMHWnd: HWND;
begin
FMForm := TFMForm1.Create(nil);
FMForm.Left := 0;
FMForm.Top := 0;
FMHWnd := FmxHandleToHWND(FMForm.Handle);
SetWindowLong(FMHWnd, GWL_STYLE, GetWindowLong(FMHwnd, GWL_STYLE) or WS_CHILD);
winapi.windows.SetParent(FMHWnd, Panel1.Handle);
FMForm.Visible := True;
Update: If you have to remove the fmx form's borders, setting `BorderStyle` sets the `WS_POPUP` style which you cannot use with `WS_CHILD`. In that case set the styles you need explicitly instead of getting and 'or'ring them. F.i.
..
LFMForm.BorderIcons := [];
LFMForm.BorderStyle := TFmxFormBorderStyle.bsNone;
LFMHWnd := FmxHandleToHWND(LFMForm.Handle);
SetWindowLong(LFMHWnd, GWL_STYLE, WS_CHILDWINDOW or WS_BORDER);
..
Problem
I used the trick described in this question to display a FireMonkey form on a TPanel in a VCL application. My problem is that clicking (controls on) the embedded form causes the VCL form (containing that TPanel) to become deactivated. The most obvious consequence of that is the window border changing color all the time. When displaying a VCL form on a TPanel of another, this doesn't happen; the forms apparently "merge". What should I do to reach a similar result with FireMonkey? I want controls on the FireMonkey form to be usable, but keep the parent form activated. Update 1 VCL ``` unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, FMX.Forms, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, FMX.Platform.Win; type TMainForm = class(TForm) Panel1: TPanel; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var MainForm: TMainForm; implementation {$R *.dfm} uses FireMonkeyForms; procedure TMainForm.Button1Click(Sender: TObject); var LFMForm: FireMonkeyForms.TForm1; LFMHWnd: HWND; begin LFMForm := FireMonkeyForms.TForm1.Create(nil); LFMForm.Left := 0; LFMForm.Top := 0; LFMForm.Height := Panel1.ClientHeight; LFMForm.Width := Panel1.ClientWidth; LFMForm.BorderStyle := TFmxFormBorderStyle.bsNone; LFMForm.BorderIcons := []; LFMHWnd := FmxHandleToHWND(LFMForm.Handle); SetWindowLong(LFMHWnd, GWL_STYLE, GetWindowLong(LFMHwnd, GWL_STYLE) or WS_CHILD); Winapi.Windows.SetParent(LFMHWnd, Panel1.Handle); LFMForm.Visible := True; end; end. ``` FireMonkey ``` unit FireMonkeyForms; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Layouts, FMX.Memo; type TForm1 = class(TForm) Label1: TLabel; Memo1: TMemo; private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} end. ```