Qt制作Aero特效窗口

转载请注明链接与作者huihui1988

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

 
以下是头文件和实现文件:
[cpp] view plaincopy
 
  1. //qtwin.h  
  2. #ifndef QTWIN_H  
  3. #define QTWIN_H  
  4. #include <QColor>  
  5. #include <QWidget>  
  6. class WindowNotifier;  
  7. class QtWin  
  8. {  
  9. public:  
  10.     static bool enableAeroWindow(QWidget *widget, bool enable = true);  
  11.     static bool extendFrameIntoClientArea(QWidget *widget,  
  12.                                           int left = -1, int top = -1,  
  13.                                           int right = -1, int bottom = -1);  
  14.     static bool isCompositionEnabled();  
  15.     static QColor colorizatinColor();  
  16. private:  
  17.     static WindowNotifier *windowNotifier();  
  18. };  
  19. #endif // QTWIN_H  
  20. //qtwin.cpp  
  21. #include "qtwin.h"  
  22. #include <QLibrary>  
  23. #include <QApplication>  
  24. #include <QWidget>  
  25. #include <QList>  
  26. #include <QPointer>  
  27. #ifdef Q_WS_WIN  
  28. #include <qt_windows.h>  
  29. // Blur behind data structures  
  30. #define DWM_BB_ENABLE                 0x00000001  // fEnable has been specified  
  31. #define DWM_BB_BLURREGION             0x00000002  // hRgnBlur has been specified  
  32. #define DWM_BB_TRANSITIONONMAXIMIZED  0x00000004  // fTransitionOnMaximized has been specified  
  33. #define WM_DWMCOMPOSITIONCHANGED        0x031E    // Composition changed window message  
  34. typedef struct _DWM_BLURBEHIND  
  35. {  
  36.     DWORD dwFlags;  
  37.     BOOL fEnable;  
  38.     HRGN hRgnBlur;  
  39.     BOOL fTransitionOnMaximized;  
  40. } DWM_BLURBEHIND, *PDWM_BLURBEHIND;  
  41. typedef struct _MARGINS  
  42. {  
  43.     int cxLeftWidth;  
  44.     int cxRightWidth;  
  45.     int cyTopHeight;  
  46.     int cyBottomHeight;  
  47. } MARGINS, *PMARGINS;  
  48. typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL* pfEnabled);  
  49. typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS* pMarInset);  
  50. typedef HRESULT (WINAPI *PtrDwmenableAeroWindow)(HWND hWnd, const DWM_BLURBEHIND* pBlurBehind);  
  51. typedef HRESULT (WINAPI *PtrDwmGetColorizationColor)(DWORD *pcrColorization, BOOL *pfOpaqueBlend);  
  52. static PtrDwmIsCompositionEnabled pDwmIsCompositionEnabled= 0;  
  53. static PtrDwmenableAeroWindow pDwmenableAeroWindow = 0;  
  54. static PtrDwmExtendFrameIntoClientArea pDwmExtendFrameIntoClientArea = 0;  
  55. static PtrDwmGetColorizationColor pDwmGetColorizationColor = 0;  
  56. /* 
  57.  *同步响应DWM状态消息 
  58.  */  
  59. class WindowNotifier : public QWidget  
  60. {  
  61. public:  
  62.     WindowNotifier() { winId(); }  
  63.     void addWidget(QWidget *widget) { widgets.append(widget); }  
  64.     void removeWidget(QWidget *widget) { widgets.removeAll(widget); }  
  65.     bool winEvent(MSG *message, long *result);  
  66. private:  
  67.     QWidgetList widgets;  
  68. };  
  69. static bool resolveLibs()  
  70. {  
  71.     if (!pDwmIsCompositionEnabled) {  
  72.         QLibrary dwmLib(QString::fromAscii("dwmapi"));  
  73.         pDwmIsCompositionEnabled =(PtrDwmIsCompositionEnabled)dwmLib.resolve("DwmIsCompositionEnabled");  
  74.         pDwmExtendFrameIntoClientArea = (PtrDwmExtendFrameIntoClientArea)dwmLib.resolve("DwmExtendFrameIntoClientArea");  
  75.         pDwmenableAeroWindow = (PtrDwmenableAeroWindow)dwmLib.resolve("DwmenableAeroWindow");  
  76.         pDwmGetColorizationColor = (PtrDwmGetColorizationColor)dwmLib.resolve("DwmGetColorizationColor");  
  77.     }  
  78.     return pDwmIsCompositionEnabled != 0;  
  79. }  
  80. #endif  
  81. /*! 
  82.   * 检查 DWM 是否开启 
  83.   * 
  84.   */  
  85. bool QtWin::isCompositionEnabled()  
  86. {  
  87. #ifdef Q_WS_WIN  
  88.     if (resolveLibs()) {  
  89.         HRESULT hr = S_OK;  
  90.         BOOL isEnabled = false;  
  91.         hr = pDwmIsCompositionEnabled(&isEnabled);  
  92.         if (SUCCEEDED(hr))  
  93.             return isEnabled;  
  94.     }  
  95. #endif  
  96.     return false;  
  97. }  
  98. /*! 
  99.   * 对一个widget实现Aero效果. 
  100.   * 
  101.   */  
  102. bool QtWin::enableAeroWindow(QWidget *widget, bool enable)  
  103. {  
  104.     Q_ASSERT(widget);  
  105.     bool result = false;  
  106. #ifdef Q_WS_WIN  
  107.     if (resolveLibs()) {  
  108.         DWM_BLURBEHIND bb = {0};  
  109.         HRESULT hr = S_OK;  
  110.         bb.fEnable = enable;  
  111.         bb.dwFlags = DWM_BB_ENABLE;  
  112.         bb.hRgnBlur = NULL;  
  113.         widget->setAttribute(Qt::WA_TranslucentBackground, enable);  
  114.         widget->setAttribute(Qt::WA_NoSystemBackground, enable);  
  115.         hr = pDwmenableAeroWindow(widget->winId(), &bb);  
  116.         if (SUCCEEDED(hr)) {  
  117.             result = true;  
  118.             windowNotifier()->addWidget(widget);  
  119.         }  
  120.     }  
  121. #endif  
  122.     return result;  
  123. }  
  124. /*! 
  125.   * 设置Aero绘图区 
  126.   */  
  127. bool QtWin::extendFrameIntoClientArea(QWidget *widget, int left, int top, int right, int bottom)  
  128. {  
  129.     Q_ASSERT(widget);  
  130.     Q_UNUSED(left);  
  131.     Q_UNUSED(top);  
  132.     Q_UNUSED(right);  
  133.     Q_UNUSED(bottom);  
  134.     bool result = false;  
  135. #ifdef Q_WS_WIN  
  136.     if (resolveLibs()) {  
  137.         QLibrary dwmLib(QString::fromAscii("dwmapi"));  
  138.         HRESULT hr = S_OK;  
  139.         MARGINS m = {left, top, right, bottom};  
  140.         hr = pDwmExtendFrameIntoClientArea(widget->winId(), &m);  
  141.         if (SUCCEEDED(hr)) {  
  142.             result = true;  
  143.             windowNotifier()->addWidget(widget);  
  144.         }  
  145.         widget->setAttribute(Qt::WA_TranslucentBackground, result);  
  146.     }  
  147. #endif  
  148.     return result;  
  149. }  
  150. /*! 
  151.   * 返回当前窗口颜色. 
  152.   */  
  153. QColor QtWin::colorizatinColor()  
  154. {  
  155.     QColor resultColor = QApplication::palette().window().color();  
  156. #ifdef Q_WS_WIN  
  157.     if (resolveLibs()) {  
  158.         DWORD color = 0;  
  159.         BOOL opaque = FALSE;  
  160.         QLibrary dwmLib(QString::fromAscii("dwmapi"));  
  161.         HRESULT hr = S_OK;  
  162.         hr = pDwmGetColorizationColor(&color, &opaque);  
  163.         if (SUCCEEDED(hr))  
  164.             resultColor = QColor(color);  
  165.     }  
  166. #endif  
  167.     return resultColor;  
  168. }  
  169. #ifdef Q_WS_WIN  
  170. WindowNotifier *QtWin::windowNotifier()  
  171. {  
  172.     static WindowNotifier *windowNotifierInstance = 0;  
  173.     if (!windowNotifierInstance)  
  174.         windowNotifierInstance = new WindowNotifier;  
  175.     return windowNotifierInstance;  
  176. }  
  177. /* 所有窗口响应 DWM 状态变换消息 */  
  178. bool WindowNotifier::winEvent(MSG *message, long *result)  
  179. {  
  180.     if (message && message->message == WM_DWMCOMPOSITIONCHANGED) {  
  181.         bool compositionEnabled = QtWin::isCompositionEnabled();  
  182.         foreach(QWidget * widget, widgets) {  
  183.             if (widget) {  
  184.                 widget->setAttribute(Qt::WA_NoSystemBackground, compositionEnabled);  
  185.             }  
  186.             widget->update();  
  187.         }  
  188.     }  
  189.     return QWidget::winEvent(message, result);  
  190. }  
  191. #endif  
  192. 使用的时候只需要在生成窗口的main.cpp中#include "qtwin.h",并使用相关函数,以下是main.cpp文件:  
  193. #include <QtGui/QApplication>  
  194. #include "widget.h"  
  195. #include "qtwin.h"  
  196. int main(int argc, char *argv[])  
  197. {  
  198.     QApplication a(argc, argv);  
  199.     Widget window;  
  200.     window.setGeometry(1040,0,240,120);  
  201.     window.setWindowFlags(Qt::CustomizeWindowHint);  
  202. #ifdef Q_WS_X11  
  203.     window.setAttribute(Qt::WA_TranslucentBackground);  
  204.     window.setAttribute(Qt::WA_NoSystemBackground, false);  
  205.     QPalette pal = window.palette();  
  206.     QColor bg = pal.window().color();  
  207.     bg.setAlpha(180);  
  208.     pal.setColor(QPalette::Window, bg);  
  209.     window.setPalette(pal);  
  210.     window.ensurePolished(); // workaround Oxygen filling the background  
  211.     window.setAttribute(Qt::WA_StyledBackground, false);  
  212. #endif  
  213.     if (QtWin::isCompositionEnabled()) {  
  214.         QtWin::extendFrameIntoClientArea(&window);  
  215.         window.setContentsMargins(0, 0, 0, 0);  
  216.     }  
  217.     window.show();  
  218.     return a.exec();  
  219. }  
 http://blog.csdn.net/huihui1988/article/details/5601497
posted @ 2015-11-17 23:00  findumars  Views(2372)  Comments(0Edit  收藏  举报