3 // Aero sample support classes
10 #if !defined _WTL_VER || _WTL_VER < 0x800
11 #error Aero.h requires the Windows Template Library 8.0
14 #if _WIN32_WINNT < 0x0600
15 #error Aero.h requires _WIN32_WINNT >= 0x0600
16 #elif !defined(NTDDI_VERSION) || (NTDDI_VERSION < NTDDI_LONGHORN)
17 #error Aero.h requires the Windows Vista SDK
20 #ifndef __ATLTHEME_H__
25 #pragma comment (lib, "dwmapi.lib")
27 #if (_MSC_VER < 1300) && !defined(_WTL_NO_THEME_DELAYLOAD)
28 #pragma comment(lib, "delayimp.lib")
29 #pragma comment(linker, "/delayload:dwmapi.dll")
30 #endif // (_MSC_VER < 1300) && !defined(_WTL_NO_THEME_DELAYLOAD)
33 ///////////////////////////////////////////////////////////////////////////////
34 // Classes in this file:
36 // CAeroImpl<T> - enables Aero translucency (when available) for any window
37 // CAeroDialogImpl<T, TBase> - dialog implementation of Aero translucency (when available)
38 // CAeroFrameImpl<T, TBase, TWinTraits> - frame implementation of Aero translucency (when available)
39 // CAeroCtrlImpl - base implementation of Aero opacity for controls
40 // CAeroStatic - Aero opaque Static control
41 // CAeroButton - Aero opaque Button control
42 // CAeroEdit - Aero opaque Edit control
49 public CBufferedPaintImpl
<T
>,
53 CAeroImpl(LPCWSTR lpstrThemeClassList
= L
"globals")
55 m_PaintParams
.dwFlags
= BPPF_ERASE
;
57 SetThemeClassList(lpstrThemeClassList
);
62 static bool IsAeroSupported()
64 return IsBufferedPaintSupported();
67 bool IsCompositionEnabled() const
69 BOOL bEnabled
= FALSE
;
70 return IsAeroSupported() ? SUCCEEDED(DwmIsCompositionEnabled(&bEnabled
)) && bEnabled
: false;
73 bool IsTheming() const
80 bool SetMargins(MARGINS
& m
)
83 T
* pT
= static_cast<T
*>(this);
84 return pT
->IsWindow() && IsAeroSupported() ? SUCCEEDED(DwmExtendFrameIntoClientArea(pT
->m_hWnd
, &m_Margins
)) : true;
88 void DoPaint(CDCHandle dc
, RECT
& rDest
)
90 T
* pT
= static_cast<T
*>(this);
93 pT
->GetClientRect(&rClient
);
95 RECT rView
= {rClient
.left
+ m_Margins
.cxLeftWidth
, rClient
.top
+ m_Margins
.cyTopHeight
,
96 rClient
.right
- m_Margins
.cxRightWidth
, rClient
.bottom
- m_Margins
.cyBottomHeight
};
98 if (IsCompositionEnabled())
99 dc
.FillSolidRect(&rClient
, RGB(0, 0, 0));
102 pT
->DrawThemeBackground(dc
, WP_FRAMEBOTTOM
, pT
->m_hWnd
== GetFocus() ? 1 : 2, &rClient
, &rDest
);
104 dc
.FillSolidRect(&rClient
, GetSysColor(COLOR_MENUBAR
));
106 if (m_Margins
.cxLeftWidth
!= -1)
107 dc
.FillSolidRect(&rView
, GetSysColor(COLOR_WINDOW
));
109 ::SetRectEmpty(&rView
);
111 pT
->AeroDoPaint(dc
, rClient
, rView
, rDest
);
114 void AeroDrawText(HDC dc
, LPCTSTR pStr
, LPRECT prText
, UINT uFormat
, DTTOPTS
&dto
)
117 if (IsAeroSupported())
118 DrawThemeTextEx (dc
, TEXT_BODYTITLE
, 0, pStr
, -1, uFormat
, prText
, &dto
);
120 DrawThemeText(dc
, TEXT_BODYTITLE
, 0, pStr
, -1, uFormat
, 0, prText
);
122 CDCHandle(dc
).DrawText(pStr
, -1, prText
, uFormat
);
125 void AeroDrawText(HDC dc
, LPCTSTR pStr
, LPRECT prText
, UINT uFormat
, DWORD dwFlags
, int iGlowSize
)
127 DTTOPTS dto
= { sizeof(DTTOPTS
) };
128 dto
.dwFlags
= dwFlags
;
129 dto
.iGlowSize
= iGlowSize
;
130 AeroDrawText(dc
, pStr
, prText
, uFormat
, dto
);
134 void AeroDoPaint(CDCHandle dc
, RECT
& rClient
, RECT
& rView
, RECT
& rDest
)
137 BEGIN_MSG_MAP(CAeroImpl
)
138 CHAIN_MSG_MAP(CThemeImpl
<T
>)
139 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
140 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
141 MESSAGE_HANDLER(WM_DWMCOMPOSITIONCHANGED
, OnCompositionChanged
)
142 MESSAGE_HANDLER(WM_PRINTCLIENT
, OnPrintClient
)
143 CHAIN_MSG_MAP(CBufferedPaintImpl
<T
>)
146 LRESULT
OnCreate(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& bHandled
)
148 if (IsThemingSupported())
151 if (IsCompositionEnabled())
152 DwmExtendFrameIntoClientArea(static_cast<T
*>(this)->m_hWnd
, &m_Margins
);
153 return bHandled
= FALSE
;
156 LRESULT
OnActivate(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& bHandled
)
158 if (!IsCompositionEnabled() && IsTheming())
159 static_cast<T
*>(this)->Invalidate(FALSE
);
160 return bHandled
= FALSE
;
163 LRESULT
OnCompositionChanged(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& /*bHandled*/)
165 if (IsCompositionEnabled())
166 SetMargins(m_Margins
);
170 LRESULT
OnPrintClient(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
& /*bHandled*/)
172 T
* pT
= static_cast<T
*>(this);
173 return ::DefWindowProc(pT
->m_hWnd
, uMsg
, wParam
, lParam
);
178 ///////////////////////////////////////////////////////////////////////////////
179 // CAeroDialogImpl - dialog implementation of Aero translucency (when available)
181 template <class T
, class TBase
= CWindow
>
182 class ATL_NO_VTABLE CAeroDialogImpl
: public CDialogImpl
<T
, TBase
>, public CAeroImpl
<T
>
185 CAeroDialogImpl(LPCWSTR lpstrThemeClassList
= L
"dialog") : CAeroImpl(lpstrThemeClassList
)
188 void AeroDoPaint(CDCHandle dc
, RECT
& rClient
, RECT
& rView
, RECT
& rDest
)
190 if (!::IsRectEmpty(&rView
))
193 DrawThemeBackground(dc
, WP_DIALOG
, 1, &rView
, &rDest
);
195 dc
.FillSolidRect(&rView
, GetSysColor(COLOR_BTNFACE
));
199 BEGIN_MSG_MAP(CAeroDialogImpl
)
200 MESSAGE_HANDLER(WM_INITDIALOG
, OnInitDialog
)
201 CHAIN_MSG_MAP(CAeroImpl
<T
>)
204 LRESULT
OnInitDialog(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& bHandled
)
206 if (IsThemingSupported())
209 EnableThemeDialogTexture(ETDT_ENABLE
);
212 if (IsCompositionEnabled())
213 DwmExtendFrameIntoClientArea(static_cast<T
*>(this)->m_hWnd
, &m_Margins
);
215 return bHandled
= FALSE
;
220 ///////////////////////////////////////////////////////////////////////////////
221 // CAeroFrameImpl - frame implementation of Aero translucency (when available)
223 template <class T
, class TBase
= ATL::CWindow
, class TWinTraits
= ATL::CFrameWinTraits
>
224 class ATL_NO_VTABLE CAeroFrameImpl
:
225 public CFrameWindowImpl
<T
, TBase
, TWinTraits
>,
228 typedef CFrameWindowImpl
<T
, TBase
, TWinTraits
> _baseClass
;
230 CAeroFrameImpl(LPCWSTR lpstrThemeClassList
= L
"window") : CAeroImpl(lpstrThemeClassList
)
233 void UpdateLayout(BOOL bResizeBars
= TRUE
)
236 GetClientRect(&rect
);
239 if (m_Margins
.cxLeftWidth
!= -1)
241 rect
.left
+= m_Margins
.cxLeftWidth
;
242 rect
.top
+= m_Margins
.cyTopHeight
;
243 rect
.right
-= m_Margins
.cxRightWidth
;
244 rect
.bottom
-= m_Margins
.cyBottomHeight
;
247 // position bars and offset their dimensions
248 UpdateBarsPosition(rect
, bResizeBars
);
250 // resize client window
251 if(m_hWndClient
!= NULL
)
252 ::SetWindowPos(m_hWndClient
, NULL
, rect
.left
, rect
.top
,
253 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
254 SWP_NOZORDER
| SWP_NOACTIVATE
);
259 void UpdateBarsPosition(RECT
& rect
, BOOL bResizeBars
= TRUE
)
262 if(m_hWndToolBar
!= NULL
&& ((DWORD
)::GetWindowLong(m_hWndToolBar
, GWL_STYLE
) & WS_VISIBLE
))
265 ::GetWindowRect(m_hWndToolBar
, &rectTB
);
268 ::SetWindowPos(m_hWndToolBar
, NULL
, rect
.left
, rect
.top
,
269 rect
.right
- rect
.left
, rectTB
.bottom
- rectTB
.top
,
270 SWP_NOZORDER
| SWP_NOACTIVATE
);
271 ::InvalidateRect(m_hWndToolBar
, NULL
, FALSE
);
273 rect
.top
+= rectTB
.bottom
- rectTB
.top
;
277 if(m_hWndStatusBar
!= NULL
&& ((DWORD
)::GetWindowLong(m_hWndStatusBar
, GWL_STYLE
) & WS_VISIBLE
))
280 ::GetWindowRect(m_hWndStatusBar
, &rectSB
);
281 rect
.bottom
-= rectSB
.bottom
- rectSB
.top
;
283 ::SetWindowPos(m_hWndStatusBar
, NULL
, rect
.left
, rect
.bottom
,
284 rect
.right
- rect
.left
, rectSB
.bottom
- rectSB
.top
,
285 SWP_NOZORDER
| SWP_NOACTIVATE
);
289 BOOL
CreateSimpleStatusBar(LPCTSTR lpstrText
, DWORD dwStyle
= WS_CHILD
| WS_VISIBLE
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
, UINT nID
= ATL_IDW_STATUS_BAR
)
291 ATLASSERT(!::IsWindow(m_hWndStatusBar
));
292 m_hWndStatusBar
= ::CreateStatusWindow(dwStyle
| CCS_NOPARENTALIGN
, lpstrText
, m_hWnd
, nID
);
293 return (m_hWndStatusBar
!= NULL
);
296 BOOL
CreateSimpleStatusBar(UINT nTextID
= ATL_IDS_IDLEMESSAGE
, DWORD dwStyle
= WS_CHILD
| WS_VISIBLE
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
, UINT nID
= ATL_IDW_STATUS_BAR
)
298 const int cchMax
= 128; // max text length is 127 for status bars (+1 for null)
299 TCHAR szText
[cchMax
];
301 ::LoadString(ModuleHelper::GetResourceInstance(), nTextID
, szText
, cchMax
);
302 return CreateSimpleStatusBar(szText
, dwStyle
, nID
);
305 static HWND
CreateSimpleReBarCtrl(HWND hWndParent
, DWORD dwStyle
= ATL_SIMPLE_REBAR_STYLE
, UINT nID
= ATL_IDW_TOOLBAR
)
307 return _baseClass::CreateSimpleReBarCtrl(hWndParent
, dwStyle
| CCS_NOPARENTALIGN
, nID
);
310 BOOL
CreateSimpleReBar(DWORD dwStyle
= ATL_SIMPLE_REBAR_STYLE
, UINT nID
= ATL_IDW_TOOLBAR
)
312 ATLASSERT(!::IsWindow(m_hWndToolBar
));
313 m_hWndToolBar
= _baseClass::CreateSimpleReBarCtrl(m_hWnd
, dwStyle
| CCS_NOPARENTALIGN
, nID
);
314 return (m_hWndToolBar
!= NULL
);
317 BEGIN_MSG_MAP(CAeroFrameImpl
)
318 CHAIN_MSG_MAP(CAeroImpl
<T
>)
319 CHAIN_MSG_MAP(_baseClass
)
323 ///////////////////////////////////////////////////////////////////////////////
324 // CAeroCtrlImpl - implementation of Aero opacity for controls
326 template <class TBase
>
327 class CAeroCtrlImpl
: public CBufferedPaintWindowImpl
<CAeroCtrlImpl
<TBase
>, TBase
>
330 DECLARE_WND_SUPERCLASS(NULL
, TBase::GetWndClassName())
332 void DoBufferedPaint(CDCHandle dc
, RECT
& rect
)
335 if(IsBufferedPaintSupported())
336 m_BufferedPaint
.Begin(dc
, &rect
, m_dwFormat
, &m_PaintParams
, &hDCPaint
);
339 DoPaint(hDCPaint
, rect
);
341 DoPaint(dc
.m_hDC
, rect
);
343 if(IsBufferedPaintSupported() && !m_BufferedPaint
.IsNull())
345 m_BufferedPaint
.MakeOpaque(&rect
);
346 m_BufferedPaint
.End();
350 void DoPaint(CDCHandle dc
, RECT
& /*rect*/)
352 DefWindowProc(WM_PRINTCLIENT
, (WPARAM
)dc
.m_hDC
, PRF_CLIENT
);
356 ///////////////////////////////////////////////////////////////////////////////
357 // CAeroStatic - Aero opaque Static control
358 // CAeroButton - Aero opaque Button control
360 typedef CAeroCtrlImpl
<CStatic
> CAeroStatic
;
361 typedef CAeroCtrlImpl
<CButton
> CAeroButton
;
363 ///////////////////////////////////////////////////////////////////////////////
364 // CAeroEdit - Aero opaque Edit control
365 class CAeroEdit
: public CAeroCtrlImpl
<CEdit
>
367 BEGIN_MSG_MAP(CAeroEdit
)
368 REFLECTED_COMMAND_CODE_HANDLER(EN_CHANGE
, OnChange
)
369 CHAIN_MSG_MAP(CAeroCtrlImpl
<CEdit
>)
372 LRESULT
OnChange(WORD
/*wNotifyCode*/, WORD
/*wID*/, HWND
/*hWndCtl*/, BOOL
& bHandled
)
375 return bHandled
= FALSE
;