Delphi onshow 主窗体/模态窗体

发布于 2024-12-27 18:12:15 字数 313 浏览 2 评论 0原文

我有一个项目,有一个主窗体和一些其他窗体。 当应用程序加载时,它需要执行一些任务并在主窗体顶部以模式形式显示结果。 我遇到的问题是,如果我调用函数来执行任务/创建并在主窗体 onshow 事件中显示模态窗体,则模态窗体会出现,但主窗体不会出现,直到模态窗体关闭,即我期望发生什么。为了解决这个问题,我在主窗体中添加了一个计时器,并在主窗体 onshow 事件上启动它,计时器调用函数来执行任务/创建并显示模式窗体。所以现在主窗体出现在模态窗体之前。

然而,我不认为这是最好的解决方案,并且想知道是否有人可以提供更好的解决方案。

我正在使用 Delphi 7

科林

I have a project which has a main form and some other forms.
When the app loads it needs to carry out some tasks and show the results in a modal form on top of the main form.
The problem I have is that if I put the call to the function to do the tasks / creates and Show the modal form in the main forms onshow event the modal form appears but the main form does not until the modal form is closed, which is what I would expect to happen. To counter this I have added a timer to the main form and start it on the main forms onshow event the timer calls the function to do the tasks / create and show the modal form. So now the main form appears before the modal form.

However I cannot see this being the best solution and was wondering if anyone could offer a better one.

I am using Delphi 7

Colin

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤独难免 2025-01-03 18:12:15

一个常用的选项是在表单的 OnShow 中向自己发布一条消息。像这样:

const
  WM_SHOWMYOTHERFORM = WM_USER + 0;

type
  TMyMainForm = class(TForm)
    procedure FormShow(Sender: TObject);
  protected
    procedure WMShowMyOtherForm(var Message: TMessage); message WM_SHOWMYOTHERFORM;
  end;

...


procedure TMyMainForm.FormShow(Sender: TObject);
begin
  PostMessage(Handle, WM_SHOWMYOTHERFORM, 0, 0);
end;

procedure TMyMainForm.WMShowMyOtherForm(var Message: TMessage);
begin
  inherited;
  with TMyOtherForm.Create(nil) do begin
    try
      ShowModal;
    finally
      Free;
    end;
  end;
end;

One commonly used option is to post yourself a message in the form's OnShow. Like this:

const
  WM_SHOWMYOTHERFORM = WM_USER + 0;

type
  TMyMainForm = class(TForm)
    procedure FormShow(Sender: TObject);
  protected
    procedure WMShowMyOtherForm(var Message: TMessage); message WM_SHOWMYOTHERFORM;
  end;

...


procedure TMyMainForm.FormShow(Sender: TObject);
begin
  PostMessage(Handle, WM_SHOWMYOTHERFORM, 0, 0);
end;

procedure TMyMainForm.WMShowMyOtherForm(var Message: TMessage);
begin
  inherited;
  with TMyOtherForm.Create(nil) do begin
    try
      ShowModal;
    finally
      Free;
    end;
  end;
end;
回梦 2025-01-03 18:12:15

为什么不像这样使用 MainForm OnActivate 事件呢?

procedure TMyMainForm.FormActivate(Sender: TObject);
begin
  //Only execute this event once ...
  OnActivate := nil;

  //and then using the code David Heffernan offered ...
  with TMyOtherForm.Create(nil) do begin
    try
      ShowModal;
    finally
      Free;
    end;
end;

将事件设置为 nil 将确保此代码仅在启动时运行一次。

Why dont you use the MainForm OnActivate event like so?

procedure TMyMainForm.FormActivate(Sender: TObject);
begin
  //Only execute this event once ...
  OnActivate := nil;

  //and then using the code David Heffernan offered ...
  with TMyOtherForm.Create(nil) do begin
    try
      ShowModal;
    finally
      Free;
    end;
end;

Setting the event to nil will ensure that this code is only run once, at startup.

勿挽旧人 2025-01-03 18:12:15

OnShow 事件在调用 Windows API 函数 ShowWindow 之前立即触发。正是对 ShowWindow 的调用实际上导致窗口出现在屏幕上。

因此,理想情况下,您需要在调用 ShowWindow 后立即运行某些内容。事实证明,驱动这一切的 VCL 代码位于 CM_SHOWINGCHANGEDTCustomForm 消息处理程序内。该消息处理程序触发 OnShow 事件,然后调用 ShowWindow。因此,一个很好的解决方案是在 CM_SHOWINGCHANGED 处理程序运行后立即显示模态表单。像这样:

type
  TMyMainForm = class(TForm)
  private
    FMyOtherFormHasBeenShown: Boolean;
  protected
    procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED;
  end;

.....

procedure TMyMainForm.CMShowingChanged(var Message: TMessage);
begin
  inherited;
  if Showing and not FMyOtherFormHasBeenShown then begin
    FMyOtherFormHasBeenShown := True;
    with TMyOtherForm.Create(nil) do begin
      try
        ShowModal;
      finally
        Free;
      end;
    end;
  end;
end;

The OnShow event is fired immediately before the call to the Windows API function ShowWindow is made. It is this call to ShowWindow that actually results in the window appearing on the screen.

So you ideally need something to run immediately after the call to ShowWindow. It turns out that the VCL code that drives all this is inside a TCustomForm message handler for CM_SHOWINGCHANGED. That message handler fires the OnShow event and then calls ShowWindow. So an excellent solution is to show your modal form immediately after the handler for CM_SHOWINGCHANGED runs. Like this:

type
  TMyMainForm = class(TForm)
  private
    FMyOtherFormHasBeenShown: Boolean;
  protected
    procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED;
  end;

.....

procedure TMyMainForm.CMShowingChanged(var Message: TMessage);
begin
  inherited;
  if Showing and not FMyOtherFormHasBeenShown then begin
    FMyOtherFormHasBeenShown := True;
    with TMyOtherForm.Create(nil) do begin
      try
        ShowModal;
      finally
        Free;
      end;
    end;
  end;
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文