如何在VCL表单中实现FireMonkey表单的无缝集成?

更新于
2026-10-04 19:15:12
2阅读来源:SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计700个文字,预计阅读时间需要3分钟。

在VCL应用程序中使用TPanel显示FireMonkey表单时,遇到的问题是在单击嵌入的表单控件后,VCL表单(包括该TPanel)会失去激活状态。最明显的现象是窗口边框立即变色。问题可能是由于控件嵌套或事件处理不当引起的。以下是一种可能的解决方案:

1. 确保在单击FireMonkey表单控件时,事件处理程序不会直接调用VCL表单的激活方法。

2.使用TForm的OnActivate和OnDeactivate事件来处理状态变化,而不是在控件事件中直接操作。

3.如果必要,可以设置FireMonkey表单的`ModalResult`属性,以避免不必要的表单激活。

示例代码如下:

delphi

procedure TForm1.FormActivate(Sender: TObject);begin // 当VCL表单激活时,可以在这里添加代码end;

procedure TForm1.FormDeactivate(Sender: TObject);begin // 当VCL表单失去激活时,可以在这里添加代码end;

procedure TFormFMForm.Button1Click(Sender: TObject);begin // 处理FireMonkey表单的按钮点击事件 // 避免直接调用VCL表单的激活方法end;

通过这种方式,可以减少对VCL表单直接操作的可能性,从而避免激活状态的问题。

我使用 this question中描述的技巧在VCL应用程序中的TPanel上显示FireMonkey表单.我的问题是单击(控件)嵌入的表单导致VCL表单(包含该TPanel)被取消激活.最明显的结果是窗口边框一直在变色.

当在另一个的TPanel上显示VCL表单时,这不会发生;表格显然是“合并”.我应该怎么做才能使用FireMonkey获得类似的结果?我希望FireMonkey表单上的控件可用,但保持父表单激活.

更新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. 行为的原因是窗口管理器不知道您已将firemonkey窗口设为子窗口,因此在激活firemonkey窗口时它将停用先前活动的窗口.如 SetParent function中所述,您必须手动设置子标志.示例用法可以是:

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;

更新:
如果必须删除fmx表单的边框,则设置BorderStyle会设置WS_CHILD样式,而WS_CHILD样式不能与WS_CHILD一起使用.在这种情况下,请明确设置您需要的样式,而不是获取和“或”它们. F.i.

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

本文共计700个文字,预计阅读时间需要3分钟。

在VCL应用程序中使用TPanel显示FireMonkey表单时,遇到的问题是在单击嵌入的表单控件后,VCL表单(包括该TPanel)会失去激活状态。最明显的现象是窗口边框立即变色。问题可能是由于控件嵌套或事件处理不当引起的。以下是一种可能的解决方案:

1. 确保在单击FireMonkey表单控件时,事件处理程序不会直接调用VCL表单的激活方法。

2.使用TForm的OnActivate和OnDeactivate事件来处理状态变化,而不是在控件事件中直接操作。

3.如果必要,可以设置FireMonkey表单的`ModalResult`属性,以避免不必要的表单激活。

示例代码如下:

delphi

procedure TForm1.FormActivate(Sender: TObject);begin // 当VCL表单激活时,可以在这里添加代码end;

procedure TForm1.FormDeactivate(Sender: TObject);begin // 当VCL表单失去激活时,可以在这里添加代码end;

procedure TFormFMForm.Button1Click(Sender: TObject);begin // 处理FireMonkey表单的按钮点击事件 // 避免直接调用VCL表单的激活方法end;

通过这种方式,可以减少对VCL表单直接操作的可能性,从而避免激活状态的问题。

我使用 this question中描述的技巧在VCL应用程序中的TPanel上显示FireMonkey表单.我的问题是单击(控件)嵌入的表单导致VCL表单(包含该TPanel)被取消激活.最明显的结果是窗口边框一直在变色.

当在另一个的TPanel上显示VCL表单时,这不会发生;表格显然是“合并”.我应该怎么做才能使用FireMonkey获得类似的结果?我希望FireMonkey表单上的控件可用,但保持父表单激活.

更新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. 行为的原因是窗口管理器不知道您已将firemonkey窗口设为子窗口,因此在激活firemonkey窗口时它将停用先前活动的窗口.如 SetParent function中所述,您必须手动设置子标志.示例用法可以是:

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;

更新:
如果必须删除fmx表单的边框,则设置BorderStyle会设置WS_CHILD样式,而WS_CHILD样式不能与WS_CHILD一起使用.在这种情况下,请明确设置您需要的样式,而不是获取和“或”它们. F.i.

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