如何在Delphi

时间:2016-04-28 01:17:46

标签: forms delphi

在我的应用程序中,我有多个可以同时显示的表单,它们都以相同的大小单位显示磁盘空间(文件,硬盘大小等)。所以它们都以字节,KB,MB,GB或TB显示磁盘空间。我还有一个单独的设置表单,用户可以在其中更改显示大小,他想要其他形式。一旦用户在设置表单中单击“确定”,我希望所有其他(打开)表单立即更改其大小设置。

每个表单都有一个受保护的过程SetViewSettings,它负责这项工作。它们都是祖先形式的后代,它将SetViewSettings定义为虚拟和抽象。实际显示的表单覆盖了祖先的SetViewSettings方法。到目前为止没有任何问题。

因为我不想调用每个单独的表单(FormX.SetViewSetttings,FormY.SetViewSettings等),所以我使用以下解决方案:

procedure TApplicationForms.SetUnits;
var
  I: Integer;
begin
  for I := 0 to Screen.FormCount - 1 do
    if Screen.Forms[I] is TfrAncestorInfo then
      with Screen.Forms[I] as TfrAncestorInfo do
        acSetUnits.Execute;
end;

当用户单击“确定”时,将从SettingsForm调用此过程。 TFrAncestorInfo是TForm的后代,将SetViewSettings方法声明为虚拟和抽象。 acSetUnits是一个在TfrAncestorInfo中声明的Action,它只调用SetViewSettings。这一切都很好,但风险在于创建TFrAncestorInfo的新后代形式,而忘记覆盖SetViewSettings方法,在这种情况下,您将遇到一个“抽象错误”#39;异常。

是否有任何替代方法可以在表单中调用SetViewSettings方法,而无需单独列出(调用)所有后代表单?我知道消息和事件,但我不知道如何在多种形式的情况下使用它们。一般情况下:如何直接向所有TFrAncestorInfo后代表单发送消息或生成事件,而不单独列出它们?

1 个答案:

答案 0 :(得分:4)

一个选项(还有许多其他可能的选项)是向每个表单发送自定义消息。无需担心虚拟/抽象覆盖,类型检查等。只有实现消息处理程序的Forms才会对消息做出反应,其余的只会忽略它。

const
  WM_SETTINGS_UPDATED = WM_APP + 1;

procedure TApplicationForms.SetUnits;
var
  I: Integer;
begin
  for I := 0 to Screen.FormCount - 1 do
    Screen.Forms[I].Perform(WM_SETTINGS_UPDATED, 0, 0);
end;

type
  TSomeForm = class(TBaseForm)
  private
    procedure WMSettingsUpdated(var Message: TMessage); message WM_SETTINGS_UPDATED;
  protected
    procedure SetViewSettings;
  end;

procedure TSomeForm.WMSettingsUpdated(var Message: TMessage);
begin
  SetViewSettings;
end;

procedure TSomeForm.SetViewSettings;
begin
  //...
end;