Sdílet prostřednictvím


Použití vizuálních stylů s vlastními a Owner-Drawn ovládacími prvky

Toto téma popisuje, jak pomocí rozhraní API vizuálních stylů použít styly vizuálů na vlastní ovládací prvky nebo ovládací prvky nakreslené vlastníkem.

Kreslení ovládacích prvků pomocí vizuálních stylů

Vizuální styly jsou podporovány ve verzi ComCtrl32.dll 6 a novější. Pokud je vaše aplikace nakonfigurovaná tak, aby používala ComCtrl32.dll verze 6 a novější a pokud je tato verze dostupná v systému, použijí se aktuální vizuální styly automaticky na všechny běžné ovládací prvky ve vaší aplikaci. Aktuální styly vizuálů se ale automaticky nepoužívají u vlastních ovládacích prvků nebo ovládacích prvků nakreslených vlastníkem. Aplikace musí obsahovat kód, který kontroluje, jestli jsou dostupné styly vizuálů, a pokud ano, použije rozhraní API vizuálních stylů k použití aktuálně vybraných vizuálních stylů na vlastní ovládací prvky a ovládací prvky nakreslené vlastníkem.

Pokud chcete zkontrolovat, jestli jsou dostupné vizuální styly, zavolejte funkci IsAppThemed. Pokud styly vizuálů nejsou k dispozici, nakreslete ovládací prvek pomocí náhradního kódu.

Pokud jsou dostupné vizuální styly, můžete k vykreslení ovládacího prvku použít funkce vizuálních stylů, jako je DrawTheme Text. Všimněte si, že DrawThemeTextEx umožňuje přizpůsobit vzhled textu, zachovat některé vlastnosti písma motivu při úpravě jiných.

Kreslení ovládacího prvku v aktuálním vizuálním stylu

  1. Volání OpenThemeData, předání hwnd ovládacího prvku, u kterého chcete použít vizuální styly, a seznam tříd popisující typ ovládacího prvku. Třídy jsou definovány ve Vssym32.h. OpenThemeData vrátí popisovač HTHEME, ale pokud je správce vizuálních stylů zakázán nebo aktuální vizuální styl neposkytuje konkrétní informace pro daný ovládací prvek, vrátí funkce NULL. Pokud je návratová hodnota NULL, použijte funkce kreslení bez použití vizuálních stylů.
  2. Chcete-li nakreslit pozadí ovládacího prvku, zavolejte DrawThemeBackground nebo DrawThemeBackgroundEx.
  3. Chcete-li určit umístění obdélníku obsahu, zavolejte GetThemeBackgroundContentRect.
  4. Chcete-li vykreslit text, použijte buď DrawThemeText nebo DrawThemeTextExse souřadnicemi založenými na obdélníku vráceném GetThemeBackgroundContentRect. Tyto funkce můžou vykreslit text v písmu motivu pro zadanou část a stav ovládacího prvku nebo v písmu, které je aktuálně vybrané v kontextu zařízení (DC).
  5. Když váš ovládací prvek obdrží zprávu WM_DESTROY, zavolejte CloseThemeData k uvolnění popisovače motivu, který byl vrácen při volání OpenThemeData.

Následující příklad kódu ukazuje jeden způsob, jak nakreslit ovládací prvek tlačítka v aktuálním vizuálním stylu.

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

Následující příklad kódu je v obslužné rutině WM_PAINT zprávy pro ovládací prvek podtříděného tlačítka. Text ovládacího prvku se vykresluje písmem vizuálních stylů, ale barva je určena aplikací podle stavu ovládacího prvku.

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

Můžete použít části z jiných ovládacích prvků a vykreslit jednotlivé části samostatně. Například u ovládacího prvku kalendáře, který se skládá z mřížky, můžete ke každému čtverci vytvořenému mřížkou přistupovat jako k tlačítku panelu nástrojů, a to získáním úchytu motivu následujícím způsobem:

OpenThemeData(hwnd, L"Toolbar");

Můžete kombinovat a sladit ovládací části voláním OpenThemeData vícekrát pro daný ovládací prvek a pomocí příslušného identifikátoru motivu nakreslit různé části. V některých vizuálních stylech ale některé části nemusí být kompatibilní s jinými částmi.

Dalším přístupem k vykreslování ovládacích prvků v aktivním vizuálním stylu je použití systémových barev. Systémové barvy můžete například použít k nastavení barvy textu při volání DrawThemeTextEx funkce. Většina systémových barev se nastavuje při použití souboru vizuálního stylu.

Reagování na změny motivu

Když váš ovládací prvek obdrží zprávu WM_THEMECHANGED a drží globální popisovač motivu, měl by udělat toto:

  • Voláním CloseThemeData zavřete existující popisovač motivu.
  • Volání OpenThemeData k získání popisovače motivu do nově načteného vizuálního stylu.

Následující příklad znázorňuje dvě volání.

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

povolení vizuálních stylů

Vizuální styly