4

我正在继承 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不会更改任何内容。


编辑:感谢 najmeddine 的帮助,我发现我必须处理 WM_PAINT 才能绘制实际的组合框,而不仅仅是下拉列表中的项目。不幸的是,现在我还必须自己绘制组合框控件。有没有办法让 GDI 绘制边框和下拉箭头,这样我只需要绘制控件的“内部”?

4

3 回答 3

6

要绘制组合框控件,您应该在 WM_PAINT 处理程序中使用主题 API(在 XP+ 中 - 您没有说明需要支持哪些 Windows 版本。)具体来说,使用DrawThemeBackground并传入CB_iPartId 的值之一

您还需要使用缓冲的绘制 API来处理 Vista 上的转换,这可能会使您的绘制处理程序复杂化 - 自定义绘制组合框控件时的这个和其他绘制问题在此处进行了相当详细的解释。我建议使用该论坛主题作为实现此功能的主要参考。

于 2009-11-13T00:54:52.057 回答
0

在 DrawItem 上,你用一些颜色填充一个矩形。但是 DrawText 或类似的东西在哪里?

自定义 DrawItem 的示例

于 2009-11-09T11:52:29.127 回答
0

要绘制组合框控件(而不是列表),您还应该处理WM_PAINT消息并在那里进行绘制。
DrawItem事件仅绘制下拉列表及其项目。

于 2009-11-10T11:32:47.210 回答