1 /********************************************************************
\r
3 * Copyright (c) 2002 Sven Wiegand <mail@sven-wiegand.de>
\r
5 * You can use this and modify this in any way you want,
\r
6 * BUT LEAVE THIS HEADER INTACT.
\r
8 * Redistribution is appreciated.
\r
18 *********************************************************************/
\r
21 #include "PropPageFrameDefault.h"
\r
22 #include "ExtTextOutFL.h"
\r
24 namespace TreePropSheet
\r
28 //uncomment the following line, if you don't have installed the
\r
33 #include <uxtheme.h>
\r
34 #include <tmschema.h>
\r
38 #define new DEBUG_NEW
\r
40 static char THIS_FILE[] = __FILE__;
\r
43 //-------------------------------------------------------------------
\r
45 //-------------------------------------------------------------------
\r
47 #define THEMEAPITYPE(f) typedef HRESULT (__stdcall *_##f)
\r
48 #define THEMEAPITYPE_(t, f) typedef t (__stdcall *_##f)
\r
49 #define THEMEAPIPTR(f) _##f m_p##f
\r
52 #define THEMECALL(f) return (*m_p##f)
\r
53 #define GETTHEMECALL(f) m_p##f = (_##f)GetProcAddress(m_hThemeLib, #f)
\r
55 void ThemeDummy(...) {ASSERT(FALSE);}
\r
56 #define HTHEME void*
\r
58 #define THEMECALL(f) return 0; ThemeDummy
\r
59 #define GETTHEMECALL(f) m_p##f = NULL
\r
64 Helper class for loading the uxtheme DLL and providing their
\r
67 One global object of this class exists.
\r
69 @author Sven Wiegand
\r
73 // construction/destruction
\r
81 Returns TRUE if the call wrappers are available, FALSE otherwise.
\r
83 BOOL IsAvailable() const;
\r
87 BOOL IsThemeActive()
\r
88 {THEMECALL(IsThemeActive)();}
\r
90 HTHEME OpenThemeData(HWND hwnd, LPCWSTR pszClassList)
\r
91 {THEMECALL(OpenThemeData)(hwnd, pszClassList);}
\r
93 HRESULT CloseThemeData(HTHEME hTheme)
\r
94 {THEMECALL(CloseThemeData)(hTheme);}
\r
96 HRESULT GetThemeBackgroundContentRect(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, OUT RECT *pContentRect)
\r
97 {THEMECALL(GetThemeBackgroundContentRect)(hTheme, hdc, iPartId, iStateId, pBoundingRect, pContentRect);}
\r
99 HRESULT DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect)
\r
100 {THEMECALL(DrawThemeBackground)(hTheme, hdc, iPartId, iStateId, pRect, pClipRect);}
\r
102 // function pointers
\r
105 THEMEAPITYPE_(BOOL, IsThemeActive)();
\r
106 THEMEAPIPTR(IsThemeActive);
\r
108 THEMEAPITYPE_(HTHEME, OpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
\r
109 THEMEAPIPTR(OpenThemeData);
\r
111 THEMEAPITYPE(CloseThemeData)(HTHEME hTheme);
\r
112 THEMEAPIPTR(CloseThemeData);
\r
114 THEMEAPITYPE(GetThemeBackgroundContentRect)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, OUT RECT *pContentRect);
\r
115 THEMEAPIPTR(GetThemeBackgroundContentRect);
\r
117 THEMEAPITYPE(DrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
\r
118 THEMEAPIPTR(DrawThemeBackground);
\r
123 /** instance handle to the library or NULL. */
\r
124 HINSTANCE m_hThemeLib;
\r
128 One and only instance of CThemeLib.
\r
130 static CThemeLib g_ThemeLib;
\r
133 CThemeLib::CThemeLib()
\r
134 : m_hThemeLib(NULL)
\r
137 m_hThemeLib = LoadLibrary(_T("uxtheme.dll"));
\r
141 GETTHEMECALL(IsThemeActive);
\r
142 GETTHEMECALL(OpenThemeData);
\r
143 GETTHEMECALL(CloseThemeData);
\r
144 GETTHEMECALL(GetThemeBackgroundContentRect);
\r
145 GETTHEMECALL(DrawThemeBackground);
\r
150 CThemeLib::~CThemeLib()
\r
153 FreeLibrary(m_hThemeLib);
\r
157 BOOL CThemeLib::IsAvailable() const
\r
159 return m_hThemeLib!=NULL;
\r
163 //-------------------------------------------------------------------
\r
164 // class CPropPageFrameDefault
\r
165 //-------------------------------------------------------------------
\r
167 BEGIN_MESSAGE_MAP(CPropPageFrameDefault, CWnd)
\r
168 //{{AFX_MSG_MAP(CPropPageFrameDefault)
\r
175 CPropPageFrameDefault::CPropPageFrameDefault()
\r
180 CPropPageFrameDefault::~CPropPageFrameDefault()
\r
182 if (m_Images.GetSafeHandle())
\r
183 m_Images.DeleteImageList();
\r
187 /////////////////////////////////////////////////////////////////////
\r
190 BOOL CPropPageFrameDefault::Create(DWORD dwWindowStyle, const RECT &rect, CWnd *pwndParent, UINT nID)
\r
192 return CWnd::Create(
\r
193 AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, AfxGetApp()->LoadStandardCursor(IDC_ARROW), GetSysColorBrush(COLOR_3DFACE)),
\r
195 dwWindowStyle, rect, pwndParent, nID);
\r
199 CWnd* CPropPageFrameDefault::GetWnd()
\r
201 return static_cast<CWnd*>(this);
\r
205 void CPropPageFrameDefault::SetCaption(LPCTSTR lpszCaption, HICON hIcon /*= NULL*/)
\r
207 CPropPageFrame::SetCaption(lpszCaption, hIcon);
\r
209 // build image list
\r
210 if (m_Images.GetSafeHandle())
\r
211 m_Images.DeleteImageList();
\r
215 if (!GetIconInfo(hIcon, &ii))
\r
219 bmMask.Attach(ii.hbmMask);
\r
220 if (ii.hbmColor) DeleteObject(ii.hbmColor);
\r
223 bmMask.GetBitmap(&bm);
\r
225 if (!m_Images.Create(bm.bmWidth, bm.bmHeight, ILC_COLOR32|ILC_MASK, 0, 1))
\r
228 if (m_Images.Add(hIcon) == -1)
\r
229 m_Images.DeleteImageList();
\r
234 CRect CPropPageFrameDefault::CalcMsgArea()
\r
237 GetClientRect(rect);
\r
238 if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive())
\r
240 HTHEME hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab");
\r
244 CDC *pDc = GetDC();
\r
245 g_ThemeLib.GetThemeBackgroundContentRect(hTheme, pDc->m_hDC, TABP_PANE, 0, rect, rectContent);
\r
247 g_ThemeLib.CloseThemeData(hTheme);
\r
249 if (GetShowCaption())
\r
250 rectContent.top = rect.top+GetCaptionHeight()+1;
\r
251 rect = rectContent;
\r
254 else if (GetShowCaption())
\r
255 rect.top+= GetCaptionHeight()+1;
\r
261 CRect CPropPageFrameDefault::CalcCaptionArea()
\r
264 GetClientRect(rect);
\r
265 if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive())
\r
267 HTHEME hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab");
\r
271 CDC *pDc = GetDC();
\r
272 g_ThemeLib.GetThemeBackgroundContentRect(hTheme, pDc->m_hDC, TABP_PANE, 0, rect, rectContent);
\r
274 g_ThemeLib.CloseThemeData(hTheme);
\r
276 if (GetShowCaption())
\r
277 rectContent.bottom = rect.top+GetCaptionHeight();
\r
279 rectContent.bottom = rectContent.top;
\r
281 rect = rectContent;
\r
286 if (GetShowCaption())
\r
287 rect.bottom = rect.top+GetCaptionHeight();
\r
289 rect.bottom = rect.top;
\r
295 void CPropPageFrameDefault::DrawCaption(CDC *pDc, CRect rect, LPCTSTR lpszCaption, HICON hIcon)
\r
297 COLORREF clrLeft = GetSysColor(COLOR_INACTIVECAPTION);
\r
298 COLORREF clrRight = pDc->GetPixel(rect.right-1, rect.top);
\r
299 FillGradientRectH(pDc, rect, clrLeft, clrRight);
\r
302 if (hIcon && m_Images.GetSafeHandle() && m_Images.GetImageCount() == 1)
\r
305 m_Images.GetImageInfo(0, &ii);
\r
306 CPoint pt(3, rect.CenterPoint().y - (ii.rcImage.bottom-ii.rcImage.top)/2);
\r
307 m_Images.Draw(pDc, 0, pt, ILD_TRANSPARENT);
\r
308 rect.left+= (ii.rcImage.right-ii.rcImage.left) + 3;
\r
314 COLORREF clrPrev = pDc->SetTextColor(GetSysColor(COLOR_CAPTIONTEXT));
\r
315 int nBkStyle = pDc->SetBkMode(TRANSPARENT);
\r
316 CFont *pFont = (CFont*)pDc->SelectStockObject(SYSTEM_FONT);
\r
318 //pDc->DrawText(lpszCaption, rect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS);
\r
320 TextOutTryFL(pDc->GetSafeHdc(), rect.left, rect.top, lpszCaption, _tcslen(lpszCaption));
\r
322 pDc->SetTextColor(clrPrev);
\r
323 pDc->SetBkMode(nBkStyle);
\r
324 pDc->SelectObject(pFont);
\r
328 /////////////////////////////////////////////////////////////////////
\r
329 // Implementation helpers
\r
331 void CPropPageFrameDefault::FillGradientRectH(CDC *pDc, const RECT &rect, COLORREF clrLeft, COLORREF clrRight)
\r
334 int nSteps = rect.right-rect.left;
\r
335 int nRRange = GetRValue(clrRight)-GetRValue(clrLeft);
\r
336 int nGRange = GetGValue(clrRight)-GetGValue(clrLeft);
\r
337 int nBRange = GetBValue(clrRight)-GetBValue(clrLeft);
\r
339 double dRStep = (double)nRRange/(double)nSteps;
\r
340 double dGStep = (double)nGRange/(double)nSteps;
\r
341 double dBStep = (double)nBRange/(double)nSteps;
\r
343 double dR = (double)GetRValue(clrLeft);
\r
344 double dG = (double)GetGValue(clrLeft);
\r
345 double dB = (double)GetBValue(clrLeft);
\r
347 CPen *pPrevPen = NULL;
\r
348 for (int x = rect.left; x <= rect.right; ++x)
\r
350 CPen Pen(PS_SOLID, 1, RGB((BYTE)dR, (BYTE)dG, (BYTE)dB));
\r
351 pPrevPen = pDc->SelectObject(&Pen);
\r
352 pDc->MoveTo(x, rect.top);
\r
353 pDc->LineTo(x, rect.bottom);
\r
354 pDc->SelectObject(pPrevPen);
\r
363 /////////////////////////////////////////////////////////////////////
\r
364 // message handlers
\r
366 void CPropPageFrameDefault::OnPaint()
\r
373 BOOL CPropPageFrameDefault::OnEraseBkgnd(CDC* pDC)
\r
375 if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive())
\r
377 HTHEME hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"TREEVIEW");
\r
381 GetClientRect(rect);
\r
382 g_ThemeLib.DrawThemeBackground(hTheme, pDC->m_hDC, 0, 0, rect, NULL);
\r
384 g_ThemeLib.CloseThemeData(hTheme);
\r
390 return CWnd::OnEraseBkgnd(pDC);
\r
396 } //namespace TreePropSheet
\r