3

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?

Asesh
  • 3,186
  • 2
  • 21
  • 31
peterchen
  • 40,917
  • 20
  • 104
  • 186
  • Have you tried [Create an Owner-Drawn Combo Box](https://learn.microsoft.com/en-us/windows/win32/controls/create-an-owner-drawn-combo-box)? – Drake Wu Dec 17 '20 at 03:33

2 Answers2

1

Have you tried replacing CP_DROPDOWNBUTTON by CP_DROPDOWNBUTTONRIGHT ?

bruno
  • 32,421
  • 7
  • 25
  • 37
  • CP_DROPDOWNBUTTONRIGHT has the right aligment, but oesn't have the CP_READONLY style of a drop down lsit. – peterchen Dec 06 '20 at 00:01
  • CP_DROPDOWNBUTTON does not include CP_READONLY if I can say, so if CP_DROPDOWNBUTTON has the CP_READONLY style this is because this is specified else where (the theme ?), just do the same for CP_DROPDOWNBUTTONRIGHT – bruno Dec 06 '20 at 08:29
  • "Do the same for CP_DROPDOWNBUTTONRIGHT" - this includes a border, and thus gives the second image, looking like a split button – peterchen Dec 15 '20 at 23:34
0

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);
Tjark
  • 11
  • 1