UXTheme: Draw Combobox Chevron Without Border

288 Views Asked by At

I'm trying to draw a custom control that should use the "combobox" theme class.

Using

m_hTheme = OpenThemeData(m_hWnd, _T("COMBOBOX"));
auto stateBG = ...; // depends on window state
DrawThemeBackground(m_hTheme, ps.hdc, CP_READONLY, stateBG, &clientRect, nullptr);

gives the correct background (read-only-look) without the chevron. But how do I add the chevron?

auto stateCV = ...; // depends on window state
DrawThemeBackground(m_hTheme, ps.hdc, CP_DROPDOWNBUTTON, stateCV, &rect, nullptr);

draws the chevron correctly, but with its own border and the chevron centered within the rect. So if I use the full client rect, I get this:

combobox centered chevron

If I use a smaller rect so that the chevron is positioned correctly, I get a separated dropdown:

combobox boxed chevron

How do I get the "normal" look? - i.e like this:

enter image description here


Bonus Questions:

Is there any documentation that does a better job than MSDN? It's as sparse as most newer documentation, e.g. just listing "Parts and States", without describing their purpose (which is not always obvious), and whether it's DrawThemeBackground or ~Edgefor a particular item.

Do I still use the good old DrawFocusRectfor the focus rect?

GetThemeBackgroundContentRect calculates the expected rectable for iPartId=CP_READONLY, but for iPartId=CP_CUEBANNER, it returns the full client rectangle, so the cue text is badly aligned. Is this... normal?

2

There are 2 best solutions below

3
On

Have you tried replacing CP_DROPDOWNBUTTON by CP_DROPDOWNBUTTONRIGHT ?

0
On

As a workaround you could use the ClipRect of DrawThemeBackground to cut off the left edge of the drop down button.

CRect clip_rect = rect;
clip_rect.DeflateRect(1, 0, 0, 0);
auto stateCV = ...; // depends on window state
DrawThemeBackground(m_hTheme, ps.hdc, CP_DROPDOWNBUTTON, stateCV, &rect, &clip_rect);