zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    权限管理
    Linux常用命令
    SSM的开发步骤分析
    03每日课后作业面试题汇总
    Redis常用命令
    大觅网07day
    消息队列面试题
    bzoj 3745: [Coci2015]Norma
    Codeforces 343E Pumping Stations
    UOJ #236. 【IOI2016】railroad
  • 原文地址:https://www.cnblogs.com/findumars/p/4973163.html
Copyright © 2011-2022 走看看