2009-02-23 7 views

risposta

24

In realtà, si tratta di un bug nel setter della proprietà Text. La dichiarazione P/Invoke per NOTIFYICONDATA in Windows Form utilizza il limite di 128 caratteri. Puoi incidere il problema 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

Qualsiasi hack per C++? –

+0

Nessuna modifica necessaria, devi solo impostare correttamente la macro WINVER in modo che il compilatore sappia che hai almeno il targeting per Windows 2000. –

+0

Scusa, voglio superare la limitazione simile in 'szInfoTitle', che imposta il titolo per un popup a fumetto . C'è una soluzione anche per questo? –

-4

bk1e qui dice che il limite è di 128 caratteri, ora, se si utilizza UTF-16, che è il formato Unicode nativo in Windows e in particolare .NET, significa che si sono limitati a 64 caratteri , compreso il NUL .

Credo che si stia utilizzando un'API Unicode che limita le descrizioni dei comandi a 64 caratteri a 16 bit (compreso il null) e che VNC Server utilizza invece API ASCII (o ANSI), consentendo l'uso di 128 8- caratteri bit (incluso il null).

EDIT: Questa risposta è sbagliata, ecco un commento utili dai Cody Grey spiegando perché:

Questo ragionamento è convincente, ma in realtà non è corretto. Quando la documentazione MSDN parla di "caratteri", in realtà significa il numero di elementi char o wchar_t nell'array (a seconda che il targeting sia Unicode). Quindi ottieni i 128 caratteri completi promessi durante l'esecuzione su Windows 2000+. Windows 9x era limitato a 64 caratteri. - Cody Grey giu 19 alla 04:11"

+0

Dove hai trovato caratteri a 32 bit? Ne voglio anche un po '! – configurator

+0

Non penso che esistano, a rigor di termini, ma UTF-32 li usa come praticità, anche se richiede solo circa 24 bit per carattere. :) È strano, tuttavia, ho il sospetto che Windows usi UTF-16, quindi è curioso il motivo per cui lo hanno limitato a 64 caratteri. Forse stanno permettendo surrogati? – Arafangion

+1

Vorrei semplicemente sospettare che questo è un limite tipico di cazzate. Qualcuno alla MS ha inventato 64 caratteri ed è così. Nessuna scienza missilistica coinvolta, o semplicemente non ci sarebbe un limite come questo. – ypnos

8

Dalla documentazione MSDN sulla Win32 NOTIFYICONDATA structure:

szTip

Una stringa alla terminazione Null che specifica il testo per uno standard Suggerimento: può contenere un massimo di 64 caratteri , compreso il carattere di terminazione .

Per Windows 2000 (Shell32.dll versione 5.0) e versioni successive, szTip può avere un massimo di 128 caratteri, incluso il carattere null terminante.

Sembra che la libreria Windows Form supporti qui il minimo comune denominatore.

1

Espansione sulla risposta corretta di bk1e.

Sotto il cofano, un'icona nella barra delle applicazioni in WinForms è implementata come un'icona di notifica Win32. Pertanto la versione winforms ha tutte le limitazioni come quella nativa. La limitazione della dimensione del tooltip è solo un esempio.

1

Recentemente ho riscontrato un problema simile. Piuttosto che hackerare il back-end, ho implementato un work-around, che utilizza BalloonTipText, che può ospitare un bel po 'di personaggi.

La descrizione comando viene visualizzata sul primo evento MouseMove sopra l'icona del vassoio e il suggerimento viene visualizzato per 2 secondi. Dopo che il suggerimento è stato chiuso, può essere riaperto nuovamente da un nuovo evento MouseMove.

L'unico svantaggio di questa soluzione è che non è possibile chiudere il palloncino in modo programmatico, quando un utente, ad esempio, lascia l'area dell'icona, quindi scompare solo dopo un timeout o se l'utente fa clic sul piccolo X- pulsante.

Si noti che il titolo e il testo possono essere impostati in qualsiasi momento altrove nel programma. Sono ambientati qui nell'evento a solo scopo dimostrativo.

EDIT:ShowBalloonTip() incendi Oltre a cascata MouseMove eventi, quindi è necessario disattivare questo evento fino al momento in cui il suggerimento palloncino è nascosto. Inoltre, BalloonTipClosed è (secondo the documentation) attivato solo quando l'utente fa clic attivamente su "X", anche se ho notato che è stato attivato quando il suggerimento è stato chiuso dopo un timeout. Ho quindi aggiunto un timer di supporto per ripristinare lo stato, invece di fare affidamento sull'evento BalloonTipClosed. Il codice rivisto e testato è qui sotto:

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: Uno screenshot di un suggerimento palloncino con un bel po 'di testo, che utilizza questa soluzione può essere seen in by blog.

Problemi correlati