为什么我的所有者绘制的组合框显示为空?

发布于 2024-08-09 20:07:27 字数 1306 浏览 9 评论 0原文

我正在对 WTL 组合框进行子类化,并且由所有者绘制组合框的项目。该控件具有属性 CBS_DROPDOWNLIST | CBS_HASSTRINGS | 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 绘制边框和下拉箭头,这样我只需绘制控件的“内部”?

I'm subclassing a WTL combobox and I'm owner-drawing the items of the combobox. The control has the attributes CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_OWNERDRAWVARIABLE and I'm using the mix-in class COwnerDraw to implement DrawItem() and MeasureItem(). When the drop down list is down, the items are drawn correctly. However when the drop down list is up, the combobox control is empty and the item isn't drawn. What am I doing wrong?

The WTL class looks like this:

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

The class is used on a dialog and is subclassed like this:

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

Changing the control attributes to CBS_OWNERDRAWFIXED doesn't change anything.


Edit:
Thanks to the help of najmeddine I figured out that I have to handle WM_PAINT to draw the actual combobox, and not only the items in the drop-down list. Unfortunately now I have to also draw the combobox control all by myself. Is there a way to let the GDI draw the border and drop arrow so that I only have to draw the "insides" of the control?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

亽野灬性zι浪 2024-08-16 20:07:27

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

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

To draw the combobox control you should use the theme APIs in your WM_PAINT handler (in XP+ - you don't say what Windows versions you need to support.) Specifically, use DrawThemeBackground, and pass in one of the CB_ values for iPartId.

You will also need to use the buffered paint APIs to handle transitions on Vista, which can complicate your paint handler - this and other drawing problems when custom painting a combobox control are explained here in a fair amount of detail. I'd suggest using that forum thread as your main reference implementing this.

终遇你 2024-08-16 20:07:27

在 DrawItem 上,您用某种颜色填充矩形。但是 DrawText 或者类似的东西在哪里呢?

自定义 DrawItem 示例

On DrawItem you filling a rect with some color. But where is DrawText or something like it?

Example of custom DrawItem.

若能看破又如何 2024-08-16 20:07:27

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

To draw the comboBox control (not the list), you should also handle the WM_PAINT message and do your painting there.
the DrawItem event only paints the drop list and it's items.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文