Windows 中不规则窗体的编程实现
2006-07-19 11:29:53 来源:WEB开发网CClientDC是CDC的派生类,故此该类具有所有CDC类的成员变量和成员函数。
图二 hello形状的窗体效果图
五、根据图像创建”region”
此法创建不规则窗体比较复杂。首先准备一张含有目标窗体形状的图片,设置透明色即将图片中部不属于窗体形状的部分,标记成同一种颜色,例如蓝色RGB(0,0,255).程序运行后先装入图片。然后逐个扫描图片的每个像素,如这个像素不属于透明色,则在相应位置创建一个只含一个像素的“region”然后将这些小”region ”合并起来组成一个任意形状的”region”.这里将使用到CRgn的一个成员函数 :int CRgn::CombineRgn( CRgn* pRgn1, CRgn* pRgn2, int nCombineMode );
其中pRgn1,pRgn2为要合并的两个“region”,nCombineMode为合并的方式,此应用中取RGN_OR,即两”region”全部合并去处重复部分。代码实现如下:
void SetupRegion(
CDC *pDC, //窗体的DC指针
CBitmap &cBitmap, //含有窗体形状的位图对象
COLORREF TransColor //透明色
)
{ CDC memDC;
//创建与传入DC兼容的临时DC
memDC.CreateCompatibleDC(pDC);
CBitmap *pOldMemBmp=NULL;
//将位图选入临时DC
pOldMemBmp=memDC.SelectObject(&cBitmap);
CRgn wndRgn;
//创建总的窗体区域,初始region为0
wndRgn.CreateRectRgn(0,0,0,0);
BITMAP bit;
cBitmap.GetBitmap (&bit);//取得位图参数,这里要用到位图的长和宽
int y;
for(y=0;y<=bit.bmHeight ;y++)
{
CRgn rgnTemp; //保存临时region
int iX = 0;
do
{
//跳过透明色找到下一个非透明色的点.
while (iX <= bit.bmWidth && memDC.GetPixel(iX, y) == TransColor)
iX++;
//记住这个起始点
int iLeftX = iX;
//寻找下个透明色的点
while (iX <= bit.bmWidth && memDC.GetPixel(iX, y) != TransColor)
++iX;
//创建一个包含起点与重点间高为1像素的临时“region”
rgnTemp.CreateRectRgn(iLeftX, y, iX, y+1);
//合并到主"region".
wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_OR);
//删除临时"region",否则下次创建时和出错
rgnTemp.DeleteObject();
}while(iX GetWindow();
pWnd->SetWindowRgn(wndRgn,TRUE);
pWnd->SetForegroundWindow();
}
上述代码创建的不规则窗体中,在OnEraseBkgnd事件中绘制该位图,就可得到与该位图形状一模一样的窗体。
图三 根据位图和位图中的透明色创建的窗体效果图
六、小结
三种创建“region”的方法,第一种最简单,如果所需的窗体形状是简单的几何图形,这种方法最合适;第二种稍微复杂些,但是创建的窗体形状更多些;第三种方法可以创建任何在图片中画出的窗体形状,但是实现的复杂度也最高。
注:本文的写作曾参考了“形态各异的不规则窗体”一文。
更多精彩
赞助商链接