Por que meu combobox desenho proprietário mostrado vazio?
-
11-09-2019 - |
Pergunta
Estou subclassificação um combobox WTL e eu sou dono desenho os itens da caixa de combinação. O controle tem o CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_OWNERDRAWVARIABLE
atributos e eu estou usando o mix-in class COwnerDraw para implementar DrawItem () e MeasureItem (). Quando a lista drop-down é baixo, os itens são desenhados corretamente. No entanto, quando a lista drop-down é para cima, o controle combobox está vazio e o item não é desenhado. O que estou fazendo de errado?
Os olhares classe WTL como este:
class CMyComboBox :
public CWindowImpl<CMyComboBox, CComboBox>,
public COwnerDraw<CMyComboBox>
{
public:
BEGIN_MSG_MAP_EX(CMyComboBox)
CHAIN_MSG_MAP(COwnerDraw<CMyComboBox>)
CHAIN_MSG_MAP_ALT(COwnerDraw<CMyComboBox>, 1)
END_MSG_MAP()
void DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
CDCHandle dc = lpDIS->hDC;
dc.FillSolidRect(&lpDIS->rcItem, lpDIS->itemID == 0 ?
RGB(255,0,0) : RGB(0,255,0));
}
void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
lpMeasureItemStruct->itemWidth = 12;
lpMeasureItemStruct->itemHeight = 12;
}
};
A classe é usada em uma caixa de diálogo e é uma subclasse como esta:
m_cbMy.SubclassWindow(GetDlgItem(IDC_COMBO1));
m_cbMy.AddString(_T("Item 1"));
m_cbMy.AddString(_T("Item 2"));
A alteração do controle atribui a CBS_OWNERDRAWFIXED
não muda nada.
Edit: Graças à ajuda de najmeddine eu descobri que eu tenho que lidar com WM_PAINT para desenhar o combobox real, e não apenas os itens na lista drop-down. Infelizmente agora eu tenho que também desenhar o controle combobox sozinho. Existe uma maneira de deixar o GDI desenhar a borda e soltar seta para que eu só tenho que desenhar as "entranhas" do controle?
Solução
Para desenhar o controle combobox você deve usar as APIs temáticos no seu manipulador WM_PAINT - Especificamente, o uso DrawThemeBackground
, e passar em um dos valores CB_
para iPartId .
Você também vai precisar usar os tamponados pintar APIs para lidar com transições no Vista, o que pode complicar seu manipulador de pintura - este e outros problemas de desenho quando costume pintar um controle combobox são explicado aqui em uma boa quantidade de detalhes. Eu sugiro usar esse segmento fórum como sua referência principal implementar isso.
Outras dicas
Em DrawItem você encher um rect com alguma cor. Mas onde está DrawText ou algo parecido?
Para desenhar o controle ComboBox (não a lista), você também deve lidar com a mensagem WM_PAINT
e fazer a sua pintura lá.
o evento DrawItem
pinta apenas a lista drop e é itens.