Combobox MFC:如何为所有者绘制渲染Aero样式组合框?

Combobox MFC:如何为所有者绘制渲染Aero样式组合框?,combobox,mfc,aero,onpaint,ownerdrawn,Combobox,Mfc,Aero,Onpaint,Ownerdrawn,我继承了一个大型MFC应用程序,它包含一个覆盖OnPaint的cmbobox子类。目前,它所有的绘图都是手工绘制的(包括线条和矩形),并呈现一个组合框,看起来绝对是Windows98风格的。然而,它在其他方面工作得很好,提供了许多我们依赖的有用的自定义功能,重写整个控件可能不是一个选项 我想将其现代化,以便在可用的情况下,OnPaint以Aero风格绘制(当无法使用现代主题时,返回到旧代码)。我用其他一些自定义控件(如按钮)实现了这一点,它非常适合我们的目的。我知道有一些小的行为,它不会得到正确

我继承了一个大型MFC应用程序,它包含一个覆盖OnPaint的
cmbobox
子类。目前,它所有的绘图都是手工绘制的(包括线条和矩形),并呈现一个组合框,看起来绝对是Windows98风格的。然而,它在其他方面工作得很好,提供了许多我们依赖的有用的自定义功能,重写整个控件可能不是一个选项

我想将其现代化,以便在可用的情况下,
OnPaint
以Aero风格绘制(当无法使用现代主题时,返回到旧代码)。我用其他一些自定义控件(如按钮)实现了这一点,它非常适合我们的目的。我知道有一些小的行为,它不会得到正确的,如鼠标悬停时的温和亮点,但这不是一个大问题,这个应用程序

我可以访问
CVisualStylesXP
ckass,因此我已经有了基础设施,可以很容易地调用
openmotedata
GetThemeColor
DrawThemeBackground
(通过
LoadLibrary
,因此我们不强制Vista作为一个最小系统)。不幸的是,我不知道调用的正确顺序,以获得一个具有适当主题边框和下拉按钮的漂亮组合框


有人知道该怎么做吗?

老实说,我不知道他们最初为什么试图覆盖OnPaint。有充分的理由吗?我认为,至少99%的时候,您只是想覆盖组合框中项目的绘图。为此,可以在派生组合框中重写DrawItem、MeasureItem和CompareItem,以获得所需的功能。在这种情况下,操作系统将正确绘制每个操作系统特定的非用户内容。

我认为您最好不要深入xp主题和各种系统指标,看看这个项目:


检查CAdvComboBox类的OnPaint-有一个完整的控件重新绘制实现,包括xp主题相关问题。

不确定是否是相同的情况-但是当我遇到这个问题时(在我的子类Cbutton中),解决它只需要将控件声明更改为指针并动态创建控件

假设您的子类控件名为ccomboxext。
你在哪里

CComboBoxExt m_cComboBoxExt;
你现在有

CComboBoxExt* m_pcComboBoxExt; 
在放置控件的窗口的OnInitDialog上,使用

m_pcComboBoxExt = new CComboBoxExt();  
m_pcComboBoxExt->Create(...)
因为这现在是一个指针,所以不要忘记调用
destronWindow()
,并在终止时删除指针


这解决了我的特殊问题——如果你的控件以同样的方式被声明,试着尝试一下。

老实说,是的,它基本上看起来像是一个普通的组合框,而不是中间显示的文本。但我真的不想重新构建它。事实上,再仔细想想,它使一个Droplist看起来更像一个下拉列表(它基本上允许用户键入文本的任何子集,然后列表显示过滤结果)。只是画得像一个吊坠是错误的。不幸的是,我已经试过了,它看起来一点也不像航空组合框。在我看来,他们对它进行了黑客攻击,并进行了有根据的猜测,直到视觉效果与XP相符,但对于Aero来说,这是完全错误的。例如,右边的箭头按钮被一个方形按钮包围,这对Luna来说是正确的,但对Aero来说是错误的。哦,我的错。好的,还有一个可能会更复杂一些,从中删除相关代码,但是使用aero风格更好。相关代码在VComboBox.cpp文件中。这不会修复手动绘制线和填充框的我的
OnPaint