How to easily embed a FireMonkey form in a VCL form?

I used the trick described in this question to display the FireMonkey form on TPanel in a VCL application. My problem is that clicking (control) on the embedded form deactivates the VCL form (containing this TPanel). The most obvious consequence of this is the color change of the window when the color changes.

When displaying a VCL form on another TPanel, this does not happen; the forms seem to "merge." What should I do to achieve a similar result with FireMonkey? I want the controls in the FireMonkey form to be usable, but keep the parent form.

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. 
+4
source share
1 answer

The reason for this behavior is that the window manager does not know that you made your firemonkey window a child, so it disables the active window when you activate the firemonkey window. As described in the SetParent function , you must set the child flag manually. An example of use 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 need to remove the borders of the fmx form, setting BorderStyle sets the WS_POPUP style, which you cannot use with WS_CHILD . In this case, set the styles that you need explicitly, and not get or orring. Fi

  .. LFMForm.BorderIcons := []; LFMForm.BorderStyle := TFmxFormBorderStyle.bsNone; LFMHWnd := FmxHandleToHWND(LFMForm.Handle); SetWindowLong(LFMHWnd, GWL_STYLE, WS_CHILDWINDOW or WS_BORDER); .. 
+3
source

Source: https://habr.com/ru/post/1441162/


All Articles