Komfortabler Dateimanager mit vielen Funktionen

Probleme mit Kontextmenü-Erweiterungen

By Sven on 16.03.2009 - 10:00 in SpeedCommander 12

Es ist ja kein Geheimnis, dass es ab und zu mal Probleme mit Kontextmenü-Erweiterungen. Vor mehr als zwei Jahren habe ich über ein Problem mit der Erweiterung des Nero-Covereditors berichtet. Ihr werdet es nicht glauben, aber es gibt immer noch Anwender, die genau diese fehlerhafte Version noch heute einsetzen.

Derzeit bereiten mir aber zwei andere Kontextmenü-Erweiterungen Probleme. Genaugenommen geht es um den Freeware-Zipper jZip und um das Vergleichsprogramm SourceGear DiffMerge. Bei beiden ist es so, dass sie ein eigenes Untermenü in das Kontextmenü einfügen und SpeedCommander bei Anwahl dieses Menüs in Ehrfurcht erstarrt und den Prozessor schwitzen lässt. Lässt man SpeedCommander im Debugger laufen, dann wirft die MFC nur so mit ASSERTs um sich. Für die Nichtentwickler unter euch: Ein ASSERT ist eine Prüfung zur Laufzeit, die auf unerwartete Zustände hinweist (z.B. ungültige Funktionsparameter). Die Prüfungen werden aber nur in der Debug-Version ausgeführt, die Release-Version enthält keine ASSERTs.

In diesem Fall treten die ASSERTs bei der Verarbeitung der WM_INITMENUPOPUP-Nachricht auf. Windows verschickt diese Nachricht, wenn ein Menü oder Untermenü angezeigt werden soll. Die MFC nutzt diese Gelegenheit, um den Status von Menüelementen zu aktualisieren. Soll z.B. ein bestimmter Menübefehl als gewählte Option angezeigt werden, so lässt sich das hier bequem erledigen. Häufig wird die WM_INITMENUPOPUP-Nachricht auch verwendet, um Menüs vor der Anzeige mit aktuellen Daten zu füllen. SpeedCommander nutzt dies u.a. für die Zusammenstellung der Ordnerfavoriten, die bei jeder Anzeige aktuell in das jeweilige Menü eingetragen werden müssen.

Eigentlich sollte man davon ausgehen können, dass das bei WM_INITMENUPOPUP im ersten Parameter mitgelieferte Menühandle auch gültig ist. Die MFC geht jedenfalls davon aus, eventuelle Probleme werden dem Programmierer durch ASSERTs gemeldet. Ich wüsste auch nicht, was dagegensprechen sollte. In 17 Jahren Windows-Programmierung kam mir noch nie eine WM_INITMENUPOPUP für ein ungültiges Menü unter. Die MFC fragt in ihrer Routine nun die Anzahl der Menüeinträge ab und durchläuft diese nacheinander, um der Anwendung die Möglichkeit zu geben, den Status der Einträge gegebenenfalls anzupassen.

Dummerweise rechnet die MFC nicht damit, dass GetMenuItemCount bei einem ungültigen Menühandle den Wert -1 zurückgeben kann. Das MFC-eigene Menüobjekt CMenu::GetMenuItemCount hat deshalb wohl auch als Rückgabewert einen UINT, was für ganzzahlige Werte von 0 bis 4294967295 steht. Und was passiert, wenn man in einer Schleife 4294967295 Menüeinträge durchlaufen möchte? Richtig, der Prozessor kommt ins Schwitzen und die Anwendung hängt erst einmal.

Aber wie kommt es zu einem ungültigen Menühandle? Ich vermute, dass beide Erweiterungen bei der Zusammenstellung des Kontextmenüs einen neuen Menüeintrag mit AppendMenu einfügen. Die Flags für den neuen Eintrag werden auf MF_POPUP gesetzt, was für ein neues Untermenü steht. Soweit ist das auch in Ordnung. Allerdings sollte dann der Parameter uIDNewItem auch das Handle eines mit CreatePopupMenu erstellten Menüs enthalten und nicht einen Zeiger auf eine private Datenstruktur.

Dass es keine normalen Windows-Menüs sind, sieht man im folgenden Screenshot:

Kontextmenü für DiffMerge

Meine Abneigung für Kontextmenü-Erweiterungen mit eigenen Symbolen zur besseren Erkennbarkeit wird übrigens auch durch solche Verunstaltungen nicht gerade kleiner:

Kontextmenü für jZip

Schon krass, wie ein einzelner Eintrag das ganze Kontextmenü versauen kann.

Es gibt 3 Kommentare zu diesem Beitrag

Trackback URL | RSS-Feed für Kommentare

  1. Thomas sagt:

    Da fragt man sich wieder, wie es denn der Explorer macht…

  2. Sven sagt:

    Das ist nicht so schwer zu beantworten. Den Explorer (wie auch andere Anwendungen) wertet diese Nachricht nicht aus und damit geht auch nichts in die Hose.

  3. hanni sagt:

    winmerge ist doch viel netter und jzip höre ich heute das 1. mal. die macke mit svn hatte ich auch mal. auch wenn du keine icons magst finde ich wenn das richtig gemacht wird eigentlich ok. liegt doch am programmierer wenn er es versaut oder nicht?

Top