用C  品尝Vista美味[4]
文章作者 100test 发表时间 2007:08:06 12:58:03
来源 100Test.Com百考试题网
绘制文本
  在毛玻璃效果上绘制文本涉及以下步骤:
  ·创建一个用于双缓冲绘制的内存DC。
  ·创建一个32位色深的DIB,并选入DC。
  ·用DrawThemeTextEx()把文本绘制在内存中的DIB上。
  ·用BitBit()把文本复制到屏幕。
  因为我们的绘制代码将会因为composition是否打开而有所不同,所以需要在绘制期间检查composition状态。检查状态的API为DwmIsCompositionEnabled(),如果API执行失败,在返回值中就不会指示出打开状态,但CMainFrame中有一个包装好的函数IsCompositionEnabled(),非常易于使用:
| 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())
 | 
 src="/ncre2/js/wxgg.js">