-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DWM: Desktop Window Manager #13
Comments
窗口玻璃特效,半透明窗口,使用DWM实现Aero Glass效果从Windows Vista开始,Aero Glass效果被应用在了Home Premium以上的系统中(Home Basic不具有该效果)。这种效果是由DWM(Desktop Window Manager)来控制的。对于一般的程序,缺省将在窗口边框应用这种效果。但如果我们想要更多的控制,比如让客户区的一部分也呈现这种效果,那也非常的简单。不需要我们在程序里做任何复杂的算法,我们只需要调API,交给DWM去做就可以了。 一、Composition(窗口合成) and Non-client Rendering(非客户区渲染)非客户区通常包括窗口标题栏和窗口边框。缺省状态下,非客户区会被渲染成毛玻璃效果,这也称为Compostion。有几个函数可以控制系统和当前窗口的渲染方式。同时也有Windows消息用于接受渲染模式的改变。
二、Transition(窗口动画) and ColorizationColor(主题颜色)Transition控制是否以动画方式显示窗口的最小化和还原。通过使用函数DwmSetWindowAttribute ,设置属性DWMWA_TRANSITIONS_FORCEDISABLED ,开启或关闭窗口动画。该设置只对当前窗口有效。
三、开启客户区域Aero Glass效果函数DwmEnableBlurBehindWindow 开启客户区的Aero Glass效果,第一个参数为窗口句柄,第二个参数为一个DWM_BLURBEHIND 结构。其中fEnable 设置是否开启客户区Glass效果。hRgnBlur 设置Glass效果的区域,该项设置为NULL将使整个客户区呈现Glass效果,设置为一个正确的区域后,该区域将呈现Glass效果, 而区域以外为完全透明。要呈现透明效果需要客户区原始的颜色为黑色,可以在WM_PAINT 消息中绘制客户区,下面的代码使用GDI+,在Aero Glass开启时将整个窗口绘制为黑色,Aero Glass关闭时绘制为灰色:
GDI+的初始化和关闭仍然是必须的:
下面代码将整个客户区设置为Glass效果:
下面代码将客户区中心一个椭圆的区域设置为Glass效果:
四、窗口边框向客户区扩展上面的方式中,非客户区和客户区之间仍然有界限。如何增大Glass效果的范围,并且消除界限呢?那就是使窗口边框向客户区扩展,利用函数DwmExtendFrameIntoClientArea 实现。函数接受一个窗口句柄和一个MARGINS 类型的参数。MARGINS指定了在上下左右4个方向上扩展的范围。如果4个值均为-1,则扩展到整个客户区
五、在窗口上绘制图形PNG图片带有alpha通道,可以与Aero Glass很好的配合。利用GDI+显示PNG图片非常方便,下面的代码将一张PNG图片加载到内存中:
在WM_PAINT消息处理中,将整个客户区绘制为黑色以后,利用GDI+将图片绘制到窗口客户区:
六、文本的绘制当窗口大范围的透明之后,窗口上的文字的阅读成了一个问题。Windows的解决办法是为文字加上发光效果(Glowing),标题栏的文本使用的就是这种方式。我们在自己的程序中可以使用DrawThemeTextEx 函数来绘制发光的文字。该函数的原型定义如下:
hTheme是一个主题句柄,可以使用OpenThemeData 获得, OpenThemeData 函数接受一个窗口句柄,和主题类的名称。iPartId和iStateId分别代表主题类中的Part和State,所有可用的主题类、Part和state在SDK的帮助文档中可以查看到。pszText是要绘制的文本。iCharCount为文字个数,-1代表绘制全部文本。dwFlags指定文本格式。pRect为文本绘制区域。pOptions中可以设定文本的发光、阴影等效果。HDC是一个设备上下文句柄,为了实现类似于标题栏中文本的发光效果,这里不能使用由BeginPaint 得到的句柄,而是要使用CreateCompatibleDC 创建一个内存中的句柄,并且要创建一张位图,通过内存句柄将文本绘制到位图上。然后再将位图转移到窗口上。下面的函数封装了绘制发光文本的过程:
在绘制了图形后,加入下面代码绘制一段文本:
因为字体发光的缘故,在文本左侧留下一个空格看起来会舒服一些。 七、缩略图关联DWM API中还有一个功能,即缩略图关联。它允许我们将一个窗口的缩略图显示到自己窗口的客户区。缩略图不同于截图,它是实时更新的。下面的代码将在窗口客户区显示QQ影音播放器的缩略图:
首先通过窗口标题查找到源窗口句柄,然后使用DwmRegisterThumbnail 注册缩略图关联,注册成功后,通过DwmUpdateThumbnailProperties 更新缩略图属性,其中设定了是否可视、透明度以及目标绘制区域。得到下面的效果: |
从Windows Vista开始,Aero Glass效果被应用在了Home Premium以上的系统中(Home Basic不具有该效果)。这种效果是由DWM(Desktop Window Manager)来控制的。对于一般的程序,缺省将在窗口边框应用这种效果。但如果我们想要更多的控制,比如让客户区的一部分也呈现这种效果,那也非常的简单。不需要我们在程序里做任何复杂的算法,我们只需要调API,交给DWM去做就可以了。
DWM相关操作的MSDN说明:Desktop Window Manager (DWM) APIs.
http://msdn.microsoft.com/en-us/library/aa969527(v=VS.85).aspx
Header Dwmapi.h
Library Dwmapi.lib
DLL Dwmapi.dll
一、Composition(窗口合成) and Non-client Rendering(非客户区渲染)
非客户区通常包括窗口标题栏和窗口边框。缺省状态下,非客户区会被渲染成毛玻璃效果,这也称为Compostion。有几个函数可以控制系统和当前窗口的渲染方式。同时也有Windows消息用于接受渲染模式的改变。
二、Transition(窗口动画) and ColorizationColor(主题颜色)
Transition控制是否以动画方式显示窗口的最小化和还原。通过使用函数DwmSetWindowAttribute,设置属性DWMWA_TRANSITIONS_FORCEDISABLED,开启或关闭窗口动画。该设置只对当前窗口有效。
三、开启客户区域Aero Glass效果
函数DwmEnableBlurBehindWindow开启客户区的Aero Glass效果,第一个参数为窗口句柄,第二个参数为一个DWM_BLURBEHIND结构。其中fEnable设置是否开启客户区Glass效果。hRgnBlur设置Glass效果的区域,该项设置为NULL将使整个客户区呈现Glass效果,设置为一个正确的区域后,该区域将呈现Glass效果, 而区域以外为完全透明。要呈现透明效果需要客户区原始的颜色为黑色,可以在WM_PAINT消息中绘制客户区,下面的代码使用GDI+,在Aero Glass开启时将整个窗口绘制为黑色,Aero Glass关闭时绘制为灰色:
GDI+的初始化和关闭仍然是必须的:
下面代码将整个客户区设置为Glass效果:
下面代码将客户区中心一个椭圆的区域设置为Glass效果:
四、窗口边框向客户区扩展
上面的方式中,非客户区和客户区之间仍然有界限。如何增大Glass效果的范围,并且消除界限呢?那就是使窗口边框向客户区扩展,利用函数DwmExtendFrameIntoClientArea实现。函数接受一个窗口句柄和一个MARGINS类型的参数。MARGINS指定了在上下左右4个方向上扩展的范围。如果4个值均为-1,则扩展到整个客户区。
五、在窗口上绘制图形
PNG图片带有alpha通道,可以与Aero Glass很好的配合。利用GDI+显示PNG图片非常方便,下面的代码将一张PNG图片加载到内存中:
在WM_PAINT消息处理中,将整个客户区绘制为黑色以后,利用GDI+将图片绘制到窗口客户区:
六、文本的绘制
当窗口大范围的透明之后,窗口上的文字的阅读成了一个问题。Windows的解决办法是为文字加上发光效果(Glowing),标题栏的文本使用的就是这种方式。我们在自己的程序中可以使用DrawThemeTextEx函数来绘制发光的文字。该函数的原型定义如下:
hTheme是一个主题句柄,可以使用OpenThemeData获得,OpenThemeData函数接受一个窗口句柄,和主题类的名称。iPartId和iStateId分别代表主题类中的Part和State,所有可用的主题类、Part和state在SDK的帮助文档中可以查看到。pszText是要绘制的文本。iCharCount为文字个数,-1代表绘制全部文本。dwFlags指定文本格式。pRect为文本绘制区域。pOptions中可以设定文本的发光、阴影等效果。HDC是一个设备上下文句柄,为了实现类似于标题栏中文本的发光效果,这里不能使用由BeginPaint得到的句柄,而是要使用CreateCompatibleDC创建一个内存中的句柄,并且要创建一张位图,通过内存句柄将文本绘制到位图上。然后再将位图转移到窗口上。下面的函数封装了绘制发光文本的过程:
在绘制了图形后,加入下面代码绘制一段文本:
因为字体发光的缘故,在文本左侧留下一个空格看起来会舒服一些。效果如下:
七、缩略图关联
DWM API中还有一个功能,即缩略图关联。它允许我们将一个窗口的缩略图显示到自己窗口的客户区。缩略图不同于截图,它是实时更新的。下面的代码将在窗口客户区显示QQ影音播放器的缩略图:
首先通过窗口标题查找到源窗口句柄,然后使用DwmRegisterThumbnail注册缩略图关联,注册成功后,通过DwmUpdateThumbnailProperties更新缩略图属性,其中设定了是否可视、透明度以及目标绘制区域。得到下面的效果:
The text was updated successfully, but these errors were encountered: