【问题标题】:Different behavior of form resizing from Delphi 10.0 Seattle to 10.2.2 Tokyo从 Delphi 10.0 Seattle 调整到 10.2.2 Tokyo 的不同行为
【发布时间】:2018-01-10 20:13:31
【问题描述】:

我安装了新的 Delphi 10.2.2 Tokyo,并开始将我的项目转移到它上面。

我在一个 Windows 桌面应用程序中发现了以下奇怪的行为。

我有一个大小为 700x545 的表单。为了防止用户调整它的大小,我使用了OnCanResize 事件并将Resize 参数设置为False。

OnCreate 事件中,我设置了所需的Width/Height 值。使用 Delphi 10.0 Seattle,它运行良好,但在 10.2.2 中,尺寸改为设置为 340x220。

显然,它是在OnCreate事件之前设置的,因为我在OnCreate事件中的更改被忽略了,可能是因为我的OnCanResize事件。

在设计时,我在 Object Inspector 中找到正确的值。

有什么想法吗?

【问题讨论】:

  • 为什么不通过设置BorderStyle 属性和BorderIcons 来使表单不可调整大小,而不是响应OnCanResize 事件?然后在 IDE 中设置表单大小(如果您担心会在 IDE 中意外调整表单大小,也可以设置约束)。无论如何,你在使用 DPI 缩放吗?
  • 为什么人们在创建表单时坚持要检查大小,尤其是当表单可能在以后调整大小时?嘘
  • 您可能在这里搞砸了一些数字。表单的默认大小为 320x240。
  • @uwe raabe,是的,你是对的,320 x 240 是正确的值

标签: delphi delphi-10-seattle delphi-10.2-tokyo


【解决方案1】:

当一个 Form 对象被创建时,它的底层窗口可以(并且通常是)在 DFM 流期间创建,在OnCreate 事件被触发之前。因此,表单可能希望在您准备好之前执行调整大小操作。这在所有版本的 Delphi 中一直都有可能,这在东京并不是新行为。

如果要使用 Form 的 OnCanResize 事件,在开始将事件的 Resize 参数设置为 False 之前,应确保 Form 对象已完全构造和初始化。例如,将Boolean 成员添加到您的Form 类并在OnCreate 事件中将其设置为True,然后让OnCanResize 事件将Resize 参数设置为该Boolean 的相反值。

或者,不使用OnCanResize 事件,而是考虑使用Form 的Contraints 属性,或者只是将Form 的BorderStyle 属性设置为不可调整大小的样式,例如bsSinglebsDialog。无论哪种方式都允许您在代码中调整表单的大小,同时防止用户手动调整表单的大小。

【讨论】:

  • 加载 DFM 时,通常在分配事件之前分配属性。这由已发布部分中所有属性的顺序控制。因此,在加载 DFM 期间不应连接 OnCanResize 事件。
  • 抱歉,我不能接受这个作为答案,因为它没有回答我的问题。我对西雅图和 10.2.2 使用相同的代码并得到不同的结果。在西雅图,表单提供了正确的大小,在 10.2.2 中,大小为 340 x 220。DFM 还包含正确的大小 700 x 545。必须有一个操作以默认大小 340 x 覆盖 dfm 值220.跨度>
【解决方案2】:

Seattle 和 10.2.2 的区别如下:

oncanresize 事件在 oncreate 事件被调用之前被调用了两次。源来自 TControl(我找不到什么控件),调用者对我来说似乎是 ScaleforCurrentDPI 过程。在西雅图,oncanresize 在完成 oncreate 事件之前永远不会被调用。

对我来说,当 onformdosomething 事件可以在 oncreate 事件之前被调用时,这听起来像是一个错误。

【讨论】:

  • 你有没有想过在 OnShow 活动中施展你的魔法?
  • 任何有线事件都会在表单被加载后被触发。为什么 OnCreate 事件要特别?如果您不希望在 OnCreate 处理程序期间调用 OnCanResize 处理程序,只需将其拆线并在您完成任务时重新连接它。当仅在某些特定条件下触发事件时,这将是相当混乱的。看来你在西雅图的代码很幸运。
  • @uwe raabe:oncreate 事件对我来说很特别,因为它是表单的第一个事件。你称之为加载,我会说创建,我想知道为什么你可以在创建/退出对象/表单之前调用其他事件。
  • 正如我所说:当 DFM 的加载完成时,这些事件是有线的。这发生在表单构造函数中。在加载过程结束时,将调用 Loaded 方法,该方法(对于表单)调用 ScaleForCurrentDpi。如果设计 DPI 和当前 DPI 不同,则可以在此处更改表单大小。稍后,当所有构造函数都已执行(即在 AfterConstruction 中)时,将触发 OnCreate 事件。因此,在此之前可能会触发某些事件并非不可能。也许将其命名为 AfterCreate 而不是 OnCreate 会更好。
猜你喜欢
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多