C#WinForm程序最小化后在托盘中隐藏方法以及几个关键点的简单分析

在做一个小程序时遇到这样一个问题,最小化Form程序后,想在托盘中隐藏,同时在任务栏中显示,双击任务栏图标再将程序显示出来。

因此在网上找了找,找到一篇实现的帖子。方法还不错,网上的实践方法也基本引用此帖:

位置:http://blog.csdn.net/cbgn/article/details/1412310

根据我个人的实践,对其中的几点内容做一些说明。都是一些困扰的小问题,可能会对朋友们有些帮助。

 

1.设置WinForm窗体属性showinTask=false  关联内容:最小化后热键失效

起初我没有使用属性字段,而是在运行时时候手动给这个字段赋值,同时我的程序中绑定了全局的热键,使用的是Windows提供的API方法 RegisterHotKey(),这样就造成了一个非常不希望的结果,当我最小化程序后,我的热键就失效了。查了CSDN 发现了和我有相同问题的帖子:

位置:http://topic.csdn.net/u/20110803/09/2c3fe776-0d0f-4fd3-b018-c21465836ebe.html

错误原因:引用帖子最后的结贴内容>>当窗体最小化以后,如果写了this.ShowInTaskbar = false;则窗体最小化到托盘,但实际上应该是被windows优化了,当点击托盘最大化窗体后,句柄会改变而且热键不响应,去掉这句万事ok了

小结:如果您在程序中与当前窗体句柄绑定了全局热键,那么如果想最小化窗体时不在托盘显示,请在窗体属性中对showinTask赋值,同时当您的热键失效的时候,检查是否有任何代码可能使窗体句柄发生变化。

 

2.加notifyicon控件notifyIcon1,为控件notifyIcon1的属性Icon添加一个icon图标。

不添加图标,在任务栏中是看不出来的。。。不信你试试。

 

3.最小化事件

原文中的方法是调用SizeChanged事件:

private void Form1_SizeChanged(object sender, EventArgs e)
{
	if (this.WindowState==FormWindowState.Minimized)
	{
		this.Hide();
	}
}

这个事件是在窗体大小改变时触发,窗体最小化 ->大小改变->隐藏

这里提供另外一种方法,调用Deactivate:

 private void Form1_Deactivate(object sender, EventArgs e)
 {
	if (this.WindowState == FormWindowState.Minimized)
         {
                this.Hide();
         }
}

在窗体变为不活动窗体时触发,窗体最小化->窗体不活动->隐藏

两种方法皆可,我个人倾向第二种,因为理解起来更好点,最小化,就是为了让窗体到后台运行,不活动么。。

 

4.显示过程

原文在显示后,将状态栏的小图标隐藏了。

private void notifyIcon1_Click(object sender, EventArgs e)
{
this.Visible = true;

this.WindowState = FormWindowState.Normal;

this.notifyIcon1.Visible = false;
}

我这里不想让小图标隐藏,加个了判断。

private void notifyIcon1_DoubleClick(object sender, EventArgs e)
{
            if (base.WindowState.Equals(FormWindowState.Minimized))
            {
                //顺序不能颠倒,否则你会后悔的!
                   base.Show();
                base.WindowState = FormWindowState.Normal;
            }
}

在这里。我之前没认为执行的两句颠倒有什么错,使用颠倒的顺序执行,窗口就是在做下角最小化,不会整体显示出来,点击上面的还原窗口也没用。

这样:再次双击通知栏的图标变这样:,反正就是展示不出来。

 

只有先将之前隐藏的窗体展示出来,再将窗体状态改为正常,才会是将窗体整个展现出来。先改变状态,窗体在被显示的时候,就会按照已经是最小化的状态,展示出来,而不会按照还原的方式展现。

具体为什么会这样,看看windows的代码就明白了(Reflector好用啊):

public void set_WindowState(FormWindowState value)
{
    if (!ClientUtils.IsEnumValid(value, (int) value, 0, 2))
    {
        throw new InvalidEnumArgumentException("value", (int) value, typeof(FormWindowState));
    }
    if ((!this.TopLevel || !this.IsRestrictedWindow) || (value == FormWindowState.Normal))
    {
        switch (value)
        {
            case FormWindowState.Normal:
                base.SetState(0x10000, false);
                break;

            case FormWindowState.Minimized:
            case FormWindowState.Maximized:
                base.SetState(0x10000, true);
                break;
        }
        if (base.IsHandleCreated && base.Visible)
        {
            IntPtr handle = base.Handle;
            switch (value)
            {
                case FormWindowState.Normal:
                    SafeNativeMethods.ShowWindow(new HandleRef(this, handle), 1);
                    break;

                case FormWindowState.Minimized:
                    SafeNativeMethods.ShowWindow(new HandleRef(this, handle), 6);
                    break;

                case FormWindowState.Maximized:
                    SafeNativeMethods.ShowWindow(new HandleRef(this, handle), 3);
                    break;
            }
        }
        this.formState[FormStateWindowState] = (int) value;
    }
}

这是WindowState 属性的set方法,注意:如果是不可见的时候,只会更改他的状态,所以再展示的时候,只是将最小化时的样子展示出来了,而不会还原到原来的样子,而先show出来再赋值,则会对窗体进行展示。

程序员就是要有没事找事的精神和没有问题制造问题的勇气~ 希望这篇小小的文章对你能有所帮助和启发。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘少博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值