1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
5 ** Use, modification and distribution is allowed without limitation,
6 ** warranty, liability or support of any kind.
8 ****************************************************************************/
12 #include <QApplication>
19 #include <qt_windows.h>
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
27 typedef struct _DWM_BLURBEHIND
32 BOOL fTransitionOnMaximized;
33 } DWM_BLURBEHIND, *PDWM_BLURBEHIND;
35 typedef struct _MARGINS
43 typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL* pfEnabled);
44 typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS* pMarInset);
45 typedef HRESULT (WINAPI *PtrDwmEnableBlurBehindWindow)(HWND hWnd, const DWM_BLURBEHIND* pBlurBehind);
46 typedef HRESULT (WINAPI *PtrDwmGetColorizationColor)(DWORD *pcrColorization, BOOL *pfOpaqueBlend);
48 static PtrDwmIsCompositionEnabled pDwmIsCompositionEnabled= 0;
49 static PtrDwmEnableBlurBehindWindow pDwmEnableBlurBehindWindow = 0;
50 static PtrDwmExtendFrameIntoClientArea pDwmExtendFrameIntoClientArea = 0;
51 static PtrDwmGetColorizationColor pDwmGetColorizationColor = 0;
55 * Internal helper class that notifies windows if the
56 * DWM compositing state changes and updates the widget
57 * flags correspondingly.
59 class WindowNotifier : public QWidget
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);
71 static bool resolveLibs()
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");
80 return pDwmIsCompositionEnabled != 0;
86 * Chekcs and returns true if Windows DWM composition
87 * is currently enabled on the system.
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.
95 bool QtWin::isCompositionEnabled()
100 BOOL isEnabled = false;
101 hr = pDwmIsCompositionEnabled(&isEnabled);
110 * Enables Blur behind on a Widget.
112 * \a enable tells if the blur should be enabled or not
114 bool QtWin::enableBlurBehindWindow(QWidget *widget, bool enable)
120 DWM_BLURBEHIND bb = {0};
123 bb.dwFlags = DWM_BB_ENABLE;
125 widget->setAttribute(Qt::WA_TranslucentBackground, enable);
126 widget->setAttribute(Qt::WA_NoSystemBackground, enable);
127 hr = pDwmEnableBlurBehindWindow(widget->winId(), &bb);
130 windowNotifier()->addWidget(widget);
138 * ExtendFrameIntoClientArea.
140 * This controls the rendering of the frame inside the window.
141 * Note that passing margins of -1 (the default value) will completely
142 * remove the frame from the window.
144 * \note you should not call enableBlurBehindWindow before calling
147 * \a enable tells if the blur should be enabled or not
149 bool QtWin::extendFrameIntoClientArea(QWidget *widget, int left, int top, int right, int bottom)
161 QLibrary dwmLib(QString::fromAscii("dwmapi"));
163 MARGINS m = {left, top, right, bottom};
164 hr = pDwmExtendFrameIntoClientArea(widget->winId(), &m);
167 windowNotifier()->addWidget(widget);
169 widget->setAttribute(Qt::WA_TranslucentBackground, result);
176 * Returns the current colorizationColor for the window.
178 * \a enable tells if the blur should be enabled or not
180 QColor QtWin::colorizatinColor()
182 QColor resultColor = QApplication::palette().window().color();
188 QLibrary dwmLib(QString::fromAscii("dwmapi"));
190 hr = pDwmGetColorizationColor(&color, &opaque);
192 resultColor = QColor(color);
199 WindowNotifier *QtWin::windowNotifier()
201 static WindowNotifier *windowNotifierInstance = 0;
202 if (!windowNotifierInstance)
203 windowNotifierInstance = new WindowNotifier;
204 return windowNotifierInstance;
208 /* Notify all enabled windows that the DWM state changed */
209 bool WindowNotifier::winEvent(MSG *message, long *result)
211 if (message && message->message == WM_DWMCOMPOSITIONCHANGED) {
212 bool compositionEnabled = QtWin::isCompositionEnabled();
213 foreach(QWidget * widget, widgets) {
215 widget->setAttribute(Qt::WA_NoSystemBackground, compositionEnabled);
220 return QWidget::winEvent(message, result);