如何在 Delphi 中退出时显示最终表单?

发布于 2024-08-12 04:08:52 字数 636 浏览 7 评论 0原文

对于某人来说这应该是一个简单的问题。我只是不知道该怎么做。

退出程序后,我想隐藏主窗体并单独显示最终的“谢谢”窗体,如下所示:

procedure TMainForm.ExitExecute(Sender: TObject);
begin
  MainForm.Visible := false;
  ThankYouForm.Show;
  MainForm.Close;
end;

但是当我这样做时,我得到了异常:

E无效操作:无法更改 OnShow 或 OnHide 中的可见内容

那么,如何在 Delphi 中退出程序时显示最终窗体,同时隐藏主窗体?


结论:Mghie 确认我的尝试是正确的并且应该有效。这表明我在退出和关闭表单的过程中存在一个错误,导致了此异常。

现在我知道了这一点,我很快就能找到并解决问题。


发现问题:我正在从ThankYouForm中关闭我的主窗体,并且不知何故循环回ExitExecute,然后,它全部被堵塞了。

但一切又都好起来了。 ThankYouForm.ShowModal 之前的 MainForm.Hide 工作得很好。

再次感谢你们。

This should be a simple one for someone. I just can't figure out how to do it.

Upon exiting of my program, I want to hide the main form and make a final "Thank You" form appear on its own, like this:

procedure TMainForm.ExitExecute(Sender: TObject);
begin
  MainForm.Visible := false;
  ThankYouForm.Show;
  MainForm.Close;
end;

But when I do that, I get the Exception:

EInvalid Operation: Cannot change Visible in OnShow or OnHide

So how do I show a final form, while hiding the main form when exiting a program in Delphi?


Conclusion: Mghie confirmed that what I was trying was correct and should have worked. That indicated that I had a bug somewhere in my procedures of exiting and closing from my forms that was bringing up this exception.

Now that I know that, it won't take me long to find and fix the problem.


Found the problem: I was closing my main form from within the ThankYouForm, and that somehow looped back through into ExitExecute and, well, it got all bunged up.

But all's well again. The MainForm.Hide before the ThankYouForm.ShowModal works perfectly.

Thanks again, guys.

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

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

发布评论

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

评论(4

删除→记忆 2024-08-19 04:08:52

不要尝试将某些内容硬塞到主窗体中,而是转到您知道其他所有内容都已完成运行的位置:Application.Run 返回的点。创建一个新过程,用于创建、显示和销毁告别表单,然后在 DPR 文件中调用它,如下所示:

begin
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
  TThankYouForm.Execute;
end.

显示函数可以类似于 Mghie 的回答展示了什么

class procedure TThankYouForm.Execute;
begin
  with Create(nil) do try
    ShowModal;
  finally
    Free;
  end;
end;

Instead of trying to shoehorn something into the main form, go to the place where you know everything else is finished running: the point where Application.Run returns. Create a new procedure that creates, shows, and destroys your farewell form, and then call it in your DPR file like this:

begin
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
  TThankYouForm.Execute;
end.

The display function can be along the lines of what Mghie's answer demonstrated:

class procedure TThankYouForm.Execute;
begin
  with Create(nil) do try
    ShowModal;
  finally
    Free;
  end;
end;
汐鸠 2024-08-19 04:08:52

您可以在主窗体的 OnClose 处理程序中执行此操作。确保 ShowModal 另一个表单,因为否则当主表单关闭终止应用程序时它将立即关闭:

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Hide;
  with TThankYouForm.Create(nil) do try
    ShowModal;
  finally
    Free;
  end;
  Action := caFree;
end;

或者甚至

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Hide;
  with TThankYouForm.Create(Application) do
    ShowModal;
  Action := caFree;
end;

确保使该行为可选 - 当用户关闭应用程序时他们已经结束了,并不是每个人都对那些不愿消失的项目感到满意。

编辑:

好的,在试用期结束时显示这样的表格确实有意义。虽然我不能真正说出为什么您的代码会引发异常 - 您应该能够通过使用调试 DCU 进行编译、在引发异常的行上设置断点并检查堆栈跟踪来找出答案。我假设表单属性和代码的某种组合会导致堆栈上方的 Visible 属性发生另一次更改,您需要找出它是什么并进行更正。上面的代码应该确实有效。

You could do that in the OnClose handler of the main form. Be sure to ShowModal the other form, because otherwise it will be closed immediately when the closing of the main form terminates the application:

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Hide;
  with TThankYouForm.Create(nil) do try
    ShowModal;
  finally
    Free;
  end;
  Action := caFree;
end;

or even

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Hide;
  with TThankYouForm.Create(Application) do
    ShowModal;
  Action := caFree;
end;

And be sure to make the behaviour optional - when the user closes the app they are finished with it, and not everybody is pleased with programs that are so reluctant to go away.

Edit:

OK, showing such a form at the end of the trial period does indeed make sense. And while I can't really say why your code raises the exception - you should be able to find out by compiling with debug DCUs, setting a breakpoint on the line that raises the exception, and examine the stack trace. I assume some combination of the form properties and your code leads to another change of the Visible property higher up the stack, and you need to find out what it is and correct that. The code above should really work.

感性不性感 2024-08-19 04:08:52

我会将(尝试)上面提供的任何代码放在主窗体的 OnCloseQuery 事件中。确保 can close := false 直到您准备好关闭主窗体。

I would put (try) any of the code supplied above in the main form's OnCloseQuery event. Ensure that can close := false until you are ready to close the main form.

夏末 2024-08-19 04:08:52

这可能是由于方法调用顺序与消息处理程序处理顺序之间的差异造成的。在您的方法完成后,操作系统队列中仍然有消息,它们正在由 VCL 调度和处理。

This may be caused by difference between order of method calls with order of message handler processing. After your method has completed there are still messages in operating system queue and they are being dispatched and handled by VCL.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文