TreeView-Items ohne bzw. fixen Checkboxen
Das TreeView-Control der Windows Common Controls bietet unter Anderem die Möglichkeit, vor jedem Eintrag Kontrollkästchen (Checkboxen) zu platzieren, die mit Tastatur und Maus beliebig ein- und ausgeschaltet werden können.
Hierzu muss einfach der Style TVS_CHECKBOXES
gesetzt werden.
Als Checkboxen-Bildchen werden sogenannte StateImages verwendet.
Leider bietet Windows keinen Einfluss auf die Automatik, die hinter dem Toggeln der Checkbox liegt.
Eine Funktion wie TVN_SELCHANGING
nur für das Ändern des Kontrollkästchen-Status wurde also scheinbar vergessen. Das ist insbesondere dann ärgerlich, wenn man einen User daran hintern möchte, den Status einer Checkbox zu ändern oder wenn man einfach nur eine Notification erhalten möchte, wenn der User den Status einer Checkbox ändert.
Es bleibt einem daher nichts anderes übrig, als die selben Nachrichten, die von der Window-Routine zum Ändern des Checkbox-Status herangezogen werden, in einer Subclassing-Procedure entsprechend zu filtern.
Bevor wir uns nun näher ansehen, wie das Ganze funktioniert, sei noch der Geheimnis gelüftet, wie man für einen einzelnen Eintrag kein Kontrollkästchen anzeigt: Hierzu nimmt man den Index 3 mittels des Makros INDEXTOSTATEIMAGEMASK
für den state
-Parameter des Treeview-Items. Benutzt man diesen Parameter, hat man aber das Problem, dass Windows den Status der Checkbox beim nächsten Klick auf die Stelle, wo sich das Kontrollkästchen befinden sollte, oder beim Drücken der Leertaste, munter weiter toggelt und das Kontrollkästchen so wieder von selbst erscheint. Mit dem hier gezeigten Lösungsansatz kann dieses Problem gelöst werden:
Grundsätzlich wird einfach eine Subclassing-Procedure für das TreeView installiert, welche Tastendrücke (WM_KEYDOWN
) auf die Leertaste (VK_SPACE
) und Mausklicks mit der linken Maustaste (WM_LBUTTONDOWN
) filtert. Eben jene Nachrichten also, die zum Toggeln der Checkboxen verwendet werden. Beim Mausklick muss natürlich noch zusätzlich überprüft werden, ob die Koordinaten des Mauscursors auf ein StateItem zeigen (TVHT_ONITEMSTATEICON
) und ob das Item zum aktuell gewählten Item gehört.
Sind diese Bedingungen erfüllt, so wird geprüft, ob es sich um ein leeres Item handelt (der Index in die Stateimagemask also 3 ist). Ist dies der Fall, so erfolgt keien weitere Behandlung der Nachricht durch die originale Windowprocedure und damit kein Toggeln des Status.
Prinzipiell ist das Ganze also relativ einfach. Das Beispiel sollte auch leicht modifizierbar sein, sodass eine entsprechende Notification gesendet wird, wenn sich der Status einer Checkbox ändert o.ä.
Für Fragen und Anregungen gilt natürlich wie immer: Einfach einen Kommentar hinterlassen.
Das komplette Codefragment mit der Realisierung des Ganzen gibt es hier