63 文字を超える systray ツールチップを表示するにはどうすればよいですか? NotifyIcon.Text には 63 文字の制限がありますが、VNC サーバーにはより長いツールチップがあることがわかりました。
VNC サーバーが行うことをどのように行うことができますか?
実際には、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 });
}
}
Win32 NOTIFYICONDATA構造に関するMSDNドキュメントから:
szTip
標準のツールチップのテキストを指定するnullで終了する文字列。終了ヌル文字を含めて、最大64文字にすることができます。
Windows 2000(Shell32.dllバージョン5.0)以降の場合、szTipは、終了ヌル文字を含めて最大128文字にすることができます。
Windowsフォームライブラリは、ここで最小公分母をサポートしているようです。
bk1eの正解を拡張します。
内部では、WinForms のシステム トレイ アイコンは Win32 通知アイコンとして実装されています。したがって、winforms バージョンには、ネイティブ バージョンと同様のすべての制限があります。ツールチップのサイズ制限は、ほんの一例です。
最近、同様の問題に遭遇しました。バックエンドをハッキングするのではなく、非常に多くの文字に対応できる BalloonTipText を使用する回避策を実装しました。
ツールチップは、トレイ アイコン上の最初の MouseMove イベントで表示され、ツールチップは 2 秒間表示されます。ツールチップが閉じられると、新しい MouseMove イベントによって再度開くことができます。
このソリューションの唯一の欠点は、ユーザーがアイコン領域を離れたときにバルーンをプログラムで閉じることができないため、タイムアウト後またはユーザーが小さな X ボタンをクリックした場合にのみバルーンが消えることです。
タイトルとテキストは、プログラムの他の場所でいつでも設定できることに注意してください。これらは、デモンストレーションのみを目的としてイベントに設定されています。
編集: ShowBalloonTip()
追加のカスケードMouseMove
イベントを発生させるため、バルーン ツールチップが非表示になるまで、このイベントを無効にする必要があります。さらに、 (ドキュメントBalloonTipClosed
によると)ユーザーがアクティブに「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: このソリューションを利用するかなり多くのテキストを含むバルーン ツールチップのスクリーンショットは、ブログで見ることができます。
ここで bk1e は、制限が 128 文字であると言っています。現在、Windows、特に .NET のネイティブ Unicode 形式である UTF-16 を使用する場合、NUL を含めて 64文字に制限されていることを意味します。
ツールチップを 64 個の 16 ビット文字 (null を含む) に制限する Unicode API を使用しており、VNC サーバーは代わりに ascii (または ANSI) API を使用して、128 個の 8 ビット文字 (を含む) を使用できるようにしていると思います。ヌル)。
編集: この答えは間違っています。理由を説明する Cody Gray による有益なコメントを次に示します。
この推論は説得力がありますが、実際には正しくありません。MSDN のドキュメントで「文字」について言及されている場合、実際には配列内の char または wchar_t 項目の数を意味します (Unicode を対象としているかどうかによって異なります)。そのため、Windows 2000 以降で実行するときに約束された 128 文字を完全に取得できます。Windows 9x では 64 文字に制限されていました。– コーディ・グレイ 6 月 19 日 4:11"