Dela via


Använda visuella format med anpassade kontroller och Owner-Drawn kontroller

Det här avsnittet beskriver hur du använder API:et för visuella format för att tillämpa visuella format på anpassade kontroller eller ägarritade kontroller.

Ritningskontroller med visuella format

Visuella format stöds av ComCtrl32.dll version 6 och senare. Om programmet är konfigurerat att använda ComCtrl32.dll version 6 och senare, och om den versionen är tillgänglig i systemet, tillämpas de aktuella visuella formatmallarna automatiskt på alla vanliga kontroller i ditt program. De nuvarande visuella stilarna tillämpas dock inte automatiskt på användardefinierade kontroller eller ägarritade kontroller. Ditt program måste innehålla kod som kontrollerar om visuella format är tillgängliga och i så fall använder API:et för visuella format för att tillämpa de markerade visuella formaten på dina anpassade och ägarritade kontroller.

Om du vill kontrollera om visuella format är tillgängliga anropar du funktionen IsAppThemed. Om visuella format inte är tillgängliga använder du reservkod för att rita kontrollen.

Om visuella format är tillgängliga kan du använda funktioner för visuella format, till exempel DrawThemeText för att återge kontrollen. Observera att DrawThemeTextEx kan du anpassa utseendet på text, behålla vissa egenskaper för temateckensnittet medan du ändrar andra.

Om du vill rita en kontroll i det aktuella visuella formatet

  1. Anropa OpenThemeDataoch skicka hwnd av kontrollen som du vill använda visuella formatmallar på och en klasslista som beskriver kontrollens typ. Klasserna definieras i Vssym32.h. OpenThemeData- returnerar ett HTHEME-handtag, men om hanteraren för visuella format är inaktiverad eller om det aktuella visuella formatet inte innehåller specifik information för en viss kontroll, returnerar funktionen NULL-. Om returvärdet är NULL, använd icke-visuella ritfunktioner.
  2. Om du vill rita kontrollbakgrunden anropar du DrawThemeBackground eller DrawThemeBackgroundEx.
  3. Om du vill fastställa platsen för innehållsrektangeln anropar du GetThemeBackgroundContentRect.
  4. Om du vill återge text använder du antingen DrawThemeText eller DrawThemeTextExoch baserar koordinaterna på den rektangel som returneras av GetThemeBackgroundContentRect. Dessa funktioner kan återge text antingen i temats teckensnitt för en angiven kontrolldel och ett angivet tillstånd, eller i det teckensnitt som för närvarande har valts i enhetskontexten (DC).
  5. När kontrollen tar emot ett WM_DESTROY-meddelande anropar du CloseThemeData för att släppa temahandtaget som returnerades när du anropade OpenThemeData.

Följande exempelkod visar ett sätt att rita en knappkontroll i det aktuella visuella formatet.

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.
    }
}

Följande exempelkod finns i WM_PAINT meddelandehanterare för en underklassad knappkontroll. Texten för kontrollen ritas i teckensnittet för visuella format, men färgen är programdefinierad beroende på kontrollens tillstånd.

// 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.
}

Du kan använda delar från andra kontroller och återge varje del separat. För en kalenderkontroll som består av ett rutnät kan du till exempel behandla varje kvadrat som bildas av rutnätet som en verktygsfältsknapp genom att hämta temahandtaget på följande sätt:

OpenThemeData(hwnd, L"Toolbar");

Du kan blanda och matcha kontrolldelar genom att anropa OpenThemeData flera gånger för en viss kontroll och använda rätt temahandtag för att rita olika delar. I vissa visuella format kanske vissa delar inte är kompatibla med andra delar.

En annan metod för att återge kontroller i det aktiva visuella formatet är att använda systemfärgerna. Du kan till exempel använda systemfärger för att ange textfärgen när du anropar funktionen DrawThemeTextEx. De flesta systemfärger anges när en fil med visuellt format används.

Svara på temaändringar

När kontrollen tar emot ett WM_THEMECHANGED meddelande och håller ett globalt handtag i temat bör den göra följande:

  • Anropa CloseThemeData för att stänga det befintliga temahandtaget.
  • Anropa OpenThemeData för att hämta temahandtaget till det nyss inlästa visuella formatet.

I följande exempel visas de två anropen.

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

Aktiverar visuella stilar

visuella stilar