4 votes

Comment intégrer de manière transparente un formulaire FireMonkey dans un formulaire VCL ?

J'ai utilisé l'astuce décrite dans cette question pour afficher un formulaire FireMonkey sur un TPanel dans une application VCL. Mon problème est que le fait de cliquer sur (les contrôles sur) le formulaire intégré entraîne la désactivation du formulaire VCL (contenant ce TPanel). La conséquence la plus évidente de ce phénomène est que la bordure de la fenêtre change de couleur en permanence.

Lorsque l'on affiche un formulaire VCL sur le panneau d'un autre formulaire, cela ne se produit pas ; les formulaires semblent "fusionner". Que dois-je faire pour obtenir un résultat similaire avec FireMonkey ? Je veux que les contrôles du formulaire FireMonkey soient utilisables, mais que le formulaire parent reste activé.

Mise à jour 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.

3voto

Sertac Akyuz Points 32656

La cause de ce comportement est que le gestionnaire de fenêtres ne sait pas que vous avez fait de votre fenêtre firemonkey un enfant, il désactive donc la fenêtre précédemment active lorsque vous activez la fenêtre firemonkey. Comme cela est documenté dans SetParent function vous devez définir le enfant le drapeau manuellement. Un exemple d'utilisation pourrait être :

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;

Mise à jour : Si vous devez supprimer les bordures du formulaire fmx, le réglage de l'option BorderStyle définit le WS_POPUP que vous ne pouvez pas utiliser avec WS_CHILD . Dans ce cas, définissez explicitement les styles dont vous avez besoin au lieu de les obtenir et de les "oraliser". F.i.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X