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

时间:2015-01-07 10:40:12

标签: c# .net winforms

我正在处理以下情况:

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

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

2 个答案:

答案 0 :(得分:3)

没有好办法,你必须在 FormClosing事件开始触发之前检测到关闭主窗口的用户。不是Winforms中公开的功能,但您可以通过覆盖主窗口的Form类中的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登录之外添加登录程序是一个严重的错误,可能会泄露密码。

答案 1 :(得分:0)

我不认为有任何内置方法可以做你想做的事情(除了预处理系统按键)。用户在应用程序中启动的任何结束(MDI表单除外)将为ÙserClosing

一种解决方法可能是将您的表单嵌入另一种形式(将Owner设置为外部表单)并检查内部表单是否符合FormOwnerClosing原因(' d如果您点击外部表单上的' X'就会发生,并检查父表单上的UserClosing,而不是实际表单(内部表单),但我要说它更不优雅,会将你的代码分成两种不同的形式。