Qt制作Aero特效窗口

转载请注明链接与作者huihui1988

初学QT,边看书边自己做点小东西。最近突然心血来潮,想自己做个小巧点的,界面美观一点的备忘当桌面上。想了半天,发现VISTA/WIN7的Aero效果就不错,况且自己现在就在用WIN7。于是上网找了下QT制作Aero效果的方法。Google之后终于找到了函数和用法。于是做了一个简单的Aero特效窗口

以下是头文件和实现文件:
//qtwin.h #ifndef QTWIN_H #define QTWIN_H #include <QColor> #include <QWidget> class WindowNotifier; class QtWin { public: static bool enableAeroWindow(QWidget *widget, bool enable = true); static bool extendFrameIntoClientArea(QWidget *widget, int left = -1, int top = -1, int right = -1, int bottom = -1); static bool isCompositionEnabled(); static QColor colorizatinColor(); private: static WindowNotifier *windowNotifier(); }; #endif // QTWIN_H //qtwin.cpp #include "qtwin.h" #include <QLibrary> #include <QApplication> #include <QWidget> #include <QList> #include <QPointer> #ifdef Q_WS_WIN #include <qt_windows.h> // Blur behind data structures #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 #define WM_DWMCOMPOSITIONCHANGED 0x031E // Composition changed window message typedef struct _DWM_BLURBEHIND { DWORD dwFlags; BOOL fEnable; HRGN hRgnBlur; BOOL fTransitionOnMaximized; } DWM_BLURBEHIND, *PDWM_BLURBEHIND; typedef struct _MARGINS { int cxLeftWidth; int cxRightWidth; int cyTopHeight; int cyBottomHeight; } MARGINS, *PMARGINS; typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL* pfEnabled); typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS* pMarInset); typedef HRESULT (WINAPI *PtrDwmenableAeroWindow)(HWND hWnd, const DWM_BLURBEHIND* pBlurBehind); typedef HRESULT (WINAPI *PtrDwmGetColorizationColor)(DWORD *pcrColorization, BOOL *pfOpaqueBlend); static PtrDwmIsCompositionEnabled pDwmIsCompositionEnabled= 0; static PtrDwmenableAeroWindow pDwmenableAeroWindow = 0; static PtrDwmExtendFrameIntoClientArea pDwmExtendFrameIntoClientArea = 0; static PtrDwmGetColorizationColor pDwmGetColorizationColor = 0; /* *同步响应DWM状态消息 */ class WindowNotifier : public QWidget { public: WindowNotifier() { winId(); } void addWidget(QWidget *widget) { widgets.append(widget); } void removeWidget(QWidget *widget) { widgets.removeAll(widget); } bool winEvent(MSG *message, long *result); private: QWidgetList widgets; }; static bool resolveLibs() { if (!pDwmIsCompositionEnabled) { QLibrary dwmLib(QString::fromAscii("dwmapi")); pDwmIsCompositionEnabled =(PtrDwmIsCompositionEnabled)dwmLib.resolve("DwmIsCompositionEnabled"); pDwmExtendFrameIntoClientArea = (PtrDwmExtendFrameIntoClientArea)dwmLib.resolve("DwmExtendFrameIntoClientArea"); pDwmenableAeroWindow = (PtrDwmenableAeroWindow)dwmLib.resolve("DwmenableAeroWindow"); pDwmGetColorizationColor = (PtrDwmGetColorizationColor)dwmLib.resolve("DwmGetColorizationColor"); } return pDwmIsCompositionEnabled != 0; } #endif /*! * 检查 DWM 是否开启 * */ bool QtWin::isCompositionEnabled() { #ifdef Q_WS_WIN if (resolveLibs()) { HRESULT hr = S_OK; BOOL isEnabled = false; hr = pDwmIsCompositionEnabled(&isEnabled); if (SUCCEEDED(hr)) return isEnabled; } #endif return false; } /*! * 对一个widget实现Aero效果. * */ bool QtWin::enableAeroWindow(QWidget *widget, bool enable) { Q_ASSERT(widget); bool result = false; #ifdef Q_WS_WIN if (resolveLibs()) { DWM_BLURBEHIND bb = {0}; HRESULT hr = S_OK; bb.fEnable = enable; bb.dwFlags = DWM_BB_ENABLE; bb.hRgnBlur = NULL; widget->setAttribute(Qt::WA_TranslucentBackground, enable); widget->setAttribute(Qt::WA_NoSystemBackground, enable); hr = pDwmenableAeroWindow(widget->winId(), &bb); if (SUCCEEDED(hr)) { result = true; windowNotifier()->addWidget(widget); } } #endif return result; } /*! * 设置Aero绘图区 */ bool QtWin::extendFrameIntoClientArea(QWidget *widget, int left, int top, int right, int bottom) { Q_ASSERT(widget); Q_UNUSED(left); Q_UNUSED(top); Q_UNUSED(right); Q_UNUSED(bottom); bool result = false; #ifdef Q_WS_WIN if (resolveLibs()) { QLibrary dwmLib(QString::fromAscii("dwmapi")); HRESULT hr = S_OK; MARGINS m = {left, top, right, bottom}; hr = pDwmExtendFrameIntoClientArea(widget->winId(), &m); if (SUCCEEDED(hr)) { result = true; windowNotifier()->addWidget(widget); } widget->setAttribute(Qt::WA_TranslucentBackground, result); } #endif return result; } /*! * 返回当前窗口颜色. */ QColor QtWin::colorizatinColor() { QColor resultColor = QApplication::palette().window().color(); #ifdef Q_WS_WIN if (resolveLibs()) { DWORD color = 0; BOOL opaque = FALSE; QLibrary dwmLib(QString::fromAscii("dwmapi")); HRESULT hr = S_OK; hr = pDwmGetColorizationColor(&color, &opaque); if (SUCCEEDED(hr)) resultColor = QColor(color); } #endif return resultColor; } #ifdef Q_WS_WIN WindowNotifier *QtWin::windowNotifier() { static WindowNotifier *windowNotifierInstance = 0; if (!windowNotifierInstance) windowNotifierInstance = new WindowNotifier; return windowNotifierInstance; } /* 所有窗口响应 DWM 状态变换消息 */ bool WindowNotifier::winEvent(MSG *message, long *result) { if (message && message->message == WM_DWMCOMPOSITIONCHANGED) { bool compositionEnabled = QtWin::isCompositionEnabled(); foreach(QWidget * widget, widgets) { if (widget) { widget->setAttribute(Qt::WA_NoSystemBackground, compositionEnabled); } widget->update(); } } return QWidget::winEvent(message, result); } #endif 使用的时候只需要在生成窗口的main.cpp中#include "qtwin.h",并使用相关函数,以下是main.cpp文件: #include <QtGui/QApplication> #include "widget.h" #include "qtwin.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget window; window.setGeometry(1040,0,240,120); window.setWindowFlags(Qt::CustomizeWindowHint); #ifdef Q_WS_X11 window.setAttribute(Qt::WA_TranslucentBackground); window.setAttribute(Qt::WA_NoSystemBackground, false); QPalette pal = window.palette(); QColor bg = pal.window().color(); bg.setAlpha(180); pal.setColor(QPalette::Window, bg); window.setPalette(pal); window.ensurePolished(); // workaround Oxygen filling the background window.setAttribute(Qt::WA_StyledBackground, false); #endif if (QtWin::isCompositionEnabled()) { QtWin::extendFrameIntoClientArea(&window); window.setContentsMargins(0, 0, 0, 0); } window.show(); return a.exec(); }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值