void CTransDlg::SetupRegion(CDC *pDC /*對(duì)話框窗口DC*/, UINT BackBitmapID /*背景位圖資源ID*/,
UINT MaskBitmapID /*區(qū)域處理位圖資源ID*/, COLORREF TransColor = 0x00000000 /*透明顏色值,默認(rèn)為黑色*/)。
{
//我們暫時(shí)認(rèn)為MaskBitmapID等同于BackBitmapID。
//其核心工作是根據(jù)MaskBitmapID指示位圖的象素顏色進(jìn)行區(qū)域組合。
CDC memDC;
CBitmap cBitmap;
CBitmap* pOldMemBmp = NULL;
COLORREF cl;
CRect cRect;
UINT x, y;
CRgn wndRgn, rgnTemp;
//取得窗口大小
GetWindowRect(&cRect);
//背景位圖資源ID
UINT m_BackBitmapID = BackBitmapID;
//裝載位圖
cBitmap.LoadBitmap(MaskBitmapID);
memDC.CreateCompatibleDC(pDC);
pOldMemBmp = memDC.SelectObject(&cBitmap);
//首先創(chuàng)建默認(rèn)的完整區(qū)域?yàn)橥暾拇翱趨^(qū)域
wndRgn.CreateRectRgn(0, 0, cRect.Width(), cRect.Height());
//下面的兩層循環(huán)為檢查背景位圖象素顏色,進(jìn)行透明區(qū)域處理;
//當(dāng)象素顏色為指定的透明值時(shí),即將該點(diǎn)從區(qū)域中剪裁掉。
int m_MaskLeftOff=0,m_MaskTopOff=0;
int m_MaskRightOff=0,m_MaskBottomOff=0;
int m_FrameWidth=0,m_CaptionHeight=0;
for(x= m_FrameWidth+m_MaskLeftOff;x<=cRect.Width() - m_FrameWidth-m_MaskRightOff; x++)
{
for(y = m_CaptionHeight+m_MaskTopOff; y<=cRect.Height() - m_FrameWidth-m_MaskBottomOff; y++)
{
//取得坐標(biāo)處象素的顏色值
cl = memDC.GetPixel(x - m_FrameWidth-m_MaskLeftOff,y - m_CaptionHeight-m_MaskTopOff);
if(col == TransColor)
{
//象素顏色為指定的透明色,創(chuàng)建透明“微區(qū)域”
rgnTemp.CreateRectRgn(x, y, x+1, y+1);
//“扣像”,從完整的區(qū)域中“扣除”透明的“微區(qū)域”
wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_XOR);
//刪除剛創(chuàng)建的透明“微區(qū)域”,釋放系統(tǒng)資源
rgnTemp.DeleteObject();
}
}
}
if (pOldMemBmp)
memDC.SelectObject(pOldMemBmp);
//用設(shè)定窗口為指定的區(qū)域
SetWindowRgn((HRGN)wndRgn, TRUE);
}
//即添加WM_ERASEBKGND消息處理過(guò)程
OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
CRect rect;
CDC memDC;
CBitmap cBitmap;
CBitmap* pOldMemBmp = NULL;
GetWindowRect(&rect);
//裝載背景位圖
cBitmap.LoadBitmap(m_BackBitmapID);
memDC.CreateCompatibleDC(pDC);
pOldMemBmp = memDC.SelectObject(&cBitmap);
//將背景位圖復(fù)制到窗口客戶區(qū)
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRC/DownloadFiles\a\2001-10-12\COPY);
if (pOldMemBmp)
memDC.SelectObject( pOldMemBmp );
//刪除系統(tǒng)卻省的OnEraseBkgnd功能
//return CDialog::OnEraseBkgnd(pDC);
return TRUE;
}
//接下來(lái)是在WM_PAINT的消息處理函數(shù)OnPaint()中添加代碼。
//由于當(dāng)背景位圖比較大時(shí),進(jìn)行區(qū)域處理比較耗時(shí),所以只在啟動(dòng)時(shí)進(jìn)行一次處理。
//一種方法是OnInitDialog()處理,但這樣會(huì)在從啟動(dòng)程序到窗口出現(xiàn)有相當(dāng)?shù)难舆t,
//易引起程序尚未啟動(dòng)的誤解。
//再一種方法就是在OnPaint()處理,但為了避免重復(fù)處理,可以加上一個(gè)判斷標(biāo)志。
//以下是OnPaint()的代碼,正體為AppWizard生成,粗體為自己添加內(nèi)容。
//
void CTransDlg::OnPaint()
{
if (IsIconic()){……}
else
{
if(m_nFirstRun)
{
//首次運(yùn)行標(biāo)志//修改鼠標(biāo)光標(biāo)為等待方式BeginWaitCursor();
//設(shè)置背景區(qū)域
SetupRegion(GetWindowDC(),IDB_BACKBMP, IDB_BACKBMP,0x00FFFFFF /*白色*/);
//恢復(fù)鼠標(biāo)光標(biāo)為正常模式
EndWaitCursor();
m_nFirstRun = 0;
}
CDialog::OnPaint();
}
}
//剩下的工作就是根據(jù)背景位圖的大小來(lái)設(shè)置對(duì)話框窗口的大小和位置
//這可以在OnInitDialog()中通過(guò)調(diào)用MoveWindow()來(lái)實(shí)現(xiàn)
//但有些情況下又需要不同的樣式,如有標(biāo)題欄、邊框等,或者只作局部的處理
//這就是前面兩個(gè)成員變量m_FrameWidth和m_CaptionHeight作用
BOOL CTransBmpDlg::OnInitDialog()
{
// TODO: Add extra initialization here
m_nFirstRun = 1;
//數(shù)據(jù)設(shè)置,窗口左上角坐標(biāo):
m_Left=0;
m_Top=0;
//背景位圖寬高:
m_Width=535;
m_Height=105;
SetSize(0, 0, 535, 105);
//蒙板處理區(qū)域與窗口邊框的距離
m_MaskLeftOff=m_MaskTopOff=m_MaskRightOff=m_MaskBottomOff=0;
//窗口邊框與標(biāo)題欄象素值
m_FrameWidth = m_CaptionHeight = 0;
//取得窗口樣式
LONG style = ::GetWindowLong(this->m_hWnd, GWL_STYLE);
//如保留窗口風(fēng)格樣式,則根據(jù)不同的窗口邊框類型
//選取不同的m_FrameWidth和m_CaptionHeight值,
//也可以根據(jù)處理位置的需要進(jìn)行付值
if((style & WS_BORDER) == WS_BORDER)
m_FrameWidth = ::GetSystemMetrics(SM_CXBORDER);
if((style & WS_THICKFRAME) == WS_THICKFRAME)
m_FrameWidth = ::GetSystemMetrics(SM_CXFIXEDFRAME);
if((style & DS_MODALFRAME) == DS_MODALFRAME)
m_FrameWidth = ::GetSystemMetrics(SM_CXFIXEDFRAME);
if((style & WS_CAPTION) == WS_CAPTION)
{
m_FrameWidth = ::GetSystemMetrics(SM_CXFIXEDFRAME);
m_CaptionHeight = ::GetSystemMetrics(SM_CYSMCAPTION);
}
m_CaptionHeight += m_FrameWidth * 2;
//重置窗口的位置和大小
MoveWindow(m_Left, m_Top, _FrameWidth * 2m_Width + m, m_Height + m_CaptionHeight, TRUE);
……return TRUE;
// return TRUE unless you set the focus to a control
}
//使窗口樣式不僅僅受背景位圖顏色的控制。
//通過(guò)指定SetupRegion()的MaskBitmapID 為一個(gè)我們稱之為“蒙板”的雙色位圖
posted on 2008-08-04 11:56
cpsprogramer 閱讀(3179)
評(píng)論(3) 編輯 收藏 引用 所屬分類:
VC++