在做一个小程序时遇到这样一个问题,最小化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出来再赋值,则会对窗体进行展示。
程序员就是要有没事找事的精神和没有问题制造问题的勇气~ 希望这篇小小的文章对你能有所帮助和启发。