繪制文本
在毛玻璃效果上繪制文本涉及以下步驟:
·創(chuàng)建一個(gè)用于雙緩沖繪制的內(nèi)存DC。
·創(chuàng)建一個(gè)32位色深的DIB,并選入DC。
·用DrawThemeTextEx()把文本繪制在內(nèi)存中的DIB上。
·用BitBit()把文本復(fù)制到屏幕。
因?yàn)槲覀兊睦L制代碼將會(huì)因?yàn)閏omposition是否打開(kāi)而有所不同,所以需要在繪制期間檢查composition狀態(tài)。檢查狀態(tài)的API為DwmIsCompositionEnabled(),如果API執(zhí)行失敗,在返回值中就不會(huì)指示出打開(kāi)狀態(tài),但CMainFrame中有一個(gè)包裝好的函數(shù)IsCompositionEnabled(),非常易于使用:
bool CMainFrame::IsCompositionEnabled() const
{
HRESULT hr;
BOOL bEnabled;
hr = DwmIsCompositionEnabled(&bEnabled);
return SUCCEEDED(hr) && bEnabled;
}
現(xiàn)在,讓我們?cè)贆z查一遍OnEraseBkgnd(),看看每個(gè)步驟是否都完成了。這個(gè)程序是一個(gè)時(shí)鐘程序,所以先用GetTimeFormat()獲取當(dāng)前時(shí)間:
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;
//獲取當(dāng)前時(shí)間
TCHAR szTime[64];
GetTimeFormat(LOCALE_USER_DEFAULT,0,NULL,NULL,szTime,_countof(szTime));
……
}
如果composition打開(kāi),我們就進(jìn)行合成繪制步驟,先設(shè)置好一個(gè)內(nèi)存DC:
if ( IsCompositionEnabled() )
{
//設(shè)置一個(gè)我們將繪制的內(nèi)存DC和位圖
CDC dcMem;
CBitmap bmp;
BITMAPINFO dib = {0};
dcMem.CreateCompatibleDC ( dc );
接下來(lái),填充BITMAPINFO結(jié)構(gòu)以得到一個(gè)32位色深位圖,且與毛玻璃區(qū)域的高寬相同。此處需重點(diǎn)留意的是,位圖高度(即BITMAPINFOHEADER的biHeight成員)為負(fù)數(shù),這是因?yàn)橥ǔG闆r下BMP是按照從下至上的順序存儲(chǔ)在內(nèi)存中的,但DrawThemeTextEx()需要的位圖順序是從上至下,所以要把高度設(shè)為負(fù)數(shù)。
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);
現(xiàn)在,我們的圖形對(duì)象就創(chuàng)建好了,可以開(kāi)始繪制文本了。
//設(shè)置好DC
dcMem.SelectBitmap ( bmp );
dcMem.SelectFont ( m_font );
//繪制文本
DTTS dto = { sizeof(DTTS) };
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 );
DTTS結(jié)構(gòu)控制了文本怎樣被繪制,在標(biāo)志中我們指明了要繪制"合成文本",并讓文本有一個(gè)發(fā)光效果。最后,把內(nèi)存中的位圖貼到屏幕上:
//將文本繪制到屏幕上。
BitBlt ( dc, rcText.left, rcText.top, rcText.Width(), rcText.Height(), dcMem, 0, 0, SRCCOPY );
} // end if (IsCompositionEnabled())
在毛玻璃效果上繪制文本涉及以下步驟:
·創(chuàng)建一個(gè)用于雙緩沖繪制的內(nèi)存DC。
·創(chuàng)建一個(gè)32位色深的DIB,并選入DC。
·用DrawThemeTextEx()把文本繪制在內(nèi)存中的DIB上。
·用BitBit()把文本復(fù)制到屏幕。
因?yàn)槲覀兊睦L制代碼將會(huì)因?yàn)閏omposition是否打開(kāi)而有所不同,所以需要在繪制期間檢查composition狀態(tài)。檢查狀態(tài)的API為DwmIsCompositionEnabled(),如果API執(zhí)行失敗,在返回值中就不會(huì)指示出打開(kāi)狀態(tài),但CMainFrame中有一個(gè)包裝好的函數(shù)IsCompositionEnabled(),非常易于使用:
bool CMainFrame::IsCompositionEnabled() const
{
HRESULT hr;
BOOL bEnabled;
hr = DwmIsCompositionEnabled(&bEnabled);
return SUCCEEDED(hr) && bEnabled;
}
現(xiàn)在,讓我們?cè)贆z查一遍OnEraseBkgnd(),看看每個(gè)步驟是否都完成了。這個(gè)程序是一個(gè)時(shí)鐘程序,所以先用GetTimeFormat()獲取當(dāng)前時(shí)間:
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;
//獲取當(dāng)前時(shí)間
TCHAR szTime[64];
GetTimeFormat(LOCALE_USER_DEFAULT,0,NULL,NULL,szTime,_countof(szTime));
……
}
如果composition打開(kāi),我們就進(jìn)行合成繪制步驟,先設(shè)置好一個(gè)內(nèi)存DC:
if ( IsCompositionEnabled() )
{
//設(shè)置一個(gè)我們將繪制的內(nèi)存DC和位圖
CDC dcMem;
CBitmap bmp;
BITMAPINFO dib = {0};
dcMem.CreateCompatibleDC ( dc );
接下來(lái),填充BITMAPINFO結(jié)構(gòu)以得到一個(gè)32位色深位圖,且與毛玻璃區(qū)域的高寬相同。此處需重點(diǎn)留意的是,位圖高度(即BITMAPINFOHEADER的biHeight成員)為負(fù)數(shù),這是因?yàn)橥ǔG闆r下BMP是按照從下至上的順序存儲(chǔ)在內(nèi)存中的,但DrawThemeTextEx()需要的位圖順序是從上至下,所以要把高度設(shè)為負(fù)數(shù)。
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);
現(xiàn)在,我們的圖形對(duì)象就創(chuàng)建好了,可以開(kāi)始繪制文本了。
//設(shè)置好DC
dcMem.SelectBitmap ( bmp );
dcMem.SelectFont ( m_font );
//繪制文本
DTTS dto = { sizeof(DTTS) };
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 );
DTTS結(jié)構(gòu)控制了文本怎樣被繪制,在標(biāo)志中我們指明了要繪制"合成文本",并讓文本有一個(gè)發(fā)光效果。最后,把內(nèi)存中的位圖貼到屏幕上:
//將文本繪制到屏幕上。
BitBlt ( dc, rcText.left, rcText.top, rcText.Width(), rcText.Height(), dcMem, 0, 0, SRCCOPY );
} // end if (IsCompositionEnabled())