透明窗体 使用DWM实现Aero Glass效果

从Windows Vista开始,Aero Glass效果被应用在了Home Premium以上的系统中(Home Basic不具有该效果)。这种效果是由DWM(Desktop Window Manager)来控制的。对于一般的程序,缺省将在窗口边框应用这种效果。但如果我们想要更多的控制,比如让客户区的一部分也呈现这种效果,那也非常的简单。不需要我们在程序里做任何复杂的算法,我们只需要调API,交给DWM去做就可以了。

 

 

一、Composition(窗口合成) and Non-client Rendering(非客户区渲染)

 

       非客户区通常包括窗口标题栏和窗口边框。缺省状态下,非客户区会被渲染成毛玻璃效果,这也称为Compostion。有几个函数可以控制系统和当前窗口的渲染方式。同时也有Windows消息用于接受渲染模式的改变。

 

       1.检测系统是否开启Aero Glass。使用 函数 DwmIsCompositionEnabled 检测系统当前是否开启了Aero Glass特效。它接受一个BOOL参数,并将当前状态存储到其中。函数原型: HRESULT DwmIsCompositionEnabled(BOOL *pfEnabled );

 

       2.开启/关闭Aero Glass。使用函数DwmEnableComposition 开启或关闭系统Aero Glass效果,传入DWM_EC_ENABLECOMPOSITION 开启,传入DWM_EC_DISABLECOMPOSITION 关闭。

 

       3.开启/关闭当前窗口的非客户区渲染。函数DwmSetWindowAttribute 用于设置窗口属性,属性DWMWA_NCRENDERING_POLICY 控制当前窗口是否使用非客户区渲染。DWMNCRP_ENABLED 开启,DWMNCRP_DISABLED 关闭。当系统的Aero Glass关闭时,设置无效。与之对应,使用函数DwmGetWindowAttribute 可以检测当前窗口属性。

 

       4.响应系统Aero Glass的开启或关闭。当Aero Glass被开启或关闭时,Windows会发送消息WM_DWMCOMPOSITIONCHANGED 使用 函数 DwmIsCompositionEnabled 检测状态。

 

       5.响应窗口非客户区渲染的开启或关闭。当前窗口的非客户区渲染开启或关闭时,Windows会发送消息WM_DWMNCRENDERINGCHANGEDwParam 指示当前状态。

 

二、Transition(窗口动画) and ColorizationColor(主题颜色)

 

       Transition控制是否以动画方式显示窗口的最小化和还原。通过使用函数DwmSetWindowAttribute ,设置属性DWMWA_TRANSITIONS_FORCEDISABLED ,开启或关闭窗口动画。该设置只对当前窗口有效。

 

       当用户通过控制面板修改主题颜色时,Windows将发送消息WM_DWMCOLORIZATIONCOLORCHANGED ,程序中通过函数DwmGetColorizationColor 取得当前主题颜色,以及是否透明。通过响应颜色的变更,可以让程序的颜色风格随主题风格而变化。

 

三、开启客户区域Aero Glass效果

 

       函数DwmEnableBlurBehindWindow 开启客户区的Aero Glass效果,第一个参数为窗口句柄,第二个参数为一个DWM_BLURBEHIND 结构。其中fEnable 设置是否开启客户区Glass效果。hRgnBlur 设置Glass效果的区域,该项设置为NULL将使整个客户区呈现Glass效果,设置为一个正确的区域后,该区域将呈现Glass效果, 而区域以外为完全透明。要呈现透明效果需要客户区原始的颜色为黑色,可以在WM_PAINT 消息中绘制客户区,下面的代码使用GDI+,在Aero Glass开启时将整个窗口绘制为黑色,Aero Glass关闭时绘制为灰色:

 

01.case WM_PAINT:  
02.    {  
03.        PAINTSTRUCT ps;  
04.        HDC hDC = BeginPaint(hWnd, &ps);  
05.        //不要直接使用窗口句柄创建Graphics,会导致闪烁   
06.        Graphics graph(hDC);  
07.        //清除客户区域   
08.        RECT rcClient;  
09.        GetClientRect(hWnd, &rcClient);  
10.        BOOL bCompEnabled;  
11.        DwmIsCompositionEnabled(&bCompEnabled);  
12.        SolidBrush br(bCompEnabled? Color::Black : Color::DarkGray);  
13.        graph.FillRectangle(&br, Rect(rcClient.left, rcClient.top,   
14.            rcClient.right, rcClient.bottom));  
15.        EndPaint(hWnd, &ps);  
16.    }  
17.    break;  
View Code

 

 

 

posted @ 2014-03-16 01:36  人走茶凉物是人非  阅读(322)  评论(0)    收藏  举报