我想更新一些类似工具栏的代码,我们必须有一个vista/win7渐变圆到他们。
目前,这些按钮具有Windows2000的外观:块状、单色。
我玩过xp的主题,使用drawthemebackground、drawthemeedge等;但我对主题绘制机制非常不满(按钮很大,主题将它们绘制为2色调、上半部分和下半部分,当按钮很小的时候看起来没问题——它给了他们一个半正派的渐变或者圆形的外观。但这些钮扣虽然大,但看起来很蠢。
通过简单地观察在各种应用程序和控件中绘制了多少控件,我可以看到它们中的大多数似乎都使用渐变-控件顶部显示为浅色,底部淡入较深的颜色-或者-颜色比背景浅在顶部,在中间增加到接近白色,然后在底部变回较暗的颜色。
我真的不知道从这里到哪里去。drawthemexx似乎不够。我真的不想用一个改进了绘图的新控件替换整个控件,但需要我交换一些代码来了解当前自定义控件的工作方式,并冒着与其他库发生各种问题的风险。
我宁愿有一个方法来绘制任意对象的风格,当前版本的窗口,我正在运行。
我本以为主题绘制功能会涵盖这一点。但正如我所描述的,他们的大脑相当受损。
有人能指点我吗?
“现代C++应用程序应该如何绘制自定义GUI元素,以便他们能够合理地期望在XP、Vista和Windows 7下有一个优雅的外观?”
目前,我们在代码中使用mfc、gdiplus和原始win32api。
这是希望有人知道很多关于在Windows下绘制现代GUI的C++!
为了使这不是一堵文字墙,下面是当前版本的绘制处理程序,它在“热跟踪”时绘制带有蚀刻边框的按钮,在按下状态下同时绘制蚀刻边框和图标+文字“按下”(移动1,1):
void CPlacesButton::PaintButton(CDC & dc, CRect & rcClient)
{
const int kLabelHeight = 8;
COLORREF clrHiLt = GetSysColor(COLOR_BTNHIGHLIGHT);
COLORREF clrShdo = GetSysColor(COLOR_BTNSHADOW);
COLORREF clrText = GetSysColor(COLOR_BTNTEXT);
COLORREF clrFace = GetSysColor(COLOR_BTNFACE);
// draw the button's background & border
if (m_bPressed || m_bDrawPressed || m_bMouseOnButton)
{
COLORREF clrDarkened = Darken(clrFace, -0.01f);
dc.FillRect(rcClient, &CBrush(clrDarkened));
//dc.Draw3dRect(rcClient, clrShdo, clrHiLt);
//dc.RoundRect(&rcClient, CPoint(10,10));
dc.DrawEdge(&rcClient, EDGE_ETCHED, BF_RECT|BF_FLAT);
//dc.DrawFrameControl(&rcClient, DFC_BUTTON, DFCS_BUTTONPUSH|DFCS_PUSHED);
}
// else if (m_bMouseOnButton) // hot draw
// //dc.Draw3dRect(rcClient, clrShdo, clrHiLt);
// dc.DrawEdge(&rcClient, EDGE_ETCHED, BF_RECT);
// //dc.RoundRect(&rcClient, CPoint(10,10));
else
dc.FillRect(rcClient, &CBrush(clrFace));
// use transparent mode for everything that follows
dc.SetBkMode(TRANSPARENT);
// center icon
CPoint ptIcon((rcClient.Width() - m_nIconSize) / 2, ((rcClient.Height() - m_nIconSize) / 2) - kLabelHeight);
if (m_bPressed || m_bDrawPressed)
ptIcon.Offset(1, 1);
// determine the state to draw ourselves in
const UINT nState = DST_ICON | (IsEnabled() ? DSS_NORMAL : DSS_DISABLED);
// draw our icon
dc.DrawState(ptIcon, CSize(m_nIconSize, m_nIconSize), m_hIcon, nState, (HBRUSH)NULL);
// create & select the font to use for the button's label
CFont guiFont;
VERIFY(guiFont.CreateStockObject(DEFAULT_GUI_FONT));
AutoSelectGDIObject select_font(dc, guiFont);
// determine clipping rect for label
CRect rcText(0, ptIcon.y+m_nIconSize+kLabelHeight, rcClient.Width(), ptIcon.y+m_nIconSize+kLabelHeight);
rcText.InflateRect(0,20);
if (m_bPressed || m_bDrawPressed)
rcText.OffsetRect(1, 1);
dc.SetTextColor(clrText);
if (IsEnabled())
dc.DrawText(m_strCaption, rcText, DT_VCENTER|DT_SINGLELINE|DT_CENTER);
else
dc.GrayString(NULL, NULL, (LPARAM)(LPCTSTR)m_strCaption, 0, rcText.TopLeft().x, rcText.TopLeft().y, rcText.Width(), rcText.Height());
}
我在代码中留下了一些注释掉的变体,以暗示我尝试过的其他可能性。不过,它们只是一个提示,因为没有完整的替代示例。