MFC繪制不規(guī)則窗體的方法
本文實(shí)例講述了MFC 繪制不規(guī)則窗體的方法。分享給大家供大家參考。具體分析如下:
實(shí)現(xiàn)過程:
1、首先創(chuàng)建基于DLG的MFC應(yīng)用程序,命名為:tryBGDlg,并將DLG的屬性設(shè)置為:Title Bar :False ,其它設(shè)置不變
2、制作兩幅圖像,其中的一幅黑白圖像,是根據(jù)播放器外觀來制作的,其中白色區(qū)域是要保留的最終在桌面上顯示的區(qū)域。將這兩幅圖像添加到工程中,第一個(gè)ID號(hào)設(shè)置為IDB_INTERFACE,第二個(gè)ID號(hào)設(shè)置為:IDB_MASK
3、在CtryBGDlg類中添加一個(gè)在函數(shù):
函數(shù)說明:cBitmap是要傳入的掩碼位置變量,這里是指IDB_MASK創(chuàng)建的對(duì)象,TransColor是指要設(shè)為透明相素的RGB值
void CtryBGDlg::SetupRegion( CDC *pDC, CBitmap &cBitmap, COLORREF TransColor )
{
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap *pOldMemBmp=NULL;
pOldMemBmp=memDC.SelectObject(&cBitmap);
BITMAP bit;
cBitmap.GetBitmap (&bit);
CRgn crRgn, crRgnTmp;
crRgn.CreateRectRgn(0, 0, 0, 0);//創(chuàng)建一個(gè)空區(qū)域
int iX = 0;int iY = 0;
for (iY = 0; iY < bit.bmHeight; iY++)
{
do
{
//skip over transparent pixels at start of lines.
while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) == TransColor)
iX++;
//remember this pixel
int iLeftX = iX;
//now find first non transparent pixel
while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) != TransColor)
++iX;
//create a temp region on this info
crRgnTmp.CreateRectRgn(iLeftX, iY, iX, iY+1);
//combine into main region.
crRgn.CombineRgn(&crRgn, &crRgnTmp, RGN_XOR);
//delete the temp region for next pass (otherwise you'll get an ASSERT)
crRgnTmp.DeleteObject();
}while(iX < bit.bmWidth);
iX = 0;
}
SetWindowRgn(crRgn, TRUE);
iX = (GetSystemMetrics(SM_CXSCREEN))-700;
iY = (GetSystemMetrics(SM_CYSCREEN)) / 2 - (bit.bmHeight / 2);
SetWindowPos(&wndTop, iX, iY, bit.bmWidth, bit.bmHeight, NULL);
// Free resources.
memDC.SelectObject(pOldMemBmp);
// Put the original bitmap back (prevents memory leaks)
memDC.DeleteDC();
crRgn.DeleteObject();
}
4、在BOOL CtryBGDlg::OnInitDialog()函數(shù)中添加如下代碼:
CBitmap bmp; bmp.LoadBitmapW(IDB_MASK); this->SetupRegion(this->GetWindowDC(),bmp,RGB(0,0,0));
5、添加對(duì)WM_ERASEBKGND消息響應(yīng),并在BOOL CtryBGDlg::OnEraseBkgnd(CDC* pDC)函數(shù)中添加如下代碼
BOOL CtryBGDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息處理程序代碼和/或調(diào)用默認(rèn)值
CRect rect;
this->GetWindowRect(&rect);
CDC memDC;
CBitmap bmp;
CBitmap *pOldBmp=NULL;
bmp.LoadBitmapW(IDB_INTERFACE);
memDC.CreateCompatibleDC(pDC);
pOldBmp=memDC.SelectObject(&bmp);
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);
if(pOldBmp)
{
memDC.SelectObject(pOldBmp);
}
return true;
// return CDialog::OnEraseBkgnd(pDC);
}
到此就實(shí)現(xiàn)了不規(guī)則窗體的創(chuàng)建,創(chuàng)建后的視圖如開頭所示。
6、一般我們還要實(shí)現(xiàn)對(duì)窗體的托動(dòng)操作,實(shí)現(xiàn)方法如下:
添加對(duì)WM_NCHITTEST消息的響應(yīng),并在生成的LRESULT CtryBGDlg::OnNcHitTest(CPoint point)函數(shù)中添加如下代碼:
LRESULT CtryBGDlg::OnNcHitTest(CPoint point)
{
// TODO: 在此添加消息處理程序代碼和/或調(diào)用默認(rèn)值
CRect rc;
GetClientRect(&rc);
ClientToScreen(&rc);
return rc.PtInRect(point) ? HTCAPTION : CDialog::OnNcHitTest(point);
// return CDialog::OnNcHitTest(point);
}
至此就完全實(shí)現(xiàn)了,不規(guī)則窗體的創(chuàng)建和對(duì)窗體托動(dòng)消息的響應(yīng)部分。
下面將細(xì)致的講解具體實(shí)現(xiàn)原理及部分的代碼的解析:
總原理:這個(gè)程序的原理主要是先用IDB_MASK圖像計(jì)算出要設(shè)定的窗體的輪廓,然后利用SetWindowRgn()函數(shù)來對(duì)其進(jìn)行更改。最后在窗體重繪的時(shí)候響應(yīng)WM_ERASEBKGND消息,將窗體背景圖片IDB_INTERFACE貼到窗體上。
利用IDB_MASK圖像計(jì)算窗體輪廓的原理:
計(jì)算窗體輪廓的代碼主要靠SetupRegion()函數(shù)來實(shí)現(xiàn),考慮到窗體的不規(guī)則,應(yīng)采取掩模位圖的方式來對(duì)其進(jìn)行描述,對(duì)于本例,其白色區(qū)域?yàn)橐A舻牟灰?guī)則窗體的輪廓區(qū)域。這段代碼首先是用crRgn.CreateRectRgn(0, 0, 0, 0)創(chuàng)建一個(gè)空的區(qū)域,然后對(duì)IDB_MASK圖像的像素信息進(jìn)行一列一列的枚舉,計(jì)算出每列中不設(shè)為透明的區(qū)域,然后跟crRgn合并,所以最后的crRgn就是所要設(shè)定的區(qū)域。
核心代碼為:
CRgn crRgn, crRgnTmp;
//創(chuàng)建一個(gè)空區(qū)域
crRgn.CreateRectRgn(0, 0, 0, 0);
int iX = 0;int iY = 0;
for (iY = 0; iY < bit.bmHeight; iY++)
{
do
{
//skip over transparent pixels at start of lines.
//以一個(gè)相素列為單位,找到在這一個(gè)相素列中,第一個(gè)不是要設(shè)為透明相素的點(diǎn)iX。
//然后再找到以這個(gè)iX為起點(diǎn)的,在這個(gè)一個(gè)相素列中最后跟他臨近的最后一個(gè)不是透明的點(diǎn)。
//然后將他們一起合并到crRgn中。
while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) == TransColor)
iX++;//在iY和iY+1這個(gè)相索列中,第一個(gè)不設(shè)為透明的點(diǎn)的X坐標(biāo)
int iLeftX = iX;//保存這個(gè)點(diǎn)的坐標(biāo)
while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) != TransColor)
++iX;//這是找到在iX最臨近的不透明的X坐標(biāo)
crRgnTmp.CreateRectRgn(iLeftX, iY, iX, iY+1);//這四個(gè)點(diǎn)連在一起就是現(xiàn)在剛找到的不透明的區(qū)域
//合并區(qū)域
crRgn.CombineRgn(&crRgn, &crRgnTmp, RGN_OR);
//記得最終要手動(dòng)刪除crRgnTmp對(duì)象
crRgnTmp.DeleteObject();
}while(iX < bit.bmWidth);
//如果iX沒有達(dá)到圖片的末尾,說明還沒有枚舉完這一行,則在iY和iY+1這個(gè)行上,進(jìn)行下一輪的//枚舉
iX = 0;
}
希望本文所述對(duì)大家的MFC程序設(shè)計(jì)有所幫助。
上一篇:C語(yǔ)言實(shí)現(xiàn)清空指定文件夾中所有文件的方法
欄 目:C語(yǔ)言
下一篇:C++實(shí)現(xiàn)顯示MP3文件信息的方法
本文標(biāo)題:MFC繪制不規(guī)則窗體的方法
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/3057.html
您可能感興趣的文章
- 01-10三種獲取網(wǎng)頁(yè)源碼的方法(使用MFC/Socket實(shí)現(xiàn))
- 01-10構(gòu)建mfc窗體的簡(jiǎn)單示例
- 01-10MFC實(shí)現(xiàn)全屏功能代碼實(shí)例
- 01-10MFC自定義消息的實(shí)現(xiàn)方法
- 01-10VC中SDK與MFC的區(qū)別淺析
- 01-10MFC中Radio Button的用法詳解
- 01-10MFC命名規(guī)則匯總
- 01-10C和MFC巧妙獲取外網(wǎng)IP的兩種實(shí)現(xiàn)方法
- 01-10VC MFC非模態(tài)對(duì)話框的實(shí)現(xiàn)方法
- 01-10MFC創(chuàng)建模態(tài)對(duì)話框和非模態(tài)對(duì)話框的方法


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10delphi制作wav文件的方法
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載


