source: tspsg-svn/trunk/src/qtwin.cpp @ 109

Last change on this file since 109 was 96, checked in by laleppa, 15 years ago
  • Fixed some wrong defines that prevented successful compilation under *nix.
  • Renamed i18n to l10n to follow common standards.
  • Translation and documentation paths are now synchronized between .pro and source.
  • Moved some versioning information to .pro file.
  • Updated translations.
  • Property svn:keywords set to Id URL
File size: 6.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4**
5** Use, modification and distribution is allowed without limitation,
6** warranty, liability or support of any kind.
7**
8****************************************************************************/
9
10#include "qtwin.h"
11#include <QLibrary>
12#include <QApplication>
13#include <QWidget>
14#include <QList>
15#include <QPointer>
16
17#ifdef Q_WS_WIN
18
19#include <qt_windows.h>
20
21// Blur behind data structures
22#define DWM_BB_ENABLE                 0x00000001  // fEnable has been specified
23#define DWM_BB_BLURREGION             0x00000002  // hRgnBlur has been specified
24#define DWM_BB_TRANSITIONONMAXIMIZED  0x00000004  // fTransitionOnMaximized has been specified
25#define WM_DWMCOMPOSITIONCHANGED        0x031E    // Composition changed window message
26
27typedef struct _DWM_BLURBEHIND
28{
29    DWORD dwFlags;
30    BOOL fEnable;
31    HRGN hRgnBlur;
32    BOOL fTransitionOnMaximized;
33} DWM_BLURBEHIND, *PDWM_BLURBEHIND;
34
35typedef struct _MARGINS
36{
37    int cxLeftWidth;
38    int cxRightWidth;
39    int cyTopHeight;
40    int cyBottomHeight;
41} MARGINS, *PMARGINS;
42
43typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL* pfEnabled);
44typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS* pMarInset);
45typedef HRESULT (WINAPI *PtrDwmEnableBlurBehindWindow)(HWND hWnd, const DWM_BLURBEHIND* pBlurBehind);
46typedef HRESULT (WINAPI *PtrDwmGetColorizationColor)(DWORD *pcrColorization, BOOL *pfOpaqueBlend);
47
48static PtrDwmIsCompositionEnabled pDwmIsCompositionEnabled= 0;
49static PtrDwmEnableBlurBehindWindow pDwmEnableBlurBehindWindow = 0;
50static PtrDwmExtendFrameIntoClientArea pDwmExtendFrameIntoClientArea = 0;
51static PtrDwmGetColorizationColor pDwmGetColorizationColor = 0;
52
53
54/*
55 * Internal helper class that notifies windows if the
56 * DWM compositing state changes and updates the widget
57 * flags correspondingly.
58 */
59class WindowNotifier : public QWidget
60{
61public:
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
67private:
68    QWidgetList widgets;
69};
70
71static bool resolveLibs()
72{
73    if (!pDwmIsCompositionEnabled) {
74        QLibrary dwmLib(QString::fromAscii("dwmapi"));
75        pDwmIsCompositionEnabled =(PtrDwmIsCompositionEnabled)dwmLib.resolve("DwmIsCompositionEnabled");
76        pDwmExtendFrameIntoClientArea = (PtrDwmExtendFrameIntoClientArea)dwmLib.resolve("DwmExtendFrameIntoClientArea");
77        pDwmEnableBlurBehindWindow = (PtrDwmEnableBlurBehindWindow)dwmLib.resolve("DwmEnableBlurBehindWindow");
78        pDwmGetColorizationColor = (PtrDwmGetColorizationColor)dwmLib.resolve("DwmGetColorizationColor");
79    }
80    return pDwmIsCompositionEnabled != 0;
81}
82
83#endif
84
85/*!
86  * Chekcs and returns true if Windows DWM composition
87  * is currently enabled on the system.
88  *
89  * To get live notification on the availability of
90  * this feature, you will currently have to
91  * reimplement winEvent() on your widget and listen
92  * for the WM_DWMCOMPOSITIONCHANGED event to occur.
93  *
94  */
95bool QtWin::isCompositionEnabled()
96{
97#ifdef Q_WS_WIN
98    if (resolveLibs()) {
99        HRESULT hr = S_OK;
100        BOOL isEnabled = false;
101        hr = pDwmIsCompositionEnabled(&isEnabled);
102        if (SUCCEEDED(hr))
103            return isEnabled;
104    }
105#endif
106    return false;
107}
108
109/*!
110  * Enables Blur behind on a Widget.
111  *
112  * \a enable tells if the blur should be enabled or not
113  */
114bool QtWin::enableBlurBehindWindow(QWidget *widget, bool enable)
115{
116    Q_ASSERT(widget);
117    Q_UNUSED(widget);
118    Q_UNUSED(enable);
119    bool result = false;
120#ifdef Q_WS_WIN
121    if (resolveLibs()) {
122        DWM_BLURBEHIND bb = {0};
123        HRESULT hr = S_OK;
124        bb.fEnable = enable;
125        bb.dwFlags = DWM_BB_ENABLE;
126        bb.hRgnBlur = NULL;
127        widget->setAttribute(Qt::WA_TranslucentBackground, enable);
128        widget->setAttribute(Qt::WA_NoSystemBackground, enable);
129        hr = pDwmEnableBlurBehindWindow(widget->winId(), &bb);
130        if (SUCCEEDED(hr)) {
131            result = true;
132            windowNotifier()->addWidget(widget);
133        }
134    }
135#endif
136    return result;
137}
138
139/*!
140  * ExtendFrameIntoClientArea.
141  *
142  * This controls the rendering of the frame inside the window.
143  * Note that passing margins of -1 (the default value) will completely
144  * remove the frame from the window.
145  *
146  * \note you should not call enableBlurBehindWindow before calling
147  *       this functions
148  *
149  * \a enable tells if the blur should be enabled or not
150  */
151bool QtWin::extendFrameIntoClientArea(QWidget *widget, int left, int top, int right, int bottom)
152{
153
154    Q_ASSERT(widget);
155    Q_UNUSED(widget);
156    Q_UNUSED(left);
157    Q_UNUSED(top);
158    Q_UNUSED(right);
159    Q_UNUSED(bottom);
160
161    bool result = false;
162#ifdef Q_WS_WIN
163    if (resolveLibs()) {
164        QLibrary dwmLib(QString::fromAscii("dwmapi"));
165        HRESULT hr = S_OK;
166        MARGINS m = {left, top, right, bottom};
167        hr = pDwmExtendFrameIntoClientArea(widget->winId(), &m);
168        if (SUCCEEDED(hr)) {
169            result = true;
170            windowNotifier()->addWidget(widget);
171        }
172        widget->setAttribute(Qt::WA_TranslucentBackground, result);
173    }
174#endif
175    return result;
176}
177
178/*!
179  * Returns the current colorizationColor for the window.
180  *
181  * \a enable tells if the blur should be enabled or not
182  */
183QColor QtWin::colorizatinColor()
184{
185    QColor resultColor = QApplication::palette().window().color();
186
187#ifdef Q_WS_WIN
188    if (resolveLibs()) {
189        DWORD color = 0;
190        BOOL opaque = FALSE;
191        QLibrary dwmLib(QString::fromAscii("dwmapi"));
192        HRESULT hr = S_OK;
193        hr = pDwmGetColorizationColor(&color, &opaque);
194        if (SUCCEEDED(hr))
195            resultColor = QColor(color);
196    }
197#endif
198    return resultColor;
199}
200
201#ifdef Q_WS_WIN
202WindowNotifier *QtWin::windowNotifier()
203{
204    static WindowNotifier *windowNotifierInstance = 0;
205    if (!windowNotifierInstance)
206        windowNotifierInstance = new WindowNotifier;
207    return windowNotifierInstance;
208}
209
210
211/* Notify all enabled windows that the DWM state changed */
212bool WindowNotifier::winEvent(MSG *message, long *result)
213{
214    if (message && message->message == WM_DWMCOMPOSITIONCHANGED) {
215        bool compositionEnabled = QtWin::isCompositionEnabled();
216        foreach(QWidget * widget, widgets) {
217            if (widget) {
218                widget->setAttribute(Qt::WA_NoSystemBackground, compositionEnabled);
219            }
220            widget->update();
221        }
222    }
223    return QWidget::winEvent(message, result);
224}
225#endif
Note: See TracBrowser for help on using the repository browser.