VC++玩转炫酷悬浮窗2---不规则窗体的实现(常规)
2014-08-22 10:47
387 查看
目标
不规则窗体也称为异型窗体,像迅雷的飞鸟型窗体就是啦。这篇文章就是要实现这样的窗体。
计划&方案
根据上一篇文章继续扩展。我们有几种方案实现不规则窗体。迅雷就是用一张图片作为窗体的形状,那
么图片的类型我们也要考虑进来。现在是png图片的天下,自带背景透明;对于bmp图片,需要程序处理
一下。
对于常规图形如圆形,只需要SetWindowRgn就可以搞定。对于复杂图形,需要用一点技巧来做。下面用
例子来演示圆形和复杂图形的不规则窗体。
关于SetWindowRgn,参见官方文档。
实践
一、 圆形窗体
这里还要借助另一个类CRgn,它作为SetWindowRgn的主要参数,通过CreateEllipticRgn方法初始化
出圆形区域。具体代码如:
二、 复杂图形窗体
引用vckbase的文章《Windows 中不规则窗体的编程实现》中“根据图像创建region”一节。
技巧:选一种图片中没有的颜色作为背景色(文章中用蓝色),程序将扫描图片的每一个像素,如果不是
背景色,那么就在此位置创建此像素的region,然后把所有这样的region合并起来构成图片,就好像
去掉了背景色一样,成为背景透明。
这里又用到一个合并region的api CombineRgn:
RGN_OR Combines both regions in their entirety (union).
例子如下:
源码在此!
通过对比,用常规方法都会产生锯齿,如何消除锯齿?引出我的下文,用GDI+实现完美不规则窗体。
不规则窗体也称为异型窗体,像迅雷的飞鸟型窗体就是啦。这篇文章就是要实现这样的窗体。
计划&方案
根据上一篇文章继续扩展。我们有几种方案实现不规则窗体。迅雷就是用一张图片作为窗体的形状,那
么图片的类型我们也要考虑进来。现在是png图片的天下,自带背景透明;对于bmp图片,需要程序处理
一下。
对于常规图形如圆形,只需要SetWindowRgn就可以搞定。对于复杂图形,需要用一点技巧来做。下面用
例子来演示圆形和复杂图形的不规则窗体。
关于SetWindowRgn,参见官方文档。
实践
一、 圆形窗体
这里还要借助另一个类CRgn,它作为SetWindowRgn的主要参数,通过CreateEllipticRgn方法初始化
出圆形区域。具体代码如:
CRgn rgn; rgn. CreateEllipticRgn(0,0,96,96); SetWindowRgn(rgn,TRUE);接下来封装一个方法来加载png图片:
void ShowPicture() { CImage img; HRESULT result = img.Load(_T("prime.png")); //加强透明化 for(int i = 0; i < img.GetWidth(); i++) { for(int j = 0; j < img.GetHeight(); j++) { unsigned char* pucColor = reinterpret_cast<unsigned char *> (img.GetPixelAddress(i , j)); pucColor[0] = pucColor[0] * pucColor[3] / 255; pucColor[1] = pucColor[1] * pucColor[3] / 255; pucColor[2] = pucColor[2] * pucColor[3] / 255; } } CDC *pDC = GetWindowDC(); int nX = img.GetWidth(); int nY = img.GetHeight(); img.Draw( pDC->m_hDC,0,0); ReleaseDC( pDC ); }
二、 复杂图形窗体
引用vckbase的文章《Windows 中不规则窗体的编程实现》中“根据图像创建region”一节。
技巧:选一种图片中没有的颜色作为背景色(文章中用蓝色),程序将扫描图片的每一个像素,如果不是
背景色,那么就在此位置创建此像素的region,然后把所有这样的region合并起来构成图片,就好像
去掉了背景色一样,成为背景透明。
这里又用到一个合并region的api CombineRgn:
int CombineRgn( CRgn* pRgn1, CRgn* pRgn2, int nCombineMode );合并的模式我们选择完全合并:
RGN_OR Combines both regions in their entirety (union).
例子如下:
void CAfoatWindowMessageDlg::SetupRegion( CDC *pDC, //DC of this window CBitmap &cBitmap, COLORREF TransColor //the color need remove ) { CDC memDC; //temporary DC memDC.CreateCompatibleDC(pDC); CBitmap *pOldMemBmp=NULL; //Load bmp file pOldMemBmp=memDC.SelectObject(&cBitmap); CRgn wndRgn; // window region //window region init wndRgn.CreateRectRgn(0,0,0,0); BITMAP bit; cBitmap.GetBitmap (&bit);//get the value of bmp file int y; for(y=0;y<=bit.bmHeight ;y++) { CRgn rgnTemp; //temporary region int iX = 0; do { //skip TransColor while (iX <= bit.bmWidth && memDC.GetPixel(iX, y) == TransColor) iX++; //record this point int iLeftX = iX; //Skip none transColor while (iX <= bit.bmWidth && memDC.GetPixel(iX, y) != TransColor) ++iX; //create temporary “region” rgnTemp.CreateRectRgn(iLeftX, y, iX, y+1); //combine "region". wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_OR); //delete temporary "region" rgnTemp.DeleteObject(); }while(iX <bit.bmWidth ); iX = 0; } if(pOldMemBmp) memDC.SelectObject(pOldMemBmp); CWnd * pWnd = pDC->GetWindow(); pWnd->SetWindowRgn(wndRgn,TRUE); pWnd->SetForegroundWindow(); }
源码在此!
通过对比,用常规方法都会产生锯齿,如何消除锯齿?引出我的下文,用GDI+实现完美不规则窗体。
相关文章推荐
- VC++玩转炫酷悬浮窗3---GDI+完美实现不规则窗体
- VC++玩转炫酷悬浮窗1---悬浮窗的实现
- vc里实现不规则窗体
- Windows 中不规则窗体的编程实现
- VC++实现不规则窗口说明
- VC透明窗体的实现
- C++BUILDER中一些实现界面效果的技巧。。不规则窗体等等。。
- 用VC++实现不规则窗口
- VC 实现 自绘 窗体 标题栏 非客户区
- VC下简易实现窗体的淡入淡出效果(fade in-out for CDialog)
- VC遍历窗体控件的实现
- VC遍历窗体控件的实现
- 不规则窗体的实现
- Qt 不规则窗体的实现
- Qt中不规则窗体和部件的实现
- Java实现带渐变字幕的不规则窗体
- VC++.NET winForm中怎样实现两个窗体互相修改对方TextBox的值,我是菜鸟:)
- VC遍历窗体控件的实现
- 用VC++实现不规则窗口
- 用VC++实现不规则窗口