Почему мой нарисованный владельцем комбобокс отображается пустым? - PullRequest
4 голосов
/ 02 ноября 2009

Я создаю подкласс в поле со списком WTL, и я рисую его элементы. Элемент управления имеет атрибуты CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_OWNERDRAWVARIABLE, и я использую смешанный класс COwnerDraw для реализации DrawItem () и MeasureItem (). Когда раскрывающийся список недоступен, элементы отображаются правильно. Однако когда выпадающий список открыт, элемент управления в выпадающем списке пуст и элемент не отрисован. Что я делаю не так?

Класс WTL выглядит следующим образом:

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

Класс используется в диалоге и подклассами выглядит так:

   m_cbMy.SubclassWindow(GetDlgItem(IDC_COMBO1));
   m_cbMy.AddString(_T("Item 1"));
   m_cbMy.AddString(_T("Item 2"));

Изменение атрибутов управления на CBS_OWNERDRAWFIXED ничего не меняет.


Edit: Благодаря помощи Najmeddine я понял, что мне нужно обработать WM_PAINT, чтобы нарисовать настоящий комбинированный список, а не только элементы в раскрывающемся списке. К сожалению, теперь я также должен нарисовать элемент управления со списком. Есть ли способ позволить GDI нарисовать границу и опустить стрелку, чтобы мне нужно было только нарисовать "внутренности" элемента управления?

Ответы [ 3 ]

6 голосов
/ 13 ноября 2009

Чтобы нарисовать элемент управления со списком, вы должны использовать API тем в вашем обработчике WM_PAINT (в XP + - вы не говорите, какие версии Windows вам нужно поддерживать). В частности, используйте DrawThemeBackground, и передать одно из значений CB_ для iPartId .

Вам также понадобится использовать API буферизованной краски для обработки переходов в Vista, что может усложнить ваш обработчик рисования - эта и другие проблемы с рисованием, когда пользовательская роспись элемента управления в выпадающем списке * объясняется здесь в значительном количестве деталей. Я бы предложил использовать эту ветку форума в качестве основной ссылки для реализации этого.

0 голосов
/ 10 ноября 2009

Чтобы нарисовать элемент управления comboBox (не список), вы также должны обработать сообщение WM_PAINT и сделать там рисование. событие DrawItem рисует только выпадающий список и его элементы.

0 голосов
/ 09 ноября 2009

На DrawItem вы заполняете прямоугольник некоторым цветом. Но где же DrawText или что-то в этом роде?

Пример пользовательского DrawItem .

...