简体   繁体   English

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

[英]How Do I Show A Final Form On Exiting In Delphi?

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 EInvalid操作:无法在OnShow或OnHide中更改Visible

So how do I show a final form, while hiding the main form when exiting a program in Delphi? 那么如何在退出Delphi中的程序时隐藏主窗体时如何显示最终窗体?


Conclusion: Mghie confirmed that what I was trying was correct and should have worked. 结论:Mghie证实我所尝试的是正确的,应该有效。 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. 发现问题:我正在从ThankYouForm中关闭我的主要表单,并以某种方式回到ExitExecute,并且,它完全被束缚了。

But all's well again. 但一切都很好。 The MainForm.Hide before the ThankYouForm.ShowModal works perfectly. ThankYouForm.ShowModal之前的MainForm.Hide工作正常。

Thanks again, guys. 伙计们,再次感谢

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. 而不是试图将某些东西塞进主要形式,转到你知道其他一切已经完成运行的地方: Application.Run返回的地方。 Create a new procedure that creates, shows, and destroys your farewell form, and then call it in your DPR file like this: 创建一个创建,显示和销毁告别表单的新过程,然后在DPR文件中调用它,如下所示:

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 : 显示功能可以与Mghie的答案所展示的一致

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

You could do that in the OnClose handler of the main form. 您可以在主窗体的OnClose处理程序中执行此操作。 Be sure to ShowModal the other form, because otherwise it will be closed immediately when the closing of the main form terminates the application: 确保ShowModal是另一种形式,因为否则当主窗体的关闭终止应用程序时它会立即关闭:

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. 虽然我不能真正说明为什么你的代码会引发异常 - 你应该能够通过编译调试DCU,在引发异常的行上设置断点,并检查堆栈跟踪来找到答案。 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. 我假设表单属性和代码的某种组合导致另一个更高的Visible属性更高的堆栈,你需要找出它是什么并纠正它。 The code above should really work. 上面的代码应该真的有效。

I would put (try) any of the code supplied above in the main form's OnCloseQuery event. 我会在主窗体的OnCloseQuery事件中放置(尝试)上面提供的任何代码。 Ensure that can close := false until you are ready to close the main form. 确保关闭:= false,直到您准备关闭主窗体。

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. 方法完成后,操作系统队列中仍然存在消息,并且它们将由VCL分派和处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM