区分用户关闭表单和用户关闭应用

Distinguish between user closing form and user closing app

我正在处理以下场景:

所以我的问题 - 是否有一种很好的方法来区分用户关闭表单或用户关闭整个应用程序?我可能可以通过覆盖 ProcessCmdKey 来设置一些 bool 标志,以区分 Alt + F4Ctrl + F4,但这不是很好,也没有解决单击关闭按钮时的问题。

我不认为有任何内置方法可以做你想做的事(除了预处理系统击键)。用户在应用程序中发起的任何关闭(MDI 表单除外)都将是 ÙserClosing.

一个解决方法是将您的表单嵌入到另一个表单中(将 Owner 设置为外部表单)并检查内部表单关闭是否具有 FormOwnerClosing 原因(即如果您单击外部表单上的 'X' 会发生这种情况),并检查父表单上的 UserClosing 而不是实际表单(内部表单),但我认为这更不优雅而且会将您的代码拆分为两种不同的形式。

没有什么好的方法,您必须在 FormClosing 事件开始触发之前 window 检测到用户关闭了您的主要 window 。这不是 Winforms 中公开的功能,但您可以通过覆盖主 window 的表单 class 中的 WndProc() 方法轻松添加它。您对 WM_SYSCOMMAND 消息感兴趣,SC_CLOSE 命令:

    public static bool MainWindowClosing;

    protected override void WndProc(ref Message m) {
        if (m.Msg == 0x112 && (m.WParam.ToInt32() & 0xfff0) == 0xf060) {
            MainWindowClosing = true;
        }
        base.WndProc(ref m);
    }

现在您可以在其他 classes:

中测试该变量
    protected override void OnFormClosing(FormClosingEventArgs e) {
        if (!Form1.MainWindowClosing && e.CloseReason == CloseReason.UserClosing) {
            // Display your dialog
            //...
        }
        base.OnFormClosing(e);
    }

如果您采取任何措施阻止用户关闭您的应用,则需要将 MainWindowClosing 设置回 false。我不想提的是,在高度安全的 Windows 登录之外添加登录过程是一个严重的错误,很可能会泄露密码。