Draw themed combobox on windows

2019-07-08 11:10发布

问题:

I try to emulate the look of a themed noneditable combobox (CBS_DROPDOWNLIST) using DrawThemeBackground. I supply the part CP_READONLY, which apparently draws the background of a themed combobox:

DrawThemeBackground(theme, dc, CP_READONLY, CBRO_NORMAL, &rectangle, nullptr);

However, it does not contain the dropdown arrow. So, I tried to paint the arrow myself the following way:

rectangle.left = rectangle.right - 20;
DrawThemeBackground(theme, dc, CP_DROPDOWNBUTTONRIGHT, CBXSR_NORMAL, &rectangle, nullptr);

But the above draws the arrow centered within the rectangle on a combobox background including the border, so I cannot use this without having a border within the combobox (which itself already has a border). I used theme-explorer to verify that the arrow is always on a background with borders.

In essence, my question is: How can I draw the background and the arrow at the appropriate position to emulate the look of a plain windows combobox?

What I have found out so far:

  • I can specify a clipping rectangle to clip away the aforementioned borders. But this poses the question of determining the exact position rectangle and the clipping rectangle: It seems that I can use GetThemeMargins to determine the margins, but that does not tell me how large the arrow is as a whole.

  • GetThemeBitmap might be useful in determining the exact size of the arrow, but as I read here and confirmed on my machine, using it with TMT_GLYPHDIBDATA does not work as advertised, and I would like to go without any workarounds, if possible.