1 // Windows Template Library - WTL version 9.10
2 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
3 //
4 // This file is a part of the Windows Template Library.
5 // The use and distribution terms for this software are covered by the
6 // Microsoft Public License (http://opensource.org/licenses/MS-PL)
7 // which can be found in the file MS-PL.txt at the root folder.
8 
9 #ifndef __ATLDWM_H__
10 #define __ATLDWM_H__
11 
12 #pragma once
13 
14 #ifdef _WIN32_WCE
15 	#error atldwm.h is not supported on Windows CE
16 #endif
17 
18 #ifndef __ATLAPP_H__
19 	#error atldwm.h requires atlapp.h to be included first
20 #endif
21 
22 #ifndef __ATLWIN_H__
23 	#error atldwm.h requires atlwin.h to be included first
24 #endif
25 
26 #if (_WIN32_WINNT < 0x0600)
27 	#error atldwm.h requires _WIN32_WINNT >= 0x0600
28 #endif
29 
30 #ifndef _DWMAPI_H_
31   #include <dwmapi.h>
32 #endif
33 #pragma comment(lib, "dwmapi.lib")
34 
35 // Note: To create an application that also runs on older versions of Windows,
36 // use delay load of dwmapi.dll and ensure that no calls to the DWM API are
37 // Delay load is NOT AUTOMATIC for VC++ 7, you have to link to delayimp.lib,
38 // and add dwmapi.dll in the Linker.Input.Delay Loaded DLLs section of the
39 // project properties.
40 #if (_MSC_VER < 1300) && !defined(_WTL_NO_DWMAPI_DELAYLOAD)
41   #pragma comment(lib, "delayimp.lib")
42   #pragma comment(linker, "/delayload:dwmapi.dll")
43 #endif // (_MSC_VER < 1300) && !defined(_WTL_NO_DWMAPI_DELAYLOAD)
44 
45 ///////////////////////////////////////////////////////////////////////////////
46 // Classes in this file:
47 //
48 // CDwm
49 // CDwmImpl<T, TBase>
50 // CDwmWindowT<TBase> - CDwmWindow
51 // CDwmThumbnailT<t_bManaged, TBase>
52 // CDwmThumbnail
53 // CDwmThumbnailHandle
54 // CAeroControlImpl
55 
56 
57 namespace WTL
58 {
59 
60 ///////////////////////////////////////////////////////////////////////////////
61 // CDwm - wrapper for DWM handle
62 
63 class CDwm
64 {
65 public:
66 // Data members
67 	static int m_nIsDwmSupported;
68 
69 // Constructor
CDwm()70 	CDwm()
71 	{
72 		IsDwmSupported();
73 	}
74 
75 // Dwm support helper
IsDwmSupported()76 	static bool IsDwmSupported()
77 	{
78 		if(m_nIsDwmSupported == -1)
79 		{
80 			CStaticDataInitCriticalSectionLock lock;
81 			if(FAILED(lock.Lock()))
82 			{
83 				ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CDwm::IsDwmSupported.\n"));
84 				ATLASSERT(FALSE);
85 				return false;
86 			}
87 
88 			if(m_nIsDwmSupported == -1)
89 			{
90 				HMODULE hDwmDLL = ::LoadLibrary(_T("dwmapi.dll"));
91 				m_nIsDwmSupported = (hDwmDLL != NULL) ? 1 : 0;
92 				if(hDwmDLL != NULL)
93 					::FreeLibrary(hDwmDLL);
94 			}
95 
96 			lock.Unlock();
97 		}
98 
99 		ATLASSERT(m_nIsDwmSupported != -1);
100 		return (m_nIsDwmSupported == 1);
101 	}
102 
103 // Operations
DwmIsCompositionEnabled()104 	BOOL DwmIsCompositionEnabled() const
105 	{
106 		if(!IsDwmSupported())
107 			return FALSE;
108 
109 		BOOL bRes = FALSE;
110 		return (SUCCEEDED(::DwmIsCompositionEnabled(&bRes)) && bRes) ? TRUE : FALSE;
111 	}
112 
DwmEnableComposition(UINT fEnable)113 	BOOL DwmEnableComposition(UINT fEnable)
114 	{
115 		if(!IsDwmSupported())
116 			return FALSE;
117 
118 		return SUCCEEDED(::DwmEnableComposition(fEnable)) ? TRUE : FALSE;
119 	}
120 
DwmEnableMMCSS(BOOL fEnableMMCSS)121 	BOOL DwmEnableMMCSS(BOOL fEnableMMCSS)
122 	{
123 		if(!IsDwmSupported())
124 			return FALSE;
125 
126 		return SUCCEEDED(::DwmEnableMMCSS(fEnableMMCSS)) ? TRUE : FALSE;
127 	}
128 
DwmGetColorizationColor(DWORD * pcrColorization,BOOL * pfOpaqueBlend)129 	HRESULT DwmGetColorizationColor(DWORD* pcrColorization, BOOL* pfOpaqueBlend)
130 	{
131 		if(!IsDwmSupported())
132 			return E_NOTIMPL;
133 
134 		return ::DwmGetColorizationColor(pcrColorization, pfOpaqueBlend);
135 	}
136 
DwmFlush()137 	HRESULT DwmFlush()
138 	{
139 		if(!IsDwmSupported())
140 			return E_NOTIMPL;
141 
142 		return ::DwmFlush();
143 	}
144 };
145 
146 __declspec(selectany) int CDwm::m_nIsDwmSupported = -1;
147 
148 
149 ///////////////////////////////////////////////////////////////////////////////
150 // CDwmImpl - DWM window support
151 
152 template <class T, class TBase = CDwm>
153 class CDwmImpl : public TBase
154 {
155 public:
DwmEnableBlurBehindWindow(const DWM_BLURBEHIND * pBB)156 	HRESULT DwmEnableBlurBehindWindow(const DWM_BLURBEHIND* pBB)
157 	{
158 		if(!IsDwmSupported())
159 			return E_NOTIMPL;
160 
161 		T* pT = static_cast<T*>(this);
162 		ATLASSERT(::IsWindow(pT->m_hWnd));
163 		return ::DwmEnableBlurBehindWindow(pT->m_hWnd, pBB);
164 	}
165 
DwmExtendFrameIntoClientArea(const MARGINS * pMargins)166 	HRESULT DwmExtendFrameIntoClientArea(const MARGINS* pMargins)
167 	{
168 		if(!IsDwmSupported())
169 			return E_NOTIMPL;
170 
171 		T* pT = static_cast<T*>(this);
172 		ATLASSERT(::IsWindow(pT->m_hWnd));
173 		return ::DwmExtendFrameIntoClientArea(pT->m_hWnd, pMargins);
174 	}
175 
DwmExtendFrameIntoEntireClientArea()176 	HRESULT DwmExtendFrameIntoEntireClientArea()
177 	{
178 		MARGINS margins = { -1 };
179 		return DwmExtendFrameIntoClientArea(&margins);
180 	}
181 
DwmGetCompositionTimingInfo(DWM_TIMING_INFO * pTimingInfo)182 	HRESULT DwmGetCompositionTimingInfo(DWM_TIMING_INFO* pTimingInfo)
183 	{
184 		if(!IsDwmSupported())
185 			return E_NOTIMPL;
186 
187 		T* pT = static_cast<T*>(this);
188 		ATLASSERT(::IsWindow(pT->m_hWnd));
189 		return ::DwmGetCompositionTimingInfo(pT->m_hWnd, pTimingInfo);
190 	}
191 
DwmGetWindowAttribute(DWORD dwAttribute,PVOID pvAttribute,DWORD cbAttribute)192 	HRESULT DwmGetWindowAttribute(DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute)
193 	{
194 		if(!IsDwmSupported())
195 			return E_NOTIMPL;
196 
197 		T* pT = static_cast<T*>(this);
198 		ATLASSERT(::IsWindow(pT->m_hWnd));
199 		return ::DwmGetWindowAttribute(pT->m_hWnd, dwAttribute, pvAttribute, cbAttribute);
200 	}
201 
DwmModifyPreviousDxFrameDuration(INT cRefreshes,BOOL fRelative)202 	HRESULT DwmModifyPreviousDxFrameDuration(INT cRefreshes, BOOL fRelative)
203 	{
204 		if(!IsDwmSupported())
205 			return E_NOTIMPL;
206 
207 		T* pT = static_cast<T*>(this);
208 		ATLASSERT(::IsWindow(pT->m_hWnd));
209 		return ::DwmModifyPreviousDxFrameDuration(pT->m_hWnd, cRefreshes, fRelative);
210 	}
211 
DwmSetDxFrameDuration(INT cRefreshes)212 	HRESULT DwmSetDxFrameDuration(INT cRefreshes)
213 	{
214 		if(!IsDwmSupported())
215 			return E_NOTIMPL;
216 
217 		T* pT = static_cast<T*>(this);
218 		ATLASSERT(::IsWindow(pT->m_hWnd));
219 		return ::DwmSetDxFrameDuration(pT->m_hWnd, cRefreshes);
220 	}
221 
DwmSetPresentParameters(DWM_PRESENT_PARAMETERS * pPresentParams)222 	HRESULT DwmSetPresentParameters(DWM_PRESENT_PARAMETERS* pPresentParams)
223 	{
224 		if(!IsDwmSupported())
225 			return E_NOTIMPL;
226 
227 		T* pT = static_cast<T*>(this);
228 		ATLASSERT(::IsWindow(pT->m_hWnd));
229 		return ::DwmSetPresentParameters(pT->m_hWnd, pPresentParams);
230 	}
231 
DwmSetWindowAttribute(DWORD dwAttribute,LPCVOID pvAttribute,DWORD cbAttribute)232 	HRESULT DwmSetWindowAttribute(DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute)
233 	{
234 		if(!IsDwmSupported())
235 			return E_NOTIMPL;
236 
237 		T* pT = static_cast<T*>(this);
238 		ATLASSERT(::IsWindow(pT->m_hWnd));
239 		return ::DwmSetWindowAttribute(pT->m_hWnd, dwAttribute, pvAttribute, cbAttribute);
240 	}
241 
DwmAttachMilContent()242 	HRESULT DwmAttachMilContent()
243 	{
244 		if(!IsDwmSupported())
245 			return E_NOTIMPL;
246 
247 		T* pT = static_cast<T*>(this);
248 		ATLASSERT(::IsWindow(pT->m_hWnd));
249 		return ::DwmAttachMilContent(pT->m_hWnd);
250 	}
251 
DwmDetachMilContent()252 	HRESULT DwmDetachMilContent()
253 	{
254 		if(!IsDwmSupported())
255 			return E_NOTIMPL;
256 
257 		T* pT = static_cast<T*>(this);
258 		ATLASSERT(::IsWindow(pT->m_hWnd));
259 		return ::DwmDetachMilContent(pT->m_hWnd);
260 	}
261 };
262 
263 template <class TBase>
264 class CDwmWindowT : public TBase, public CDwmImpl<CDwmWindowT< TBase > >
265 {
266 public:
TBase(hWnd)267 	CDwmWindowT(HWND hWnd = NULL) : TBase(hWnd)
268 	{ }
269 
270 	CDwmWindowT< TBase >& operator =(HWND hWnd)
271 	{
272 		m_hWnd = hWnd;
273 		return *this;
274 	}
275 };
276 
277 typedef CDwmWindowT<ATL::CWindow>	CDwmWindow;
278 
279 
280 ///////////////////////////////////////////////////////////////////////////////
281 // CDwmThumbnail - provides DWM thumbnail support
282 
283 template <bool t_bManaged, class TBase = CDwm>
284 class CDwmThumbnailT : public TBase
285 {
286 public:
287 // Data members
288 	HTHUMBNAIL m_hThumbnail;
289 
290 // Constructor
m_hThumbnail(hThumbnail)291 	CDwmThumbnailT(HTHUMBNAIL hThumbnail = NULL) : m_hThumbnail(hThumbnail)
292 	{ }
293 
~CDwmThumbnailT()294 	~CDwmThumbnailT()
295 	{
296 		if(t_bManaged && (m_hThumbnail != NULL))
297 			Unregister();
298 	}
299 
300 // Operations
301 	CDwmThumbnailT<t_bManaged, TBase>& operator =(HTHUMBNAIL hThumbnail)
302 	{
303 		Attach(hThumbnail);
304 		return *this;
305 	}
306 
Attach(HTHUMBNAIL hThumbnailNew)307 	void Attach(HTHUMBNAIL hThumbnailNew)
308 	{
309 		if(t_bManaged && m_hThumbnail != NULL && m_hThumbnail != hThumbnailNew)
310 			Unregister();
311 		m_hThumbnail = hThumbnailNew;
312 	}
313 
Detach()314 	HTHUMBNAIL Detach()
315 	{
316 		HTHUMBNAIL hThumbnail = m_hThumbnail;
317 		m_hThumbnail = NULL;
318 		return hThumbnail;
319 	}
320 
Register(HWND hwndDestination,HWND hwndSource)321 	HRESULT Register(HWND hwndDestination, HWND hwndSource)
322 	{
323 		ATLASSERT(::IsWindow(hwndDestination));
324 		ATLASSERT(::IsWindow(hwndSource));
325 		ATLASSERT(m_hThumbnail==NULL);
326 
327 		if(!IsDwmSupported())
328 			return E_NOTIMPL;
329 
330 		return ::DwmRegisterThumbnail(hwndDestination, hwndSource, &m_hThumbnail);
331 	}
332 
Unregister()333 	HRESULT Unregister()
334 	{
335 		if(!IsDwmSupported())
336 			return E_NOTIMPL;
337 		if(m_hThumbnail == NULL)
338 			return S_FALSE;
339 
340 		HRESULT Hr = ::DwmUnregisterThumbnail(m_hThumbnail);
341 		if(SUCCEEDED(Hr))
342 			m_hThumbnail = NULL;
343 
344 		return Hr;
345 	}
346 
HTHUMBNAIL()347 	operator HTHUMBNAIL() const { return m_hThumbnail; }
348 
IsNull()349 	bool IsNull() const { return (m_hThumbnail == NULL); }
350 
UpdateProperties(const DWM_THUMBNAIL_PROPERTIES * ptnProperties)351 	HRESULT UpdateProperties(const DWM_THUMBNAIL_PROPERTIES* ptnProperties)
352 	{
353 		if(!IsDwmSupported())
354 			return E_NOTIMPL;
355 
356 		ATLASSERT(m_hThumbnail != NULL);
357 		return ::DwmUpdateThumbnailProperties(m_hThumbnail, ptnProperties);
358 	}
359 
360 // Attributes
QuerySourceSize(PSIZE pSize)361 	HRESULT QuerySourceSize(PSIZE pSize)
362 	{
363 		if(!IsDwmSupported())
364 			return E_NOTIMPL;
365 
366 		ATLASSERT(m_hThumbnail != NULL);
367 		return ::DwmQueryThumbnailSourceSize(m_hThumbnail, pSize);
368 	}
369 };
370 
371 typedef CDwmThumbnailT<true, CDwm> CDwmThumbnail;
372 typedef CDwmThumbnailT<false, CDwm> CDwmThumbnailHandle;
373 
374 
375 #ifdef __ATLTHEME_H__
376 
377 ///////////////////////////////////////////////////////////////////////////////
378 // CAeroControlImpl - Base class for controls on Glass
379 
380 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlWinTraits>
381 class CAeroControlImpl : public CThemeImpl<T>,
382                          public CBufferedPaintImpl<T>,
383                          public ATL::CWindowImpl<T, TBase, TWinTraits>
384 {
385 public:
386 	typedef CThemeImpl<T> _themeClass;
387 	typedef CBufferedPaintImpl<T> _baseClass;
388 	typedef ATL::CWindowImpl<T, TBase, TWinTraits> _windowClass;
389 
CAeroControlImpl()390 	CAeroControlImpl()
391 	{
392 		m_PaintParams.dwFlags = BPPF_ERASE;
393 	}
394 
GetThemeName()395 	static LPCWSTR GetThemeName()
396 	{
397 #ifdef _UNICODE
398 		return TBase::GetWndClassName();
399 #else
400 		ATLASSERT(!_T("Return UNICODE string of window classname / theme class"));
401 		return NULL;
402 #endif // _UNICODE
403 	}
404 
405 // Message map and handlers
406 	BEGIN_MSG_MAP(CAeroControlImpl)
MESSAGE_HANDLER(WM_CREATE,OnCreate)407 		MESSAGE_HANDLER(WM_CREATE, OnCreate)
408 		MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
409 		CHAIN_MSG_MAP(_themeClass)
410 		CHAIN_MSG_MAP(_baseClass)
411 	END_MSG_MAP()
412 
413 	LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
414 	{
415 		T* pT = static_cast<T*>(this);
416 		pT->Init();
417 
418 		bHandled = FALSE;
419 		return 0;
420 	}
421 
OnActivate(UINT,WPARAM,LPARAM,BOOL & bHandled)422 	LRESULT OnActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
423 	{
424 		if(IsThemingSupported())
425 			Invalidate(FALSE);
426 
427 		bHandled = FALSE;
428 		return 0;
429 	}
430 
431 // Operations
SubclassWindow(HWND hWnd)432 	BOOL SubclassWindow(HWND hWnd)
433 	{
434 		ATLASSERT(m_hWnd == NULL);
435 		ATLASSERT(::IsWindow(hWnd));
436 		BOOL bRet = _windowClass::SubclassWindow(hWnd);
437 		if(bRet)
438 		{
439 			T* pT = static_cast<T*>(this);
440 			pT->Init();
441 		}
442 
443 		return bRet;
444 	}
445 
446 // Implementation
DefWindowProc()447 	LRESULT DefWindowProc()
448 	{
449 		const ATL::_ATL_MSG* pMsg = m_pCurrentMsg;
450 		LRESULT lRes = 0;
451 		if(pMsg != NULL)
452 			lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam);
453 
454 		return lRes;
455 	}
456 
DefWindowProc(UINT uMsg,WPARAM wParam,LPARAM lParam)457 	LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
458 	{
459 		T* pT = static_cast<T*>(this);
460 		LRESULT lRes = 0;
461 		if(::DwmDefWindowProc(pT->m_hWnd, uMsg, wParam, lParam, &lRes) != FALSE)
462 			return lRes;
463 
464 		return _windowClass::DefWindowProc(uMsg, wParam, lParam);
465 	}
466 
DoBufferedPaint(HDC hDC,RECT & rcPaint)467 	void DoBufferedPaint(HDC hDC, RECT& rcPaint)
468 	{
469 		T* pT = static_cast<T*>(this);
470 		HDC hDCPaint = NULL;
471 		RECT rcClient = { 0 };
472 		GetClientRect(&rcClient);
473 		m_BufferedPaint.Begin(hDC, &rcClient, m_dwFormat, &m_PaintParams, &hDCPaint);
474 		ATLASSERT(hDCPaint != NULL);
475 		pT->DoAeroPaint(hDCPaint, rcClient, rcPaint);
476 		m_BufferedPaint.End();
477 	}
478 
DoPaint(HDC,RECT &)479 	void DoPaint(HDC /*hdc*/, RECT& /*rcClient*/)
480 	{
481 		DefWindowProc();
482 	}
483 
484 // Overridables
Init()485 	void Init()
486 	{
487 		T* pT = static_cast<T*>(this);
488 		pT;   // avoid level 4 warning
489 		SetThemeClassList(pT->GetThemeName());
490 		if(m_lpstrThemeClassList != NULL)
491 			OpenThemeData();
492 	}
493 
DoAeroPaint(HDC hDC,RECT &,RECT & rcPaint)494 	void DoAeroPaint(HDC hDC, RECT& /*rcClient*/, RECT& rcPaint)
495 	{
496 		DefWindowProc(WM_PAINT, (WPARAM) hDC, 0L);
497 		m_BufferedPaint.MakeOpaque(&rcPaint);
498 	}
499 };
500 
501 #endif // __ATLTHEME_H__
502 
503 }; // namespace WTL
504 
505 #endif // __ATLDWM_H__
506