c# - 区分用户关闭表单和用户关闭应用程序

标签 c# .net winforms

我正在处理以下场景:

  • 当用户尝试关闭我的应用程序中的一个特定表单时(通过 Ctrl + F4 或通过专用按钮),我需要他在满足某些条件时注销,
  • 因此,我覆盖了 OnFormClosed 方法,检查条件,如果满足,我会显示一个消息框,一旦用户单击“确定”,他就会从我的应用程序中注销,
  • 我正在调查 FormClosedEventArgs.CloseReason 并且仅在 UserClosing 的情况下应用此逻辑,
  • 但是,当用户尝试关闭整个应用程序时(通过 Alt + F4 或右上角的“关闭”按钮),CloseReason仍然是 UserClosing,因此他不会关闭应用程序,而是会看到消息框并随后退出应用程序。这是不希望的,因为应用程序关闭显然比注销更强大。

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

最佳答案

没有什么好的方法,您必须在 FormClosing 事件开始触发之前检测用户关闭主窗口。这不是 Winforms 中公开的功能,但您可以通过重写主窗口的 F​​orm 类中的 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);
    }

现在您可以在其他类中测试该变量:

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

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

关于c# - 区分用户关闭表单和用户关闭应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27817556/

相关文章:

c# - 将DataMemberAttribute 放在接口(interface)成员上是什么意思?

C# 图像去歪斜

winforms - Datagridview,禁用按钮/行

c# - C#/。NET ThreadException-创建窗口句柄时出错

带参数的 C# UITypeEditor

c# - 什么开源消息队列软件提供严格排序的持久性?

c# - 此属性不能在写入开始后设置!在 C# WebRequest 对象上

c# - 在 C# 中加密 SQLite 数据库

c# - SalesForce 查询方法不返回可用数据

c# - MVVM - 在 View 中显示来自多个模型实体的消息