随着Microsoft凭借Windows在操作系统上取得的巨大成绩,Windows用户界面也日益成为业界标准。统一的界面给广大用户对应用软件的学习与使用带来了很大方便。但每天都面对同一副面孔,日久天长难免会产生一些厌倦,想开发一些"离经叛道"的应用程序,如果能够一改Windows千篇一律的"标准"界面,一定会给用户带来一种清新的感觉。标准Windows应用程序窗口一般为带有标题栏的浅灰色矩形外观,因而"异形"对话框/窗口也主要是颜色与外形上动手脚。本实例实现了一个"精灵"窗口,程序编译运行后的界面效果如图一所示:
![]() 图一、叠加在Visual C++开发工具上的透明"精灵"窗体 |
| ///////////////////////////////////////////////////////////////////////////// // 获得窗体矩形 CRect rectWnd; this->GetWindowRect(rectWnd); // 读取"掩模"位图资源 CBitmap myBitmap,*pOldBitmap; myBitmap.LoadBitmap(nMaskId); // 创建"内存一致"设备 CDC memDC; memDC.CreateCompatibleDC(pDC); // 选择绘图设备 pOldBitmap = memDC.SelectObject(&myBitmap); // 创建窗体的初始区域 CRgn rgnWnd,rgnTemp; rgnWnd.CreateRectRgn(0,0,rectWnd.Width(),rectWnd.Height()); int nWidth,nHeight; COLORREF color; //下面的两层循环为检查背景位图象素颜色,进行透明区域处理; //当象素颜色为指定的透明值时,即将该点从区域中剪裁掉。 for (nWidth = 0;nWidth <= rectWnd.Width()-1;nWidth++) { for (nHeight = 0;nHeight <= rectWnd.Height();nHeight++) { color = memDC.GetPixel(nWidth,nHeight); // 当象素是白色时,去掉该点 if (color == RGB(255,255,255)) { //象素颜色为指定的透明色,创建透明"微区域" rgnTemp.CreateRectRgn(nWidth,nHeight,nWidth+1,nHeight+1); //"扣像",从完整的区域中"扣除"透明的"微区域" rgnWnd.CombineRgn(&rgnWnd,&rgnTemp,RGN_XOR); //删除刚创建的透明"微区域",释放系统资源 rgnTemp.DeleteObject(); } } } memDC.SelectObject(pOldBitmap); SetWindowRgn((HRGN)rgnWnd,TRUE); //用最终设定窗口的显示区域为指定区域 |
为了最终显示透明效果的窗体,还需要重置系统默认的背景擦除操作,即添加WM_ERASEBKGND消息处理过程,在其中实现背景位图的显示功能,这一步可以借助ClassWizard来实现。
最后需要注意的是,为了使异形窗体应用程序能够正常地脱动和退出,需要处理窗体的WM_NCHITTEST、WM_CHAR等消息,这部分内容本书中其它实例已经作过介绍,这里就不再赘述了,感性趣的读者朋友可以参考相关实例。