【问题标题】:Main Form not displaying when showing modal form in main form's OnShow?在主窗体的 OnShow 中显示模态窗体时主窗体不显示?
【发布时间】:2011-08-17 14:52:57
【问题描述】:

我创建了一个应用程序,其中主窗体在主窗体的 FormShow 事件上调用子窗体。显示子表单并提供两个选项可供选择。如果选择了子表单上的第一个选项,则会显示一条消息,然后将显示主表单。现在,当应用程序第一次运行时,在子表单 Meassage 上选择选项后将显示。但我想以主窗体作为背景显示消息。所以对此的任何解决方案。下面是FormShow的代码。

Procedure TMainForm.FormShow(Sender:TObject);
begin
  if (SubForm.ShowModal = mrOK) and bOption1 then
  begin
    ShowMessage('Enter the value');
  end;
end;

【问题讨论】:

  • 你将不得不在 onPaint 事件上用 Canvas 来绘制它,就像这样,我在 7 年前用 Delphi 7 写过,所以它可能会有所改变。 :D
  • 但是在主窗体上我放了一个重定向到子窗体的按钮。在该按钮上单击我已将 Mainform Visible 设为 false,并且在用户再次从 SubForm 中选择选项后,Mainform 设为 true。在这种情况下,Smessage 在后台显示 Mainform。感谢您的帮助。

标签: delphi modal-dialog tform


【解决方案1】:

如果我理解正确,那么您的问题是当消息框出现时您的主窗体仍然不可见。

如果是这种情况,那么您有两种选择:

  1. 不要在主窗体的OnShow 事件中显示您的SubForm,而是在以后显示
  2. 不要在ShowModal 返回后直接显示消息,而是稍后显示

对于第 2 点,您可以使用与我建议的 here 类似的方法,使用 PostMessage。所以你的代码看起来像这样:

procedure TMainForm.FormShow(Sender:TObject);
begin
  if (SubForm.ShowModal = mrOK) and bOption1 then
  begin
    PostMessage(Self.Handle, WM_SHOWMYDIALOG, 0, 0);
  end;
end;

WM_SHOWMYDIALOG 的处理程序然后显示实际消息。这种方法也适用于第 1 点,请参阅ain's answer。

PostMessage向您的应用程序的消息队列发布一条消息,该消息将在主窗体完成可见后进行处理。

【讨论】:

    【解决方案2】:

    另一个选项是使用 Mainform 的 OnActivate 而不是 onShow。

    【讨论】:

    【解决方案3】:

    如果我没听错的话

    const
        UM_AFTERSHOW   = WM_APP + 1;
    
    type
      TForm1 = class(TForm)
      protected
        procedure UMAfterShow(var Msg: TMessage); message UM_AFTERSHOW;
        procedure DoShow; override;
      end;
    
    
    procedure TForm1.DoShow;
    begin
      inherited;
      PostMessage(Self.Handle, UM_AFTERSHOW, 0, 0);
    end;
    
    procedure TForm1.UMAfterShow(var Msg: TMessage);
    begin
      ShowMessage('Enter the value');
    end;
    

    通过在 UMAfterShow 处理程序中显示您的消息,您可以让主窗体有机会变得可见,从而在后台显示。

    【讨论】:

      【解决方案4】:

      您看到的问题(如果我理解正确的话)是 FormShow 在您的主窗体实际可见之前被调用。因此消息对话框显示在您的主窗体之前。

      您需要做的是使用 PostMessage 将消息发布到您的主表单,然后您将处理该消息。这将使您的 FormShow 代码完成,并在显示表单后触发代码。

      以here 为例。

      【讨论】:

        【解决方案5】:

        另一种选择是在主窗体上放置一个 TTimer 组件以触发消息对话框。

        在您的主窗体上放置一个 TTimer 组件并将 enabled 属性设置为 False 并将时间从 1000 更改为 100。编写消息对话框并在计时器事件中将 Timer.Enabled 属性设置为 False 以避免重复触发。

        现在您可以在主窗体的 OnShow 事件中显示消息对话框的位置启用计时器。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-01
          • 1970-01-01
          • 2022-01-08
          • 1970-01-01
          • 2012-12-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多