Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1300045
  • 博文数量: 548
  • 博客积分: 7597
  • 博客等级: 少将
  • 技术积分: 4224
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-15 13:21
个人简介

嵌入式软件工程师&&太极拳

文章分类

全部博文(548)

文章存档

2014年(10)

2013年(76)

2012年(175)

2011年(287)

分类: LINUX

2011-03-02 21:15:19

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

以下是头文件和实现文件:
view plaincopy to clipboardprint?
//qtwin.h  
#ifndef QTWIN_H  
#define QTWIN_H  
#include   
#include   
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   
#include   
#include   
#include   
#include   
#ifdef Q_WS_WIN  
#include   
// 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   
#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();  

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/huihui1988/archive/2010/05/17/5601497.aspx
阅读(1321) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~