C# 如何显示长度超过63个字符的systray工具提示?

C# 如何显示长度超过63个字符的systray工具提示?,c#,winforms,systray,C#,Winforms,Systray,如何显示长度超过63个字符的systray工具提示?Text有63个字符的限制,但我已经看到VNC服务器有更长的工具提示 我如何做VNC服务器所做的事情?bk1e这里说,现在,如果您使用UTF-16,这是windows特别是.NET中的本机unicode格式,则限制为128个字符,这意味着您被限制为64个字符,包括NUL 我相信您使用的unicode API将工具提示限制为64个16位字符(包括null),而VNC服务器使用ascii(或ANSI)API,允许使用128个8位字符(包括null)

如何显示长度超过63个字符的systray工具提示?Text有63个字符的限制,但我已经看到VNC服务器有更长的工具提示


我如何做VNC服务器所做的事情?

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

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

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


这一推理令人信服,但实际上并不正确。当MSDN文档谈到“字符”时,它实际上意味着数组中字符或wchar\t项的数量(取决于您是否以Unicode为目标)。因此,在Windows 2000+上运行时,您将获得承诺的完整128个字符。Windows 9x限制为64个字符科迪·格雷6月19日4:11“


从Win32上的MSDN文档中:

szTip

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

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


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

扩展bk1e的正确答案


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

实际上,这是文本属性的属性设置器中的一个错误。NOTIFYICONDATA在窗口内的p/Invoke声明s窗体使用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 });
      }
    }

我最近遇到了一个类似的问题。我没有对后端进行黑客攻击,而是实现了一个变通方法,它利用了BalloadTiptText,它可以容纳相当多的字符

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

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

请注意,标题和文本可以随时在程序中的其他位置进行设置。它们在事件中的设置仅用于演示目的

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

    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:使用此解决方案的气球工具提示的屏幕截图,包含大量文本。

您在哪里找到32位字符?我也想要一些!严格来说,我认为它们不存在,但UTF-32使用它们作为一种方便,尽管它只需要每个字符大约24位。:)这很奇怪-我怀疑windows使用UTF-16,所以很奇怪为什么他们将其限制为64个字符。也许他们允许使用代理?我只是怀疑这是一个典型的胡说八道的限制。微软有人提出了64个字符,就是这样。没有涉及火箭科学,或者根本就不会有这样的限制。这个理由是令人信服的,但不是实际上不正确。当MSDN文档谈到“字符”时,它实际上是指数组中
char
wchar\t
项的数量(取决于您是否针对Unicode)因此,在Windows 2000上运行时,您可以得到128个字符。Windows 9x限制为64个字符。@ CODYGRY:迄今为止最有帮助的注释。感谢启迪。任何针对C++的黑客攻击?没有必要的黑客攻击,您只需要正确设置WINVER宏,这样编译器就知道您至少瞄准了Windows 2000。对不起,我是WAW。nt以克服
szInfoTitle
中的类似限制,该限制为气球弹出窗口设置标题。是否也有解决方法?