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