前言
接触QT都挺多年了,今天开始打算把这几年攒下的QT资源记录下来,留个存档吧。今天记录的是windows下(只有win vista|win7支持)的玻璃磨砂效果封装处理,记得最开始接触这个效果的时候还是上学时期,当时只会MFC O__O "…
开始
封装类中使用到三个系统函数DwmIsCompositionEnabled、DwmEnableBlurBehindWindow、DwmExtendFrameIntoClientArea,这三个系统函数度娘都有很多说明【可以参考这里】,我这里简单说下:
- DwmIsCompositionEnabled:判断是否兼容DWM模式,返回TRUE,表示支持玻璃磨砂效果,否则为不支持;
- DwmEnableBlurBehindWindow:开启或关闭指定区域的玻璃磨砂效果;
- DwmExtendFrameIntoClientArea:窗口边框向客户区扩展的玻璃磨砂效果;
封装类中使用动态加载方式来引用这3个系统库Dwmapi.dll,因为使用这个封装类的程序可能要跑在XP系统中,而XP中是没有Dwmapi.dll这个系统库的。
源码
QOwnAeroClass.h
#ifndef QOWNAEROCLASS_H
#define QOWNAEROCLASS_H
#include<windows.h>
#include<QLibrary>
#include<QRect>
#ifndef DWM_BB_ENABLE
//*****************用于XP下的结构定义************
#define DWM_BB_ENABLE 0x00000001 // fEnable has been specified
#define DWM_BB_BLURREGION 0x00000002 // hRgnBlur has been specified
#define DWM_BB_TRANSITIONONMAXIMIZED 0x00000004 // fTransitionOnMaximized has been specified
typedef struct _DWM_BLURBEHIND
{
DWORD dwFlags;
BOOL fEnable;
HRGN hRgnBlur;
BOOL fTransitionOnMaximized;
} DWM_BLURBEHIND, *PDWM_BLURBEHIND;
#endif
typedef struct _MARGINS
{
int cxLeftWidth; // width of left border that retains its size
int cxRightWidth; // width of right border that retains its size
int cyTopHeight; // height of top border that retains its size
int cyBottomHeight; // height of bottom border that retains its size
} MARGINS, *PMARGINS;
typedef HRESULT (WINAPI* MyDwmIsCompositionEnabled)(BOOL *pBEnable);
typedef HRESULT (WINAPI* MyDwmExtendFrameIntoClientArea)(HWND hWnd,const MARGINS *pMargins);
typedef HRESULT (WINAPI* MyDwmEnableBlurBehindWindow)(HWND hWnd,const DWM_BLURBEHIND *pDWM_bulr);
class QOwnAeroClass
{
private:
QOwnAeroClass(void);
~QOwnAeroClass(void);
enum SysType
{
UNKNOW=0,
WINME,
WIN98,
WIN2K,
WINXP,
VISTA,
WIN7,
};
public:
//返回是否具有透明效果
static bool IsCompositionEnabled();
//取消透明效果
static bool cancelAeroStyle(HWND hWnd);
//设置全局透明效果
static bool setAeroStyle(HWND hWnd,bool bFrame=true,int nPadding = 6, QRect* pNewRect = NULL);
//获取系统版本信息
static SysType getSysVersion();
//DWM接口
static MyDwmIsCompositionEnabled m_MyDwmIsCompositionEnabledFun;
static MyDwmExtendFrameIntoClientArea m_MyDwmExtendFrameIntoClientAreaFun;
static MyDwmEnableBlurBehindWindow m_MyDwmEnableBlurBehindWindowFun;
//初始化DWM接口
static bool InitDwmPort();
//接口dll
static QLibrary m_DwnLib;
private:
};
#endif // QOWNAEROCLASS_H
QOwnAeroClass.cpp
#include "QOwnAeroClass.h"
#include <QDebug>
MyDwmIsCompositionEnabled QOwnAeroClass::m_MyDwmIsCompositionEnabledFun=NULL;
MyDwmExtendFrameIntoClientArea QOwnAeroClass::m_MyDwmExtendFrameIntoClientAreaFun=NULL;
MyDwmEnableBlurBehindWindow QOwnAeroClass::m_MyDwmEnableBlurBehindWindowFun=NULL;
QLibrary QOwnAeroClass::m_DwnLib;
QOwnAeroClass::QOwnAeroClass(void)
{
}
QOwnAeroClass::~QOwnAeroClass(void)
{
}
//初始化DWM接口,Theme接口
bool QOwnAeroClass::InitDwmPort()
{
m_MyDwmEnableBlurBehindWindowFun = NULL;
m_MyDwmExtendFrameIntoClientAreaFun = NULL;
m_MyDwmIsCompositionEnabledFun = NULL;
if(m_DwnLib.isLoaded())
{
m_DwnLib.unload();
}
m_DwnLib.setFileName("Dwmapi.dll");
if(!m_DwnLib.load())
return false;
m_MyDwmIsCompositionEnabledFun = (MyDwmIsCompositionEnabled)m_DwnLib.resolve("DwmIsCompositionEnabled");
m_MyDwmExtendFrameIntoClientAreaFun = (MyDwmExtendFrameIntoClientArea)m_DwnLib.resolve("DwmExtendFrameIntoClientArea");
m_MyDwmEnableBlurBehindWindowFun = (MyDwmEnableBlurBehindWindow)m_DwnLib.resolve("DwmEnableBlurBehindWindow");
if(m_MyDwmEnableBlurBehindWindowFun == NULL ||
m_MyDwmExtendFrameIntoClientAreaFun == NULL ||
m_MyDwmIsCompositionEnabledFun == NULL)
{
return false;
}
return true;
}
//返回是否具有透明效果
bool QOwnAeroClass::IsCompositionEnabled()
{
//return false;
BOOL bCompEnabled = FALSE;
SysType sysType;
sysType = getSysVersion();
if(sysType <VISTA)
return false;
if(m_MyDwmIsCompositionEnabledFun == NULL)
{
if(!InitDwmPort())
{
qDebug() << "QOwnAeroClass::IsCompositionEnabled InitDWM fail!!!!";
return false;
}
}
m_MyDwmIsCompositionEnabledFun(&bCompEnabled);
if(bCompEnabled)
{
return true;
}
else
return false;
}
//取消透明效果
bool QOwnAeroClass::cancelAeroStyle(HWND hWnd)
{
if(::IsWindow(hWnd))
{
SysType sysType;
sysType = getSysVersion();
if(sysType < VISTA)
return false;
if(m_MyDwmExtendFrameIntoClientAreaFun == NULL
|| m_MyDwmEnableBlurBehindWindowFun == NULL)
{
if(!InitDwmPort())
{
qDebug() << "QOwnAeroClass::cancelAeroStyle InitDWM fail!!!!";
return false;
}
}
MARGINS margins = {0}; //将取消
m_MyDwmExtendFrameIntoClientAreaFun(hWnd, &margins);
//
DWM_BLURBEHIND bb = {0};
bb.dwFlags = DWM_BB_ENABLE /*| DWM_BB_BLURREGION*/;
bb.fEnable = false;
bb.hRgnBlur = NULL;
m_MyDwmEnableBlurBehindWindowFun(hWnd, &bb);
return true;
}
return false;
}
//设置全局透明效果
bool QOwnAeroClass::setAeroStyle(HWND hWnd,bool bFrame,int nPadding, QRect* pNewRect)
{
if(!::IsWindow(hWnd))
return false;
SysType sysType;
sysType = getSysVersion();
if(sysType <VISTA)
return false;
//先取消在设置
cancelAeroStyle(hWnd);
//全屏效果
if(bFrame)
{
if(m_MyDwmExtendFrameIntoClientAreaFun == NULL)
{
if(!InitDwmPort())
{
qDebug() << "QOwnAeroClass::setAeroStyle InitDWM fail!!!!";
return false;
}
}
MARGINS margins = {-1}; //将效果
m_MyDwmExtendFrameIntoClientAreaFun(hWnd, &margins);
}
//局部效果
else
{
DWM_BLURBEHIND blurBehind = { 0 };
blurBehind.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
blurBehind.fEnable = true;
//blurBehind.fTransitionOnMaximized = TRUE;
RECT winRect,NewRect;
::GetWindowRect(hWnd,&winRect);
if(pNewRect != NULL)
{
NewRect.top = nPadding;
NewRect.left = nPadding;
NewRect.bottom = pNewRect->height()-nPadding;
NewRect.right = pNewRect->width()-nPadding;
}
else{
NewRect.top = nPadding;
NewRect.left = nPadding;
NewRect.bottom = (winRect.bottom - winRect.top)-nPadding;
NewRect.right = (winRect.right - winRect.left)-nPadding;
}
/*winRect.left += 6;
winRect.top += 6;
winRect.bottom -= 6;
winRect.right -= 6;*/
HRGN hRgn = ::CreateRectRgn(NewRect.left,NewRect.top,NewRect.right,NewRect.bottom);
blurBehind.hRgnBlur = hRgn;
m_MyDwmEnableBlurBehindWindowFun(hWnd,
&blurBehind);
}
return true;
}
//获取系统版本信息
QOwnAeroClass::SysType QOwnAeroClass::getSysVersion()
{
OSVERSIONINFO Version;
ZeroMemory(&Version,sizeof(OSVERSIONINFO));
Version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&Version);
if (Version.dwPlatformId==VER_PLATFORM_WIN32_NT)
{
if((Version.dwMajorVersion==5)&&(Version.dwMinorVersion==0))
{
return WIN2K;
}else if((Version.dwMajorVersion==5)&&(Version.dwMinorVersion>0))
{
return WINXP;
}else if((Version.dwMajorVersion==6)&&(Version.dwMinorVersion==0))
return VISTA;
else if((Version.dwMajorVersion>=6))
return WIN7;
}
else if(Version.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
{
if ((Version.dwMajorVersion == 4) && (Version.dwMinorVersion < 90) )
{
return WIN98;
}
if ((Version.dwMajorVersion == 4) && (Version.dwMinorVersion >= 90) )
{
return WINME;
}
}
return UNKNOW;
}