2009-02-23 14 views

Respuesta

24

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. Puede 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 }); 
     } 
    } 
+0

¿Algún truco para C++? –

+0

No es necesario hackear, solo necesita establecer la macro WINVER correctamente para que el compilador sepa que al menos está apuntando a Windows 2000. –

+0

Lo siento, quiero superar la limitación similar en 'szInfoTitle', que establece el título para un globo emergente . ¿Hay alguna solución para eso también? –

-4

bk1e aquí dice que el límite es de 128 caracteres, ahora, si se utiliza UTF-16, que es el formato Unicode nativo en las ventanas y en especial .NET, eso significa que está limitado a 64 caracteres , incluyendo 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, permitiendo el uso de 128 8- caracteres de bit (incluido el nulo).

EDIT: Esta respuesta es incorrecta, aquí es un comentario como útiles por Cody gris que explica por qué:

Este razonamiento es convincente, pero no es realmente 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 gris Jun 19 a las 04:11"

+0

¿Dónde encontraste personajes de 32 bits? ¡Yo también quiero algunos! – configurator

+0

No creo que existan, estrictamente hablando, pero UTF-32 los usa como una conveniencia aunque solo necesite 24 bits por carácter. :) Aunque es extraño, sospecho que Windows usa UTF-16, por lo que es curioso por qué lo han limitado a 64 caracteres. Tal vez están permitiendo sustitutos? – Arafangion

+1

Me limitaría a sospechar que este es un límite típico de mierda. Alguien en MS inventó 64 caracteres y así es. No hay ciencia espacial involucrada, o simplemente no habría un límite como este. – ypnos

8

De la documentación de MSDN en el Win32 NOTIFYICONDATA structure:

szTip

Una cadena terminada en cero que especifica el texto de una norma información sobre herramientas. puede tener un máximo de 64 caracteres , incluyendo el carácter nulo de terminación.

Para Windows 2000 (versión 5.0 de Shell32.dll) 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í.

1

Expandiendo la respuesta correcta de bk1e.

Debajo del capó, un icono de la 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.

1

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 de iconos, por lo que solo desaparece después de un tiempo de espera o si el usuario hace clic en la pequeña X- botón.

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

EDIT:ShowBalloonTip() incendios Además en cascada MouseMove eventos, por lo que es necesario desactivar este evento hasta el momento en que la información sobre herramientas globo está oculto. Además, BalloonTipClosed (según the documentation) 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 auxiliar para restablecer el estado, en lugar de confiar en el evento BalloonTipClosed. El código revisado y probado es el siguiente:

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 globo con un buen montón de texto, que utiliza esta solución puede ser seen in by blog.

Cuestiones relacionadas