comparison foosdk/wtl/Include/atldwm.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
comparison
equal deleted inserted replaced
0:e9bb126753e7 1:20d02a178406
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__