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
66 void addWidget(QWidget
*widget
)
68 widgets
.append(widget
);
70 void removeWidget(QWidget
*widget
)
72 widgets
.removeAll(widget
);
74 bool winEvent(MSG
*message
, long *result
);
80 static bool resolveLibs()
82 if (!pDwmIsCompositionEnabled
)
84 QLibrary
dwmLib(QString::fromAscii("dwmapi"));
85 pDwmIsCompositionEnabled
=(PtrDwmIsCompositionEnabled
)dwmLib
.resolve("DwmIsCompositionEnabled");
86 pDwmExtendFrameIntoClientArea
= (PtrDwmExtendFrameIntoClientArea
)dwmLib
.resolve("DwmExtendFrameIntoClientArea");
87 pDwmEnableBlurBehindWindow
= (PtrDwmEnableBlurBehindWindow
)dwmLib
.resolve("DwmEnableBlurBehindWindow");
88 pDwmGetColorizationColor
= (PtrDwmGetColorizationColor
)dwmLib
.resolve("DwmGetColorizationColor");
90 return pDwmIsCompositionEnabled
!= 0;
96 * Chekcs and returns true if Windows DWM composition
97 * is currently enabled on the system.
99 * To get live notification on the availability of
100 * this feature, you will currently have to
101 * reimplement winEvent() on your widget and listen
102 * for the WM_DWMCOMPOSITIONCHANGED event to occur.
105 bool QtWin::isCompositionEnabled()
111 BOOL isEnabled
= false;
112 hr
= pDwmIsCompositionEnabled(&isEnabled
);
121 * Enables Blur behind on a Widget.
123 * \a enable tells if the blur should be enabled or not
125 bool QtWin::enableBlurBehindWindow(QWidget
*widget
, bool enable
)
132 DWM_BLURBEHIND bb
= {0};
135 bb
.dwFlags
= DWM_BB_ENABLE
;
137 widget
->setAttribute(Qt::WA_TranslucentBackground
, enable
);
138 widget
->setAttribute(Qt::WA_NoSystemBackground
, enable
);
139 hr
= pDwmEnableBlurBehindWindow(widget
->winId(), &bb
);
143 windowNotifier()->addWidget(widget
);
151 * ExtendFrameIntoClientArea.
153 * This controls the rendering of the frame inside the window.
154 * Note that passing margins of -1 (the default value) will completely
155 * remove the frame from the window.
157 * \note you should not call enableBlurBehindWindow before calling
160 * \a enable tells if the blur should be enabled or not
162 bool QtWin::extendFrameIntoClientArea(QWidget
*widget
, int left
, int top
, int right
, int bottom
)
175 QLibrary
dwmLib(QString::fromAscii("dwmapi"));
177 MARGINS m
= {left
, top
, right
, bottom
};
178 hr
= pDwmExtendFrameIntoClientArea(widget
->winId(), &m
);
182 windowNotifier()->addWidget(widget
);
184 widget
->setAttribute(Qt::WA_TranslucentBackground
, result
);
191 * Returns the current colorizationColor for the window.
193 * \a enable tells if the blur should be enabled or not
195 QColor
QtWin::colorizatinColor()
197 QColor resultColor
= QApplication::palette().window().color();
204 QLibrary
dwmLib(QString::fromAscii("dwmapi"));
206 hr
= pDwmGetColorizationColor(&color
, &opaque
);
208 resultColor
= QColor(color
);
215 WindowNotifier
*QtWin::windowNotifier()
217 static WindowNotifier
*windowNotifierInstance
= 0;
218 if (!windowNotifierInstance
)
219 windowNotifierInstance
= new WindowNotifier
;
220 return windowNotifierInstance
;
224 /* Notify all enabled windows that the DWM state changed */
225 bool WindowNotifier::winEvent(MSG
*message
, long *result
)
227 if (message
&& message
->message
== WM_DWMCOMPOSITIONCHANGED
)
229 bool compositionEnabled
= QtWin::isCompositionEnabled();
230 Q_FOREACH(QWidget
* widget
, widgets
)
234 widget
->setAttribute(Qt::WA_NoSystemBackground
, compositionEnabled
);
239 return QWidget::winEvent(message
, result
);