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