为什么我的所有者绘制的组合框显示为空?
我正在对 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
要绘制组合框控件,您应该在 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 theCB_
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.
在 DrawItem 上,您用某种颜色填充矩形。但是 DrawText 或者类似的东西在哪里呢?
自定义 DrawItem 示例。
On DrawItem you filling a rect with some color. But where is DrawText or something like it?
Example of custom DrawItem.
要绘制组合框控件(而不是列表),您还应该处理
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.