VC编程之VC实现顶层窗口的透明与实现子窗口的透明

本文主要向大家介绍了VC编程之VC实现顶层窗口的透明与实现子窗口的透明,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。

本人在vc开发过程中,多次因窗口透明而煞费苦心,在本人的前一文章《UpdateLayeredWindow与SetLayeredWindowAttributes》中已经指明实现窗口的透明方法,在过往实际的开发过程中我也一直沿袭这一做法,但也并不是屡试不爽,实际应用过程中的缺陷暴露如下:

(1)SetLayeredWindowAttributes和UpdateLayeredWindow两个API函数只能适用于层级窗口,也就是非子窗口;

(2)UpdateLayeredWindow方法效率比SetLayeredWindowAttributes效率高,但是它是通过绘制到某一个内存中间设备上下文后,将设备上下文拷贝到指定层级窗口上实现的,也就是所有的绘制都必须在内存设备上下文实现,甚至包括所有子控件,所以通过它实现透明,父窗口上的所有子控件“不见了”,所以应特别注意[这也是经验总结,切记!],但好处是指定不透明度为255时候,它自动从使用的png的alpha[当然不一定是png贴图,只要贴图有alpha通道]通道去透明窗口,也就是透明度就是图片的透明度,否则不使用贴图情况当然可以使用const

透明常亮指定透明度;SetLayeredWindowAttributes透明也有两种方式,第一种是通过指定COLORREF crKey,

掩码色,也就是参数2指定为要剔除的掩码色【窗口自动将所有背景中为crkey的掩码色的背景完全透明】,当然使用掩码色方法的时候必须指定 DWORD dwFlags为LWA_COLORKEY,即使用掩码色透明;第二种方式就是不使用掩码色,而是使用透明度去透明而不关心你背景颜色到底如何,只是将整个窗口加上一层透明度,这时crkey忽略填写0,将bAlpha不透明度指定成0-255的任意值,0指完全透明,255指完全不透明,此时指定 DWORD dwFlags为LWA_ALPHA.

BOOL SetLayeredWindowAttributes(

HWND hwnd,

COLORREF crKey,

BYTE bAlpha,

DWORD dwFlags

);通过对比可以知道SetLayeredWindowAttributes中第一种透明方法是逐个去掉掩码色位置的像素,而UpdateLayeredWindow是通过二进制与操作实现的,所以UpdateLayeredWindow效率要高很多很多;

(3)由于是层级窗口,在实际应用中将透明窗口都设置为透明窗口导致的问题是,切换到其他页面的时候,必须手动去隐藏改层级窗口,如果手动SetParent这层级窗口就失效,调用后自动带上WS_CHILD属性导致层级窗口透明无法实现;

(4)最小化后再显示,透明窗口显示比其他窗口快,感觉覆盖在其他窗口上的透明窗口“不是一伙的”,失联了一般;

(5)透明窗口单独跑到桌面上去了,应用程序最小化不可见;

以上是使用层级窗口透明的方法以及使用该方法暴露的若干问题,针对以上问题,为了完善或避免以上方法,我一直在寻找使得子窗口透明的方法,不巧,偶然中使用中空画刷,这才让我恍然大悟:中空HOLLOW_BRUSH就等于NULL_BRUSH,含义就是不使用画刷,也就是不做画刷填充,不填充其实就是透明,提到这边不知道各位网友是否已经想到实现子窗口透明的方法?算了,不卖关子了,听我细细道来:首先窗口以及窗口上的子控件绘制成什么样的背景是通过什么方法告知窗口的,这里提的字很关键, 是告知不是让你代码实现,对!就是通过OnCtlColor的返回值来告知父窗口到底将本窗口或本窗口子控件背景默认绘制成啥颜色,置于具体是返回本窗口还是本窗口子控件是通过OnCtlColor的参数UINT nCtlColor类型指定的,当为CTLCOLOR_DLG时就是指定窗口的背景色,当是CTLCOLOR_EDIT时告知编辑框的背景色,CTLCOLOR_BUTTON告知按钮默认的背景色...

通过以上指点分析,我们只要截获ON_WM_CTLCOLOR消息,然后在该处理函数不论是什么类型都返回空画刷也就是return (HBRUSH)GetStockObject(HOLLOW_BRUSH);即可,这时候该窗口就透明了【该窗口指定为其他窗口的子窗口后,则子窗口也透明】,如果还想再该透明子窗口上划线、画矩形等实现OnLbuttonDown、OnLbuttonup和OnMouseMove消息函数,在OnEraseBkGround处理函数中绘制即可!

 

你可能感兴趣的:(VC++)