Bug im Tray-Kontextmenü

Veröffentlicht: 09. Okt 2003 | Aktualisiert: 27. Jun 2004
Von Mathias Schiffer

Dieser MSDN Quickie zeigt ein unangenehmes Problem im Zusammenhang mit der Anzeige von Icons im Systemtray. Es trifft auf, wenn Sie das Visual Studio .NET-eigene NotifyIcon-Control in Verbindung mit dem ContextMenu-Control verwenden und hierbei selbstgezeichnete Menüs verwenden wollen.

Wenn Sie die OwnerDraw-Eigenschaft von Menüelementen im Kontextmenü zu True gesetzt haben und die
ContextMenu- und Icon-Eigenschaften eines NotifyIcon-Controls setzen, werden die Menüelemente zur Laufzeit nicht angezeigt, obwohl Sie mit der rechten Maustaste auf das Icon im Systemtray klicken.

Der Grund für dieses unkorrekte Verhalten liegt darin, dass das NotifyIcon-Control die Fensternachrichten WM_DRAWITEM und WM_MEASUREITEM empfängt, jedoch zugehörige DrawItem- und MeasureItem-Eventhandler für MenuItem-Controls nicht nutzt. Daher werden die Menüelemente nicht bzw. als leer angezeigt, obwohl Sie mit der rechten Maustaste auf das Icon im Systemtray klicken.

Sie können diesen Bug folgendermaßen reproduzieren:

Erstellen Sie ein neues Windows Forms Projekt in Visual Basic .NET. Fügen Sie der standardmäßig erstellten Form1 das Steuerelement ContextMenu hinzu. Fügen Sie dann dem Codemodul der Form den folgenden Code hinzu:

  Private Sub Form1_Load(ByVal sender As System.Object, _ 
 ByVal e As System.EventArgs) _ 
 Handles MyBase.Load 
 Me.ContextMenu1.MenuItems.Add(New MenuItem("Einfügen")) 
 Me.ContextMenu1.MenuItems.Add(New MenuItem("Kopieren")) 
 Dim item As MenuItem 
 For Each item In ContextMenu1.MenuItems 
   item.OwnerDraw = True 
   AddHandler item.DrawItem, New DrawItemEventHandler( _ 
  AddressOf DrawCurrentItem) 
   AddHandler item.MeasureItem, New MeasureItemEventHandler( _ 
  AddressOf MeasureCurrentItem) 
 Next 
  End Sub 
  Private Sub DrawCurrentItem(ByVal sender As Object, _ 
  ByVal e As System.Windows.Forms.DrawItemEventArgs) 
 Dim ItemFont As Font = New Font(FontFamily.GenericSansSerif, _ 
   11, FontStyle.Underline, _ 
   GraphicsUnit.Pixel) 
  e.Graphics.DrawString(Me.ContextMenu1.MenuItems(e.Index).Text, _ 
 ItemFont, System.Drawing.Brushes.Blue, _ 
 e.Bounds.X, e.Bounds.Y) 
  End Sub 
  Private Sub MeasureCurrentItem(ByVal sender As Object, _ 
 ByVal e As System.Windows.Forms.MeasureItemEventArgs) 
 e.ItemHeight = 25 
 e.ItemWidth = 100 
  End Sub

Nun fügen Sie der Form noch ein NotifyIcon-Control hinzu und wählen in dessen Eigenschaftenfenster das ContextMenu1 als zugehöriges Kontextmenü sowie ein beliebiges Icon zur Anzeige im Systemtray. Starten Sie die Anwendung, so werden Sie das Problem bemerken, sobald Sie mit der rechten Maustaste auf das Icon im Systemtray klicken.

Ändern Sie hingegen im Ereignis Form1_Load die OwnerDraw-Anweisung in der Schleife ("item.OwnerDraw = False"), so erscheint das Kontextmenü wie erwartet - jedoch ohne die erweiterten Möglichkeiten eines benutzerdefiniert gezeichneten Menüs.


Anzeigen: