21

如何显示超过 63 个字符的系统托盘工具提示?NotifyIcon.Text 有 63 个字符的限制,但我看到 VNC Server 的工具提示更长。

我怎样才能做 VNC 服务器所做的事情?

4

5 回答 5

33

实际上,这是 Text 属性的属性设置器中的一个错误。Windows 窗体中 NOTIFYICONDATA 的 P/Invoke 声明使用 128 个字符的限制。你可以用反射来破解它:

using System;
using System.Windows.Forms;
using System.Reflection;

    public class Fixes {
      public static void SetNotifyIconText(NotifyIcon ni, string text) {
        if (text.Length >= 128) throw new ArgumentOutOfRangeException("Text limited to 127 characters");
        Type t = typeof(NotifyIcon);
        BindingFlags hidden = BindingFlags.NonPublic | BindingFlags.Instance;
        t.GetField("text", hidden).SetValue(ni, text);
        if ((bool)t.GetField("added", hidden).GetValue(ni))
          t.GetMethod("UpdateIcon", hidden).Invoke(ni, new object[] { true });
      }
    }
于 2009-02-24T02:44:57.413 回答
9

从 Win32 NOTIFYICONDATA 结构的 MSDN 文档中:

szTip

一个以 null 结尾的字符串,它指定标准工具提示的文本。它最多可以有 64 个字符,包括终止空字符。

对于 Windows 2000(Shell32.dll 5.0 版)及更高版本,szTip 最多可以有 128 个字符,包括终止空字符。

看起来 Windows 窗体库在这里支持最低公分母。

于 2009-02-24T01:28:13.243 回答
1

扩展 bk1e 的正确答案。

在后台,WinForms 中的系统托盘图标被实现为 Win32 通知图标。因此,winforms 版本具有与本机版本一样的所有限制。工具提示大小限制只是一个例子。

于 2009-02-24T02:18:13.107 回答
1

我最近遇到了一个类似的问题。我没有破解后端,而是实现了一种变通方法,它利用了 BalloonTipText,它可以容纳相当多的字符。

工具提示显示在托盘图标上的第一个 MouseMove 事件上,并且工具提示显示 2 秒。工具提示关闭后,可以通过新的 MouseMove 事件再次打开它。

此解决方案的唯一缺点是无法以编程方式关闭气球,例如,当用户离开图标区域时,它只会在超时或用户单击小 X 按钮后消失。

请注意,可以在程序的其他地方随时设置标题和文本。在活动中设置它们仅用于演示目的。

编辑: ShowBalloonTip()触发附加级联MouseMove事件,因此有必要禁用此事件,直到气球工具提示被隐藏。此外,BalloonTipClosedis(根据文档)仅在用户主动单击“X”时触发,尽管我观察到它在超时后关闭工具提示时触发。因此,我添加了一个辅助计时器来重置状态,而不是依赖于BalloonTipClosed事件。修改和测试的代码如下:

    private bool balloonTipShown;
    private Timer balloonTimer;
    private void trayIcon_MouseMove(object sender, MouseEventArgs e)
    {
        if (balloonTipShown)
        {
            return;
        }
        balloonTipShown = true;
        trayIcon.MouseMove -= trayIcon_MouseMove;
        balloonTimer = new Timer();
        balloonTimer.Tick += balloonTimer_Tick;
        balloonTimer.Interval = 2005;
        balloonTimer.Start();
        trayIcon.ShowBalloonTip(2000);
    }

    void balloonTimer_Tick(object sender, EventArgs e)
    {
        balloonTipShown = false;
        balloonTimer.Stop();
        balloonTimer.Dispose();
        trayIcon.MouseMove += trayIcon_MouseMove;
    }

编辑 2:可以在 blog 中看到使用此解决方案的带有大量文本的气球工具提示的屏幕截图。

于 2013-03-12T10:09:40.147 回答
-4

bk1e 在这里说限制是 128 个字符,现在,如果您使用 UTF-16,这是 Windows 尤其是 .NET 中的本机 unicode 格式,这意味着您被限制为 64 个字符,包括 NUL。

我相信您使用的 unicode API 将工具提示限制为 64 个 16 位字符(包括 null),而 VNC 服务器使用 ascii(或 ANSI)api,允许使用 128 个 8 位字符(包括空值)。

编辑:这个答案是错误的,这是 Cody Gray 的有用评论,解释了原因:

这个推理很有说服力,但实际上并不正确。当 MSDN 文档谈到“字符”时,它实际上是指数组中 char 或 wchar_t 项的数量(取决于您是否针对 Unicode)。因此,当您在 Windows 2000+ 上运行时,您将获得承诺的全部 128 个字符。Windows 9x 被限制为 64 个字符。– 科迪·格雷 6 月 19 日 4:11"

于 2009-02-23T22:39:02.057 回答