Reputation: 6626
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.
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.
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.
Upvotes: 4
Views: 4091
Reputation: 54822
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);
..
Upvotes: 3