You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态创建FMX窗体时BorderStyle设置导致的尺寸异常问题

解决FMX动态创建窗体时BorderStyle变更导致客户区尺寸异常的问题

问题分析

动态创建FMX窗体时,设置BorderStyle为Single或None后直接指定ClientWidth/ClientHeight,会出现尺寸计算异常:

  • 即使明确设置客户区为300x300,窗体总尺寸仍保留Sizeable样式对应的边框大小,导致实际客户区超出预期。
  • 设计器内操作无此问题,VCL环境下变更边框样式会自动调整总尺寸以维持客户区固定,符合预期逻辑。
  • BorderStyle=None时直接设置Width/Height能临时解决,但Single样式因存在边框,此方法不适用。

解决方案

核心思路是触发FMX重新计算边框与客户区的尺寸关系,或手动推导正确的总窗体尺寸。

方法1:调用UpdateBounds强制刷新尺寸逻辑

设置BorderStyle和客户区尺寸后,调用UpdateBounds触发窗体重新计算尺寸,确保客户区大小符合设定:

var
  Form: TForm;
  Shape: TRectangle;
begin
  // 修复Single样式的窗体
  Form := TForm.CreateNew(Application);
  Form.BorderStyle := TFmxFormBorderStyle.Single;
  Form.Fill.Color := TAlphaColors.Yellow;
  Form.Fill.Kind := TBrushKind.Solid;

  Form.ClientWidth := 300;
  Form.ClientHeight := 300;
  // 强制同步边框与客户区尺寸计算
  Form.UpdateBounds(Form.Left, Form.Top, Form.Width, Form.Height);

  Shape := TRectangle.Create(Form);
  Shape.Parent := Form;
  Shape.SetBounds(0, 0, 300, 300);

  Form.Show;

  // 修复None样式的窗体
  Form := TForm.CreateNew(Application);
  Form.BorderStyle := TFmxFormBorderStyle.None;
  Form.Fill.Color := TAlphaColors.Yellow;
  Form.Fill.Kind := TBrushKind.Solid;

  Form.ClientWidth := 300;
  Form.ClientHeight := 300;
  Form.UpdateBounds(Form.Left, Form.Top, Form.Width, Form.Height);

  Shape := TRectangle.Create(Form);
  Shape.Parent := Form;
  Shape.SetBounds(0, 0, 300, 300);

  Form.Show;
end;

方法2:手动计算Single样式的总窗体尺寸

针对Single样式,直接通过边框、标题栏参数反推总尺寸,确保客户区为设定值:

var
  Form: TForm;
  Shape: TRectangle;
  BorderWidth: Integer;
  CaptionHeight: Integer;
begin
  Form := TForm.CreateNew(Application);
  Form.BorderStyle := TFmxFormBorderStyle.Single;
  Form.Fill.Color := TAlphaColors.Yellow;
  Form.Fill.Kind := TBrushKind.Solid;

  // 获取Single样式的边框与标题栏尺寸
  BorderWidth := Form.BorderWidth;
  CaptionHeight := Form.CaptionHeight;

  // 计算总尺寸:客户区尺寸 + 左右边框*2 + 标题栏高度 + 底部边框
  Form.Width := 300 + BorderWidth * 2;
  Form.Height := 300 + CaptionHeight + BorderWidth;

  Shape := TRectangle.Create(Form);
  Shape.Parent := Form;
  Shape.SetBounds(0, 0, 300, 300);

  Form.Show;
end;

方法3:先显示窗体再修改样式(临时方案)

先以默认Sizeable样式创建并显示窗体,再修改BorderStyle和客户区尺寸,此时FMX会正确计算尺寸关系:

var
  Form: TForm;
  Shape: TRectangle;
begin
  Form := TForm.CreateNew(Application);
  Form.BorderStyle := TFmxFormBorderStyle.Sizeable;
  Form.Fill.Color := TAlphaColors.Yellow;
  Form.Fill.Kind := TBrushKind.Solid;

  Form.ClientWidth := 300;
  Form.ClientHeight := 300;
  Form.Show;

  // 显示后修改边框样式并重置客户区尺寸
  Form.BorderStyle := TFmxFormBorderStyle.Single;
  Form.ClientWidth := 300;
  Form.ClientHeight := 300;

  Shape := TRectangle.Create(Form);
  Shape.Parent := Form;
  Shape.SetBounds(0, 0, 300, 300);
end;

原理说明

FMX动态创建流程中,BorderStyle变更不会自动触发尺寸重新计算,而设计器会在样式变更时同步调整尺寸逻辑。调用UpdateBounds可强制窗体重新解析当前边框样式下的客户区与总尺寸关系;手动计算则是绕过FMX的异常逻辑,直接基于系统边框参数推导正确值。

内容的提问来源于stack exchange,提问作者Digão Dalpiaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 10:17:24