head.WriteLine()

Dienstag, April 04, 2006

VisualStyles und VisualStylesRenderer, Teil 1

Bei der Entwicklung eigener Owner Drawn Controls benötigt man häufig Standardgrafikelemente, wie Buttons oder die Symbole von Combo- oder Check-Boxen. Hierfür konnte man bisher die Klasse ControlPaint verwenden, wie das folgende Beispiel zeigt:

ControlPaint.DrawButton(
    e.Graphics,
    new Rectangle(10, 10, 50, 30),
    ButtonState.Normal);

Das Problem dieser API ist jedoch, dass die Symbole ohne Berücksichtigung des aktiv eingestellten Windows-Theme gezeichnet werden. Zudem bietet ControlPaint nur eine sehr geringe Anzahl an Standardelementen.

Zur Lösung dieser Probleme wurden in .NET 2.0 die Klassen VisualStyles und VisualStylesRenderer eingeführt. Während Erstere eine Repräsentation der Windows-Standardsymbole bietet, ermöglicht Letztere das Zeichnen der Elemente. Hierbei wird der aktuell eingestellte Windows-Theme berücksichtigt.

VisualStyleElement (zu finden im Namespace System.Windows.Forms.VisualStyles) definiert 24 Unterklassen, die jeweils ein Element darstellen. Jedes dieser Elemente enthält ihrerseits Unterklassen, die den Typ näher spezifizieren. So definiert die Button-Klasse beispielsweise die Untertypen PushButton, CheckBox, RadioButton, GroupBox und UserButton. Jede dieser Klasse definiert wiederum verschiedene Stati in Form von Eigenschaften. Diese Stati repräsentieren den Zustand des zu zeichnenden Elements.
Ein einfacher Button könnte somit wie folgt definiert werden:

VisualStyleElement.Button.PushButton.Normal

Um den so definierten Button nun auf den Bildschirm zu bringen, kann die VisualStylesRenderer-Klasse verwendet werden.

protected override void OnPaint(PaintEventArgs e)
{
    VisualStyleRenderer renderer = new VisualStyleRenderer(
    VisualStyleElement.Button.PushButton.Normal);

    renderer.DrawBackground(
        e.Graphics, new Rectangle(0, 0, 100, 32));
}

VisualStyleRenderer zeichnet jedoch nur Visual Styles im jeweils eingestellten Theme. Wurden die Visual Styles in Windows deaktiviert, verweigert die Klasse seine Dienste. Wie dies ermittelt werden kann, beschreibe ich im 2 Teil dieser kleinen Serie.