国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C > 正文

MFC繪制不規(guī)則窗體的方法

2020-01-26 15:06:24
字體:
供稿:網(wǎng)友

本文實(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ì)有所幫助。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 铜梁县| 阿城市| 东乌珠穆沁旗| 福海县| 运城市| 霍州市| 安庆市| 徐州市| 遂川县| 赤城县| 三门县| 兰坪| 顺义区| 茌平县| 渭南市| 巢湖市| 海丰县| 罗甸县| 昌图县| 桂阳县| 南开区| 罗甸县| 思南县| 新邵县| 集安市| 潮安县| 景谷| 云阳县| 盱眙县| 黄浦区| 阿克苏市| 三亚市| 峡江县| 越西县| 舒城县| 获嘉县| 宁阳县| 邵东县| 湖北省| 海伦市| 高碑店市|