QT-磨砂玻璃效果实现

QT-磨砂玻璃效果实现

前言

接触QT都挺多年了,今天开始打算把这几年攒下的QT资源记录下来,留个存档吧。今天记录的是windows下(只有win vista|win7支持)的玻璃磨砂效果封装处理,记得最开始接触这个效果的时候还是上学时期,当时只会MFC O__O "…

开始

封装类中使用到三个系统函数DwmIsCompositionEnabledDwmEnableBlurBehindWindowDwmExtendFrameIntoClientArea,这三个系统函数度娘都有很多说明【可以参考这里】,我这里简单说下:

  1. DwmIsCompositionEnabled:判断是否兼容DWM模式,返回TRUE,表示支持玻璃磨砂效果,否则为不支持;
  2. DwmEnableBlurBehindWindow:开启或关闭指定区域的玻璃磨砂效果;
  3. 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;
}
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值