处理我。关闭e.Cancel与NotifyIcon失败

时间:2012-02-07 00:36:27

标签: vb.net visual-studio-2010 forms notifyicon

我的程序会提示用户在退出时保存信息。如果单击是,则>计划结束。如果点击取消>计划保持开放。

这是一个例子:

Private Sub Form_Close(ByVal sender As System.Object, ByVal e As FormClosingEventArgs) Handles Me.Closing
        e.Cancel = (MessageBox.Show("Are You Sure You Want To Exit?", "Backup Data", MessageBoxButtons.YesNo) = DialogResult.No)
        End If
    End Sub

以上工作正常,这也很好(在某种意义上说,如果点击是或取消,程序将不会关闭):

Private Sub Form_Close(ByVal sender As System.Object, ByVal e As FormClosingEventArgs) Handles Me.Closing
            e.Cancel = (MessageBox.Show("Are You Sure You Want To Exit?", "Backup Data", MessageBoxButtons.YesNo) = DialogResult.No)
            e.Cancel = True
            End If
        End Sub

在看到上述两者如何发挥作用之后,我所遇到的问题是为什么这不起作用:

Private Sub Form_Close(ByVal sender As System.Object, ByVal e As FormClosingEventArgs) Handles Me.Closing
        If e.CloseReason <> 0 Then
            e.Cancel = (MessageBox.Show("Are You Sure You Want To Exit?", "Backup Data", MessageBoxButtons.YesNo) = DialogResult.No)
        Else
            e.Cancel = True
        End If
    End Sub

表单最小化e.CloseReason = 0(使用MessageBox弹出窗口测试)。所以e.Cancel然后等于True,但程序无论如何都会自行关闭!

我的NotifyIcon唯一的修正是Me.Visible = False:

Private Sub Form1_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SizeChanged
If Me.WindowState = FormWindowState.Minimized Then
            Me.WindowState = FormWindowState.Minimized
            Me.Visible = False
            NotifyIcon1.Visible = True
            NotifyIcon1.BalloonTipText = "Minimized To The Tray" & vbCrLf & "Click This Icon To Display The Main Screen"
            NotifyIcon1.ShowBalloonTip(5000)
        End If
End Sub

如何以这种方式使用NotifyIcon时阻止程序关闭?

2 个答案:

答案 0 :(得分:1)

首先,据我所知,通过设置其Visible属性隐藏表单不会“关闭”窗口。它只是在保持实例有效的同时隐藏窗口(尽管窗口的句柄及其子控件AFAIK变为无效)。

其次,几乎没有任何东西能用CloseReason of None关闭窗口。对Form.Close()的调用将具有UserClosing的原因,就像单击标题栏中的X一样。对Application.Exit()的调用将拥有自己的erason,如果for因为其MDI父级或所有者而关闭,那么它们有其特定的原因。即使从任务管理器或Windows关闭结束程序也是已知的,可区别的原因。

您是否100%确定您的流程已终止?除非用户确认,否则您的代码几乎会阻止应用程序完全退出。但是,它不会阻止应用程序最小化到其托盘图标;在所有情况下,你可以截取和取消的唯一方法是覆盖WndProc并查找WParam为0(隐藏)的WM_SHOWWINDOW消息,和/或WParam为1(最小化)的WM_SIZE消息。设置窗口状态或可见性不会引发可取消的.NET事件,例如关闭窗口。

这是我为测试您所看到的行为而创建的基本应用。最重要的是,我将这个窗口(应用程序的主窗口)最小化到托盘图标没有任何问题。

namespace BasicFormClosingTest
{
    public class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            previousState = WindowState;
            if (WindowState != FormWindowState.Minimized)
                WindowState = FormWindowState.Minimized;

            Visible = false;
            notifyIcon1.Visible = true;
            notifyIcon1.BalloonTipText = "Minimized To Tray";
            notifyIcon1.ShowBalloonTip(2000);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel =
                MessageBox.Show(String.Format("Form Closing for reason {0}. Do you want to cancel?", e.CloseReason),
                                "Closing", MessageBoxButtons.YesNo) == DialogResult.Yes;
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Visible = true;
            notifyIcon1.Visible = false;
            WindowState = previousState == FormWindowState.Minimized ? FormWindowState.Normal : previousState;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.button3 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // notifyIcon1
            // 
            this.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon")));
            this.notifyIcon1.Text = "notifyIcon1";
            this.notifyIcon1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.notifyIcon1_MouseDoubleClick);
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(31, 52);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(153, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "Minimize To Tray";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button2
            // 
            this.button2.Location = new System.Drawing.Point(31, 82);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(153, 23);
            this.button2.TabIndex = 1;
            this.button2.Text = "Close";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // button3
            // 
            this.button3.Location = new System.Drawing.Point(31, 112);
            this.button3.Name = "button3";
            this.button3.Size = new System.Drawing.Size(153, 23);
            this.button3.TabIndex = 2;
            this.button3.Text = "Exit Application";
            this.button3.UseVisualStyleBackColor = true;
            this.button3.Click += new System.EventHandler(this.button3_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 262);
            this.Controls.Add(this.button3);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.NotifyIcon notifyIcon1;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.Button button3;
        private FormWindowState previousState;
    }
}

答案 1 :(得分:0)

我发现了这个问题: 我在Form1.vb之前加载了LoginForm.vb。 LoginForm.vb使用Form1.ShowDialog而不是Form1.Show(),这样当我最小化Form1.vb时,它实际上是将Form作为对话框最小化。