【发布时间】:2014-12-17 18:45:33
【问题描述】:
我的 Delphi XE7 FireMonkey 项目正在增加控件,我自然而然地转向使用框架。在 VCL 中使用框架的情况下,我只是选择将一个(复杂)VCL 表单托管在另一个表单中,在表单的 OnShow 中创建和显示它并将其设置为与客户端对齐(这样做的好处是您在编辑框架时不会遇到悬挂继承控件的问题)。
不过,使用 FireMonkey,事情发生了轻微的变化,我试图让一个子窗体客户端在另一个窗体中对齐的尝试是磕磕绊绊的。我遇到了这个very useful SO link,它展示了如何在 VCL 表单中托管 FireMonkey 表单,所以我在此基础上使用我的代码构建如下:
procedure THostForm.FormCreate(Sender: TObject);
begin
FForm := TChildForm.Create( Self );
FForm.BorderIcons := [];
FForm.BorderStyle := TFmxFormBorderStyle.None;
FForm.Visible := True;
FForm.Parent := Self;
ResizeForm;
end;
procedure THostForm.FormResize(Sender: TObject);
begin
inherited;
ResizeForm;
end;
procedure THostForm.ResizeForm;
begin
if Assigned(FForm) then
FForm.SetBounds( Round(ClientRect.Left), Round(ClientRect.Top), Round(ClientWidth), Round(ClientHeight));
end;
这会产生一个子表单,它会随主表单改变大小,但仍保留在屏幕的左上角。我也在ResizeForm 例程中尝试了各种位置选项。在我看来,一个表单可能无法成为另一个表单的父级,因为 TForm 不是 IAligneableControl 而 TFrame 是。因此,我尝试将我的子表单“停靠”到与主机表单对齐的 TRectangle 客户端,其行为方式相同。
有人检查过这个吗?
* 以下是 MARCO 建议的解决方案详情 *
Marco 的解决方案非常简洁,将“托管”减少到仅两行代码。您确实需要确保您的子(托管)表单在另一个客户端对齐控件中包含所有内容 - Marco 建议使用 TLayout,但我已经有一个用于背景的 TPanel,所以我没有完全修改子表单。因此,要在 THostForm 中托管此子表单 TChildForm,只需执行以下操作:
procedure THostForm.FormCreate(Sender: TObject);
begin
FForm := TChildForm.Create( Self );
FForm.Panel1.Parent := Self;
end;
工作完成。谢谢马可。
【问题讨论】:
-
尝试ClientToScreen(ClientRect) 或者 - 如果父窗体本身不是另一个窗体的子窗体 - 只需 BoundsRect。
-
好主意 - 解决了左上角的问题,但移动主机窗体不会移动子窗体 - 我猜是因为这不会触发 OnResize。由于重新定位,调整大小看起来也相当可怕,带有闪烁的黑色条带。
标签: delphi frame firemonkey