none
如何动态显示notifyIcon.Text RRS feed

  • 问题

  • 简单的一个计时器。timer, timespan和notifyIcon,timer每秒Subtract一下

    notifyIcon有个方法

    private void notifyIcon1_MouseMove(object sender, MouseEventArgs e)
            {
                this.notifyIcon1.Text = ts.ToString();
            }

    但是效果是这样的,鼠标移到图标上后显示的是当前剩余计时,移开后再移上去,会更新这个计时。

    我希望能移上去以后一直显示动态的倒计时,请问该如何实现?(不是气泡提示)

    2011年3月2日 8:24

答案

  • 建议你使用气泡提示。因为托盘图标的提示字符串(NotifyIcon.Text)在用户鼠标停留在图标并显示提示字符串时并无法改变。我们可以调用Windows API Shell_NotifyIcon来为我们的程序增加,修改或删除系统托盘图标。详细文档请看:
    http://msdn.microsoft.com/en-us/library/bb762159(v=vs.85).aspx
    http://msdn.microsoft.com/en-us/library/bb773352(v=vs.85).aspx
    http://www.cnblogs.com/wind2005/archive/2009/07/20/shell_notifyicon.html
    http://blog.csdn.net/kvs112219/archive/2010/12/11/6069936.aspx

    即使我们调用Shell_NotifyIcon来手动改变系统托盘,并且该API返回True,提示字符串仍然不会改变。你可以参考测试下一下代码:
    ====================================================
            private void timer1_Tick(object sender, EventArgs e)
            {
                ts = ts.Subtract(new TimeSpan(0, 0, 1));
                var window = typeof(NotifyIcon).GetField("window", BindingFlags.Instance | BindingFlags.NonPublic);
                var windowValue = window.GetValue(notifyIcon1);
                var handle = windowValue.GetType().GetProperty("Handle");
                var handleValue = handle.GetValue(windowValue, new object[] { });
                NOTIFYICONDATA pnid = new NOTIFYICONDATA();
                pnid.uFlags |= 2;
                pnid.uFlags |= 4;
                pnid.uFlags |= 0x00000010;
                pnid.hWnd = (IntPtr)handleValue;
                pnid.uID = 1;
                pnid.hIcon = notifyIcon1.Icon.Handle;
                pnid.szTip = ts.ToString();
                int i = Shell_NotifyIcon(1, pnid);
            }
    ====================================================

    或者你可以考虑用另一种方法,但个人感觉显示效果很差。
    ====================================================
                notifyIcon1.Text = ts.ToString();
                notifyIcon1.Visible = false;
                notifyIcon1.Visible = true;
    ====================================================

    这里是使用气泡提示的代码,供你参考:
    ====================================================
            private void timer1_Tick(object sender, EventArgs e)
            {
                ts = ts.Subtract(new TimeSpan(0, 0, 1));
                notifyIcon1.BalloonTipText = ts.ToString();
                notifyIcon1.ShowBalloonTip(1000);
            }
    ====================================================

    谢谢!


    Michael Sun [MSFT]
    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载 MSDN 论坛好帮手
    • 已标记为答案 Jeuo 2011年3月8日 9:07
    2011年3月2日 14:05
  • 你好!

    写一个无边框的窗体来显示你的计时器。


    知识改变命运,奋斗成就人生!
    • 已标记为答案 Jeuo 2011年3月8日 9:07
    2011年3月7日 15:48
    版主

全部回复

  • 建议你使用气泡提示。因为托盘图标的提示字符串(NotifyIcon.Text)在用户鼠标停留在图标并显示提示字符串时并无法改变。我们可以调用Windows API Shell_NotifyIcon来为我们的程序增加,修改或删除系统托盘图标。详细文档请看:
    http://msdn.microsoft.com/en-us/library/bb762159(v=vs.85).aspx
    http://msdn.microsoft.com/en-us/library/bb773352(v=vs.85).aspx
    http://www.cnblogs.com/wind2005/archive/2009/07/20/shell_notifyicon.html
    http://blog.csdn.net/kvs112219/archive/2010/12/11/6069936.aspx

    即使我们调用Shell_NotifyIcon来手动改变系统托盘,并且该API返回True,提示字符串仍然不会改变。你可以参考测试下一下代码:
    ====================================================
            private void timer1_Tick(object sender, EventArgs e)
            {
                ts = ts.Subtract(new TimeSpan(0, 0, 1));
                var window = typeof(NotifyIcon).GetField("window", BindingFlags.Instance | BindingFlags.NonPublic);
                var windowValue = window.GetValue(notifyIcon1);
                var handle = windowValue.GetType().GetProperty("Handle");
                var handleValue = handle.GetValue(windowValue, new object[] { });
                NOTIFYICONDATA pnid = new NOTIFYICONDATA();
                pnid.uFlags |= 2;
                pnid.uFlags |= 4;
                pnid.uFlags |= 0x00000010;
                pnid.hWnd = (IntPtr)handleValue;
                pnid.uID = 1;
                pnid.hIcon = notifyIcon1.Icon.Handle;
                pnid.szTip = ts.ToString();
                int i = Shell_NotifyIcon(1, pnid);
            }
    ====================================================

    或者你可以考虑用另一种方法,但个人感觉显示效果很差。
    ====================================================
                notifyIcon1.Text = ts.ToString();
                notifyIcon1.Visible = false;
                notifyIcon1.Visible = true;
    ====================================================

    这里是使用气泡提示的代码,供你参考:
    ====================================================
            private void timer1_Tick(object sender, EventArgs e)
            {
                ts = ts.Subtract(new TimeSpan(0, 0, 1));
                notifyIcon1.BalloonTipText = ts.ToString();
                notifyIcon1.ShowBalloonTip(1000);
            }
    ====================================================

    谢谢!


    Michael Sun [MSFT]
    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载 MSDN 论坛好帮手
    • 已标记为答案 Jeuo 2011年3月8日 9:07
    2011年3月2日 14:05
  • 显示当前剩余计时的代码在哪?
    http://feiyun0112.cnblogs.com/
    2011年3月4日 1:25
    版主
  • 是问我吗? :)

    周末愉快!


    Michael Sun [MSFT]
    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载 MSDN 论坛好帮手
    2011年3月4日 1:27
  • 重写notifyIcon.
    微软技术,世界动力
    2011年3月4日 2:22
    版主
  • 你好!

    写一个无边框的窗体来显示你的计时器。


    知识改变命运,奋斗成就人生!
    • 已标记为答案 Jeuo 2011年3月8日 9:07
    2011年3月7日 15:48
    版主