快速业务通道

用C++品尝Vista美味:界面的毛玻璃效果

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30
),非常易于使用:

bool CMainFrame::IsCompositionEnabled() const
{
 HRESULT hr;
 BOOL bEnabled;
 hr = DwmIsCompositionEnabled(&bEnabled);
 return SUCCEEDED(hr) && bEnabled;
}

现在,让我们再检查一遍OnEraseBkgnd(),看看每个步骤是否都完成了。这个程序是一个时钟程序,所以先用GetTimeFormat()获取当前时间:

BOOL CMainFrame::OnEraseBkgnd(HDC hdc)
{
 CDCHandle dc = hdc;
 CRect rcClient, rcText;
 GetClientRect ( rcClient );
 dc.FillSolidRect ( rcClient, RGB(0,0,0) );
 rcText = rcClient;
 rcText.top = rcText.bottom - 100;
 
 //获取当前时间
 TCHAR szTime[64];
 GetTimeFormat(LOCALE_USER_DEFAULT,0,NULL,NULL,szTime,_countof(szTime));
 ……
}

如果composition打开,我们就进行合成绘制步骤,先设置好一个内存DC:

if ( IsCompositionEnabled() )
{
 //设置一个我们将绘制的内存DC和位图
 CDC dcMem;
 CBitmap bmp;
 BITMAPINFO dib = {0};
 dcMem.CreateCompatibleDC ( dc );

接下来,填充BITMAPINFO结构以得到一个32位色深位图,且与毛玻璃区域的高宽相同。此处需重点留意的是,位图高度(即BITMAPINFOHEADER的biHeight成员)为负数,这是因为通常情况下BMP是按照从下至上的顺序存储在内存中的,但DrawThemeTextEx()需要的位图顺序是从上至下,所以要把高度设为负数。

dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
dib.bmiHeader.biWidth = rcText.Width();
dib.bmiHeader.biHeight = -rcText.Height();
dib.bmiHeader.biPlanes = 1;
dib.bmiHeader.biBitCount = 32;
dib.bmiHeader.biCompression = BI_RGB;
bmp.CreateDIBSection (dc,&dib,DIB_RGB_COLORS,NULL,NULL,0);

现在,我们的图形对象就创建好了,可以开始绘制文本了。

//设置好DC
dcMem.SelectBitmap ( bmp );
dcMem.SelectFont ( m_font );
//绘制文本
DTTOPTS dto = { sizeof(DTTOPTS) };
const UINT uFormat = DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_NOPREFIX;
CRect rcText2 = rcText;
dto.dwFlags = DTT_COMPOSITED|DTT_GLOWSIZE;
dto.iGlowSize = 10;
rcText2 -= rcText2.TopLeft(); //相同的rect,但左上角为(0,0)
DrawThemeTextEx ( m_hTheme, dcMem, 0, 0, CT2CW(szTime), -1,
uFormat, rcText2, &dto );

DTTOPTS结构控制了文本怎样被绘制,在标志中我们指明了要绘制"合成文本",并让文本有一个发光效果。最后,把内存中的位图贴到屏幕上:

 //将文本绘制到屏幕上。
 BitBlt ( dc, rcText.left, rcText.top, rcText.Width(), rcText.Height(), dcMem, 0, 0, SRCCOPY );
} // end if (IsCompositionEnabled())

如果composition未打开,我们用GDI函数绘制文本:

else
{
 const UINT uFormat = DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_NOPREFIX;
 //设置好DC
 dc.SetTextColor ( RGB(255,255,255) );
 dc.SelectFont ( m_font );
 dc.SetBkMode ( TRANSPARENT );
 //绘制文本
 dc.DrawText ( szTime, -1, rcText, uFormat );
}
return true; //我们绘制了整个背景
}

下面就是"合成文本"的模样:

用C++品尝Vista美味:界面的毛玻璃效果

为演示发光效果,下面是同一背景上的一段文本,但没有发光效果:

用C++品尝Vista美味:界面的毛玻璃效果

处理composition相关的通知

当DWM的composition状态打开或关闭时,系统会向所有顶层窗口广播一个WM_DWMCOMPOSITIONCHANGED消息;如果composition为打开,需要再次调用DwmExtendFrameIntoClientArea()以告之DWM,我们窗口的哪一部分应为毛玻璃效果:

LRESULT CMainFrame::OnCompositionChanged(...)
{
 if ( IsCompositionEnabled() )
 {
  MARGINS mar = {0};
  mar.cyBottomHeight = 100;
  DwmExtendFrameIntoClientAr

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号