实现不规则窗体------基于MFC based DLG
来源:互联网 发布:白皮猪 知乎 编辑:程序博客网 时间:2024/05/21 16:58
实现界面如下所示:(文末有源码下载地址,初写技术博客,写的不好还请大家多多批评指正)
实现过程:
1、首先创建基于DLG的MFC应用程序,命名为:tryBGDlg,并将DLG的属性设置为:Title Bar :False ,其它设置不变2、制作两幅图像,其中的一幅黑白图像,是根据播放器外观来制作的,其中白色区域是要保留的最终在桌面上显示的区域。将这两幅图像添加到工程中,第一个ID号设置为IDB_INTERFACE,第二个ID号设置为:IDB_MASK
3、在CtryBGDlg类中添加一个在函数:
//函数说明:cBitmap是要传入的掩码位置变量,这里是指IDB_MASK创建的对象,TransColor是指要设为透明相素的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);//创建一个空区域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 pixelint iLeftX = iX;//now find first non transparent pixelwhile (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) != TransColor)++iX;//create a temp region on this infocrRgnTmp.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()函数中添加如下代码:
CBitmap bmp;bmp.LoadBitmapW(IDB_MASK);this->SetupRegion(this->GetWindowDC(),bmp,RGB(0,0,0));
5、添加对WM_ERASEBKGND消息响应,并在BOOL CtryBGDlg::OnEraseBkgnd(CDC* pDC)函数中添加如下代码
BOOL CtryBGDlg::OnEraseBkgnd(CDC* pDC){// TODO: 在此添加消息处理程序代码和/或调用默认值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);}
到此就实现了不规则窗体的创建,创建后的视图如开头所示。
6、一般我们还要实现对窗体的托动操作,实现方法如下:
添加对WM_NCHITTEST消息的响应,并在生成的LRESULT CtryBGDlg::OnNcHitTest(CPoint point)函数中添加如下代码:
LRESULT CtryBGDlg::OnNcHitTest(CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值CRect rc;GetClientRect(&rc);ClientToScreen(&rc);return rc.PtInRect(point) ? HTCAPTION : CDialog::OnNcHitTest(point);//return CDialog::OnNcHitTest(point);}
至此就完全实现了,不规则窗体的创建和对窗体托动消息的响应部分。
下面将细致的讲解具体实现原理及部分的代码的解析:
总原理:这个程序的原理主要是先用IDB_MASK图像计算出要设定的窗体的轮廓,然后利用SetWindowRgn()函数来对其进行更改。最后在窗体重绘的时候响应WM_ERASEBKGND消息,将窗体背景图片IDB_INTERFACE贴到窗体上。
利用IDB_MASK图像计算窗体轮廓的原理:
计算窗体轮廓的代码主要靠SetupRegion()函数来实现,考虑到窗体的不规则,应采取掩模位图的方式来对其进行描述,对于本例,其白色区域为要保留的不规则窗体的轮廓区域。这段代码首先是用crRgn.CreateRectRgn(0, 0, 0, 0)创建一个空的区域,然后对IDB_MASK图像的像素信息进行一列一列的枚举,计算出每列中不设为透明的区域,然后跟crRgn合并,所以最后的crRgn就是所要设定的区域。
核心代码为:
CRgn crRgn, crRgnTmp;//创建一个空区域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.//以一个相素列为单位,找到在这一个相素列中,第一个不是要设为透明相素的点iX。//然后再找到以这个iX为起点的,在这个一个相素列中最后跟他临近的最后一个不是透明的点。//然后将他们一起合并到crRgn中。while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) == TransColor)iX++;//在iY和iY+1这个相索列中,第一个不设为透明的点的X坐标int iLeftX = iX;//保存这个点的坐标while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) != TransColor)++iX;//这是找到在iX最临近的不透明的X坐标crRgnTmp.CreateRectRgn(iLeftX, iY, iX, iY+1);//这四个点连在一起就是现在刚找到的不透明的区域//合并区域crRgn.CombineRgn(&crRgn, &crRgnTmp, RGN_OR);//记得最终要手动删除crRgnTmp对象crRgnTmp.DeleteObject();}while(iX < bit.bmWidth);//如果iX没有达到图片的末尾,说明还没有枚举完这一行,则在iY和iY+1这个行上,进行下一轮的//枚举iX = 0;}
源码下载地址:http://download.csdn.net/detail/harvic880925/4562697
源码下载收了两分,就当是讲解费吧,嘻嘻
声明:所用图片来自网络,感谢金山影音的网络图片,如果存在版权问题,你直接回复,我将删除
- 实现不规则窗体------基于MFC based DLG
- MFC制作不规则窗体
- MFC不规则窗体
- MFC 绘制不规则窗体
- MFC 创建不规则窗体
- MFC制作不规则窗体
- MFC界面编程1:GDI+实现不规则窗体
- [转]MFC制作不规则窗体
- 不规则窗体的实现
- wxWidgets实现不规则窗体
- 不规则窗体实现
- 不规则窗体实现 收藏
- 不规则窗体的实现
- QT实现不规则窗体
- wxWidgets实现不规则窗体
- javafx 不规则窗体实现
- QT实现不规则窗体
- QT实现不规则窗体
- junit4测试(二)
- 点分直线,直线分平面,平面分空间
- 享受寂寞
- android 三种定位方式
- 杨叔子院士:人生在勤,贵在励志
- 实现不规则窗体------基于MFC based DLG
- java 程序调用Oracle Function .
- 《编程之美》 2.18 数组分割
- Dojo 1.8 之 StoreSeries (Point Coordinate)
- ant的安装遇到的问题
- 借我一生
- QTP框架-学习交流
- Oracle安装
- 学习Spring3.X 企业应用开发实战笔记(二 )