visual c# winforms systray

c# - visual - ¿Cómo puedo mostrar una sugerencia de herramienta de bandeja de más de 63 caracteres?



tooltip c# (5)

¿Cómo puedo mostrar una sugerencia de herramienta de bandeja de más de 63 caracteres? NotifyIcon.Text tiene un límite de 63 caracteres, pero he visto que el servidor VNC tiene una información sobre herramientas más larga.

¿Cómo puedo hacer lo que hace el servidor VNC?


Ampliando la respuesta correcta de bk1e.

Debajo del capó, un ícono de bandeja del sistema en WinForms se implementa como un icono de notificación de Win32. Por lo tanto, la versión de winforms tiene todas las limitaciones como la nativa. La limitación del tamaño de la información sobre herramientas es solo un ejemplo.


De la documentación de MSDN en la estructura NOTIFYICONDATA de Win32:

szTip

Una cadena terminada en nulo que especifica el texto para una información sobre herramientas estándar. Puede tener un máximo de 64 caracteres, incluido el carácter nulo de terminación.

Para Windows 2000 (Shell32.dll versión 5.0) y posterior, szTip puede tener un máximo de 128 caracteres, incluido el carácter nulo de terminación.

Parece que la biblioteca de Windows Forms admite el mínimo común denominador aquí.


En realidad, es un error en el establecimiento de la propiedad Text. La declaración P / Invoke para NOTIFYICONDATA dentro de Windows Forms utiliza el límite de 128 caracteres. Puedes hackearlo con Reflection:

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 }); } }


bk1e aquí dice que el límite es de 128 caracteres, ahora, si usa UTF-16, que es el formato nativo de Unicode en Windows y especialmente .NET, eso significa que tiene 64 caracteres como máximo, incluido el NUL.

Creo que está utilizando una API Unicode que limita la información sobre herramientas a 64 caracteres de 16 bits (incluido el nulo), y que el servidor VNC utiliza api ascii (o ANSI) en su lugar, lo que permite el uso de 128 caracteres de 8 bits (incluyendo el nulo).

EDITAR: Esta respuesta es incorrecta, aquí hay un comentario útil de Cody Gray que explica por qué:

Este razonamiento es convincente, pero en realidad no es correcto. Cuando la documentación de MSDN habla de "caracteres", en realidad significa la cantidad de elementos char o wchar_t en la matriz (dependiendo de si se dirige a Unicode). Entonces obtienes los 128 caracteres completos prometidos cuando se ejecuta en Windows 2000+. Windows 9x estaba limitado a 64 caracteres. - Cody Gray, 19 de junio a las 4:11 "


Recientemente me encontré con un problema similar. En lugar de piratear el back-end, implementé un work-around, que hace uso de BalloonTipText, que puede acomodar una gran cantidad de personajes.

La información sobre herramientas se muestra en el primer evento MouseMove sobre el icono de la bandeja y la información sobre herramientas se muestra durante 2 segundos. Después de que la información sobre herramientas esté cerrada, se puede volver a abrir nuevamente mediante un nuevo evento MouseMove.

El único inconveniente de esta solución es que no es posible cerrar el globo programáticamente, cuando un usuario, por ejemplo, abandona el área del icono, por lo que solo desaparece después de un tiempo de espera o si el usuario hace clic en el pequeño botón X.

Tenga en cuenta que el título y el texto pueden establecerse en cualquier momento en cualquier parte del programa. Se establecen aquí en el evento solo con fines de demostración.

EDIT: ShowBalloonTip() MouseMove eventos MouseMove cascada, por lo que es necesario desactivar este evento hasta que se oculte la información sobre herramientas del globo. Además, BalloonTipClosed (según la documentación ) solo se activa cuando el usuario hace clic activamente en ''X'', aunque observé que se disparaba cuando la información sobre herramientas se cerraba después de un tiempo de espera. Por lo tanto, agregué un temporizador de ayuda para restablecer el estado, en lugar de confiar en el evento BalloonTipClosed . El código revisado y probado está a continuación:

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; }

EDIT 2: una captura de pantalla de una información sobre herramientas de globo con bastante texto, que utiliza esta solución se puede ver en el blog .