Verwenden von visuellen Stilen mit benutzerdefinierten und Owner-Drawn Steuerelementen

In diesem Thema wird beschrieben, wie Sie die API für visuelle Stile verwenden, um visuelle Stile auf benutzerdefinierte Steuerelemente oder vom Besitzer gezeichnete Steuerelemente anzuwenden.

Zeichnen von Steuerelementen mit visuellen Stilen

Visuelle Stile werden von ComCtrl32.dll Version 6 und höher unterstützt. Wenn Ihre Anwendung für die Verwendung von ComCtrl32.dll Version 6 und höher konfiguriert ist und diese Version im System verfügbar ist, werden die aktuellen visuellen Stile automatisch auf alle allgemeinen Steuerelemente in Ihrer Anwendung angewendet. Die aktuellen visuellen Stile werden jedoch nicht automatisch auf benutzerdefinierte Steuerelemente oder vom Besitzer gezeichnete Steuerelemente angewendet. Ihre Anwendung muss Code enthalten, der überprüft, ob visuelle Stile verfügbar sind, und verwendet in diesem Beispiel die API für visuelle Stile, um die aktuell ausgewählten visuellen Stile auf Ihre benutzerdefinierten und vom Besitzer gezeichneten Steuerelemente anzuwenden.

Um zu überprüfen, ob visuelle Stile verfügbar sind, rufen Sie die IsAppThemed-Funktion auf. Wenn keine visuellen Stile verfügbar sind, verwenden Sie Fallbackcode, um das Steuerelement zu zeichnen.

Wenn visuelle Stile verfügbar sind, können Sie visuelle Stilfunktionen wie DrawThemeText verwenden, um Das Steuerelement zu rendern. Beachten Sie, dass DrawThemeTextEx es Ihnen ermöglicht, die Darstellung von Text anzupassen, wobei einige Eigenschaften der Designschriftart beibehalten und andere geändert werden.

So zeichnen Sie ein Steuerelement im aktuellen visuellen Stil

  1. Rufen Sie OpenThemeData auf,und übergeben Sie den HWND des Steuerelements, auf das Sie visuelle Stile anwenden möchten, und eine Klassenliste, die den Typ des Steuerelements beschreibt. Die Klassen werden in Vssym32.h definiert. OpenThemeData gibt ein HTHEME-Handle zurück, aber wenn der Visuelle Stil-Manager deaktiviert ist oder der aktuelle visuelle Stil keine spezifischen Informationen für ein bestimmtes Steuerelement liefert, gibt die Funktion NULL zurück. Wenn der Rückgabewert NULL ist, verwenden Sie Zeichnungsfunktionen, die keine visuellen Stile sind.
  2. Um den Hintergrund des Steuerelements zu zeichnen, rufen Sie DrawThemeBackground oder DrawThemeBackgroundEx auf.
  3. Rufen Sie GetThemeBackgroundContentRectauf, um die Position des Inhaltsrechtecks zu bestimmen.
  4. Verwenden Sie zum Rendern von Text entweder DrawThemeText oder DrawThemeTextEx,und verwenden Sie dabei die Koordinaten auf dem Rechteck, das von GetThemeBackgroundContentRect zurückgegeben wird. Diese Funktionen können Text entweder in der Schriftart des Designs für einen angegebenen Steuerelementteil und -zustand oder in der Schriftart rendern, die derzeit im Gerätekontext (DC) ausgewählt ist.
  5. Wenn Ihr Steuerelement eine WM _ DESTROY-Nachricht empfängt, rufen Sie CloseThemeData auf, um das Designhand handle frei zu geben, das zurückgegeben wurde, als Sie OpenThemeData aufgerufen haben.

Der folgende Beispielcode veranschaulicht eine Möglichkeit, ein Schaltflächen-Steuerelement im aktuellen visuellen Stil zu zeichnen.

HTHEME hTheme = NULL;

hTheme = OpenThemeData(hwndButton, L"Button");
// ...
DrawMyControl(hDC, hwndButton, hTheme, iState);
// ...
if (hTheme)
{
    CloseThemeData(hTheme);
}


void DrawMyControl(HDC hDC, HWND hwndButton, HTHEME hTheme, int iState)
{
    RECT rc, rcContent;
    TCHAR szButtonText[255];
    HRESULT hr;
    size_t cch;

    GetWindowRect(hwndButton, &rc);
    GetWindowText(hwndButton, szButtonText,
                  (sizeof(szButtonText) / sizeof(szButtonText[0])+1));
    hr = StringCchLength(szButtonText,
         (sizeof(szButtonText) / sizeof(szButtonText[0])), &cch);
    if (hTheme)
    {
        hr = DrawThemeBackground(hTheme, hDC, BP_PUSHBUTTON, iState, &rc, 0);
        if (SUCCEEDED(hr))
        {
            hr = GetThemeBackgroundContentRect(hTheme, hDC, BP_PUSHBUTTON, 
                    iState, &rc, &rcContent);
        }

        if (SUCCEEDED(hr))
        {
            hr = DrawThemeText(hTheme, hDC, BP_PUSHBUTTON, iState, 
                    szButtonText, cch,
                    DT_CENTER | DT_VCENTER | DT_SINGLELINE,
                    0, &rcContent);
        }

    }
    else
    {
        // Draw the control without using visual styles.
    }
}

Der folgende Beispielcode befindet sich im WM PAINT-Meldungshandler _ für ein Unterklassen-Schaltflächen-Steuerelement. Der Text für das Steuerelement wird in der Schriftart für visuelle Stile gezeichnet, aber die Farbe ist anwendungsdefiniert, abhängig vom Zustand des Steuerelements.

// textColor is a COLORREF whose value has been set according to whether the button is "hot".
// paint is the PAINTSTRUCT whose members are filled in by BeginPaint.
HTHEME theme = OpenThemeData(hWnd, L"button");
if (theme)
{
    DTTOPTS opts = { 0 };
    opts.dwSize = sizeof(opts);
    opts.crText = textColor;
    opts.dwFlags |= DTT_TEXTCOLOR;
    WCHAR caption[255];
    size_t cch;
    GetWindowText(hWnd, caption, 255);
    StringCchLength(caption, 255, &cch);
    DrawThemeTextEx(theme, paint.hdc, BP_PUSHBUTTON, CBS_UNCHECKEDNORMAL, 
        caption, cch, DT_CENTER | DT_VCENTER | DT_SINGLELINE, 
        &paint.rcPaint, &opts);
    CloseThemeData(theme);
}
else
{
    // Draw the control without using visual styles.
}

Sie können Teile aus anderen Steuerelementen verwenden und jeden Teil separat rendern. Für ein Kalendersteuerfeld, das aus einem Raster besteht, können Sie z. B. jedes quadratische, durch das Raster gebildete Quadrat wie eine Symbolleistenschaltfläche behandeln, indem Sie das Designhandle wie folgt abrufen:

OpenThemeData(hwnd, L"Toolbar");

Sie können Steuerelementteile mischen und abwenden, indem Sie OpenThemeData mehrmals für ein bestimmtes Steuerelement aufrufen und das entsprechende Designhandling verwenden, um verschiedene Teile zu zeichnen. In einigen visuellen Stilen sind bestimmte Teile jedoch möglicherweise nicht mit anderen Teilen kompatibel.

Ein weiterer Ansatz zum Rendern von Steuerelementen im aktiven visuellen Stil ist die Verwendung der Systemfarben. Beispielsweise können Sie die Textfarbe mithilfe von Systemfarben festlegen, wenn Sie die DrawThemeTextEx-Funktion aufrufen. Die meisten Systemfarben werden festgelegt, wenn eine visuelle Stildatei angewendet wird.

Reagieren auf Designänderungen

Wenn Ihr Steuerelement eine WM _ THEMECHANGED-Nachricht empfängt und ein globales Handle für das Design enthält, sollte es folgende Schritte unternehmen:

Im folgenden Beispiel werden die beiden Aufrufe veranschaulicht.

case WM_THEMECHANGED:
     CloseThemeData (g_hTheme);
     g_hTheme = OpenThemeData (hwnd, L"MyClassName");

Aktivieren von visuellen Stilen

Visuelle Stile