1

我的许多应用程序表单都继承自一个基本表单,该表单加载在 FormClose 期间记录的保存的窗口大小、位置和状态,并在FormShow期间应用它。

FormShowinherited;的后代版本中的行位于方法开头的通常位置,并且通常后面有相当数量的代码,这些代码需要创建表单上的可视组件,以便可以操作和设置它们.

我遇到的问题是表单通常隐藏到后代FormShow事件结束,这是预期的行为,除非在祖先类FormShow事件中将WindowState设置为wsMaximized 。在这种情况下,一旦执行该行,表单就会变得可见,并且您可以看到剩余的视觉元素被组织起来。inherited;

设置VCL.Forms.TForm的WindowState属性时,将执行以下代码:

procedure TCustomForm.SetWindowState(Value: TWindowState);
const
  ShowCommands: array[TWindowState] of Integer =
    (SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED);
begin
  if FWindowState <> Value then
  begin
    FWindowState := Value;
    if not (csDesigning in ComponentState) then
    begin
      if Showing then
        ShowWindow(Handle, ShowCommands[Value])
      else if HandleAllocated and (FWindowState = wsMaximized) then
        RecreateWnd;
    end;
  end;
end;

问题的明显原因在于该方法的某个地方。theShowWindow或 the RecreateWnd,这似乎触发了立即绘制表单。

除了将我的LoadFormState(Self);方法从TBaseForm.FormShow移动到TBaseForm.FormActivate 之外,还有其他方法可以将表单设置为最大化而不实际显示表单吗?

4

1 回答 1

1

您不应该LoadFromStateTBaseForm.FormShow或调用您的过程TBaseForm.FormActivate

TBaseForm.FormShow每次表单的可见性从False变为时都会调用True
因此,例如,如果您在显示另一个时隐藏您的,然后在另一个表单关闭后再次显示它TBaseForm.FormShow会触发,因此您将从保存状态加载表单的尺寸和位置,这可能与表单隐藏时的状态不同. 自应用程序启动以来,用户可能已经移动并调整了 from 的大小。
这将导致表单在用户不希望这样做的情况下移动其位置,因此它会惹恼您的用户。

也不要使用TBaseForm.FormActivate,因为每次 Form 收到焦点时都会触发。因此,将焦点从另一个更改回此焦点TBaseForm.FormActivate,从而将您的表单尺寸和位置更改为已保存状态,当表单失去焦点时,该状态可能不是状态。

调用加载表单初始属性的过程的正确位置LoadFormState是在表单构造函数中。

于 2020-12-15T04:22:38.440 回答