【问题标题】:ExitProcess from the OnShow event of MainForm in DelphiDelphi 中 MainForm 的 OnShow 事件的 ExitProcess
【发布时间】:2009-05-26 19:30:03
【问题描述】:

我有一个应用程序在启动时检查一些条件并在主窗体的 OnShow 事件中启动一个外部程序。问题是如果启动外部程序时出现错误,我希望应用程序立即终止。但是有一个问题,因为 EurekaLog 捕获了我的异常,并通过否定所有对 Application.Teminate 的调用和任何其他正常的关闭方法来以某种方式破坏那里的消息循环。

所以这是我的问题,当这种情况存在时,ExitProcess 是否是立即终止我的应用程序的最佳途径?

【问题讨论】:

    标签: delphi winapi


    【解决方案1】:

    OnShow 被触发时,您已经进入程序太深,无法决定您真的不希望程序运行。你应该早点做出这个决定。 OnShow 不是决定不显示表单的地方。

    这是您在创建主表单之前应该检查的事情。将您的检查放入 DPR 文件中,如果您确定该程序不应运行,则只需调用 exit

    begin
      Application.Initialize;
      if not ApplicationShouldReallyStart then
        exit;
      Application.CreateForm(TMainAppForm, MainAppForm);
      Application.Run;
    end.
    

    填写您自己的ApplicationShouldReallyStart 实现。 (它确实应该是一个单独的函数,而不是内嵌在 DPR 文件中。如果 DPR 文件中的 begin-end 块太复杂,IDE 会感到困惑。)

    除此之外,请勿致电ExitProcess。请致电HaltHalt 调用 ExitProcess,但它也调用单元终结部分和其他特定于 Delphi 的进程关闭任务。

    【讨论】:

    • 我同意。为什么不尝试从 dpr 启动外部程序,如果失败就不要继续。这样就不需要 Halt,wmClose 或者你有什么。
    • 是的,我想我会在创建主窗体之前检查条件。
    • 一个不错的有效问题和一个不错的优雅答案 +1 为你们俩:Pusher 和 Popper :) 永远不要溢出堆栈! ;P
    【解决方案2】:

    系统一起工作,而不是反对它!你不能简单地死在事情的中间。如果您想死,请在规则内执行 - WM_CLOSE 或者您自己的例程,说明它为什么会死,然后发送 WM_CLOSE。

    【讨论】:

      【解决方案3】:

      你最好向窗口发送一条 wmClose 消息。否则,您很有可能会因为其他消息发送到表单而陷入麻烦。

      【讨论】:

      • 唯一的缺点是应用程序会在屏幕上短暂闪烁。为避免闪烁,请先将表单移出屏幕。
      • @skamradt,说得好。虽然我想给出一条错误消息,让用户知道为什么应用程序没有启动。
      【解决方案4】:

      我写了一个小应用程序来测试一个理论,这就是我的建议。

      调用 CLOSE 方法。

      以下示例单元在 D2009 中关闭应用程序且没有错误。

      unit Unit1;
      
      interface
      
      uses
        Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
        Dialogs;
      
      type
        TForm1 = class(TForm)
          procedure FormShow(Sender: TObject);
        private
          { Private declarations }
        public
          { Public declarations }
        end;
      
      var
        Form1: TForm1;
      
      implementation
      
      {$R *.dfm}
      
      procedure TForm1.FormShow(Sender: TObject);
      begin
         close;
      end;
      
      end.
      

      【讨论】:

      • 我无法调用 close 方法,因为 Eurekalog 在获取异常时会阻止主窗体在此时关闭并且主窗体仍然出现。
      • 那么您可以告诉 Eurekalog 忽略该异常(类型)或将其他程序的启动放在项目文件中。通过将它放在项目文件中,您可以在创建主窗体之前或在 application.run 命令之前捕获它。
      【解决方案5】:

      虽然我完全同意 Rob Kennedy 的观点,但我想指出,您可以使用 EurekaLog 的例程来控制错误对话框行为。 例如:

      uses
        ExceptionLog, ECore;
      ...
      begin
        ForceApplicationTermination(tbTerminate);
        // ... <- Bad code goes there
      end;
      

      这样,应用程序将在显示错误对话框后立即关闭。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-28
        • 1970-01-01
        • 2016-03-09
        • 1970-01-01
        • 2020-10-25
        相关资源
        最近更新 更多