PropPageFrameDefault.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:10k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /********************************************************************
  2. *
  3. * Copyright (c) 2002 Sven Wiegand <mail@sven-wiegand.de>
  4. *
  5. * You can use this and modify this in any way you want,
  6. * BUT LEAVE THIS HEADER INTACT.
  7. *
  8. * Redistribution is appreciated.
  9. *
  10. * $Workfile:$
  11. * $Revision: 1.1 $
  12. * $Modtime:$
  13. * $Author: gabest $
  14. *
  15. * Revision History:
  16. * $History:$
  17. *
  18. *********************************************************************/
  19. #include "stdafx.h"
  20. #include "PropPageFrameDefault.h"
  21. namespace TreePropSheet
  22. {
  23. //uncomment the following line, if you don't have installed the
  24. //new platform SDK
  25. #define XPSUPPORT
  26. #ifdef XPSUPPORT
  27. #include <uxtheme.h>
  28. #include <tmschema.h>
  29. #endif
  30. #ifdef _DEBUG
  31. #define new DEBUG_NEW
  32. #undef THIS_FILE
  33. static char THIS_FILE[] = __FILE__;
  34. #endif
  35. //-------------------------------------------------------------------
  36. // class CThemeLib
  37. //-------------------------------------------------------------------
  38. #define THEMEAPITYPE(f) typedef HRESULT (__stdcall *_##f)
  39. #define THEMEAPITYPE_(t, f) typedef t (__stdcall *_##f)
  40. #define THEMEAPIPTR(f) _##f m_p##f
  41. #ifdef XPSUPPORT
  42. #define THEMECALL(f) return (*m_p##f)
  43. #define GETTHEMECALL(f) m_p##f = (_##f)GetProcAddress(m_hThemeLib, #f)
  44. #else
  45. void ThemeDummy(...) {ASSERT(FALSE);}
  46. #define HTHEME void*
  47. #define TABP_PANE 0
  48. #define THEMECALL(f) return 0; ThemeDummy
  49. #define GETTHEMECALL(f) m_p##f = NULL
  50. #endif
  51. /**
  52. Helper class for loading the uxtheme DLL and providing their 
  53. functions.
  54. One global object of this class exists.
  55. @author Sven Wiegand
  56. */
  57. class CThemeLib
  58. {
  59. // construction/destruction
  60. public:
  61. CThemeLib();
  62. ~CThemeLib();
  63. // operations
  64. public:
  65. /**
  66. Returns TRUE if the call wrappers are available, FALSE otherwise.
  67. */
  68. BOOL IsAvailable() const;
  69. // call wrappers
  70. public:
  71. BOOL IsThemeActive() 
  72. {THEMECALL(IsThemeActive)();}
  73. HTHEME OpenThemeData(HWND hwnd, LPCWSTR pszClassList) 
  74. {THEMECALL(OpenThemeData)(hwnd, pszClassList);}
  75. HRESULT CloseThemeData(HTHEME hTheme) 
  76. {THEMECALL(CloseThemeData)(hTheme);}
  77. HRESULT GetThemeBackgroundContentRect(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId,  const RECT *pBoundingRect, OUT RECT *pContentRect)
  78. {THEMECALL(GetThemeBackgroundContentRect)(hTheme, hdc, iPartId, iStateId, pBoundingRect, pContentRect);}
  79. HRESULT DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect)
  80. {THEMECALL(DrawThemeBackground)(hTheme, hdc, iPartId, iStateId, pRect, pClipRect);}
  81. // function pointers
  82. private:
  83. #ifdef XPSUPPORT
  84. THEMEAPITYPE_(BOOL, IsThemeActive)();
  85. THEMEAPIPTR(IsThemeActive);
  86. THEMEAPITYPE_(HTHEME, OpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
  87. THEMEAPIPTR(OpenThemeData);
  88. THEMEAPITYPE(CloseThemeData)(HTHEME hTheme);
  89. THEMEAPIPTR(CloseThemeData);
  90. THEMEAPITYPE(GetThemeBackgroundContentRect)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId,  const RECT *pBoundingRect, OUT RECT *pContentRect);
  91. THEMEAPIPTR(GetThemeBackgroundContentRect);
  92. THEMEAPITYPE(DrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
  93. THEMEAPIPTR(DrawThemeBackground);
  94. #endif
  95. // properties
  96. private:
  97. /** instance handle to the library or NULL. */
  98. HINSTANCE m_hThemeLib;
  99. };
  100. /**
  101. One and only instance of CThemeLib.
  102. */
  103. static CThemeLib g_ThemeLib;
  104. CThemeLib::CThemeLib()
  105. : m_hThemeLib(NULL)
  106. {
  107. #ifdef XPSUPPORT
  108. m_hThemeLib = LoadLibrary(_T("uxtheme.dll"));
  109. if (!m_hThemeLib)
  110. return;
  111. GETTHEMECALL(IsThemeActive);
  112. GETTHEMECALL(OpenThemeData);
  113. GETTHEMECALL(CloseThemeData);
  114. GETTHEMECALL(GetThemeBackgroundContentRect);
  115. GETTHEMECALL(DrawThemeBackground);
  116. #endif
  117. }
  118. CThemeLib::~CThemeLib()
  119. {
  120. if (m_hThemeLib)
  121. FreeLibrary(m_hThemeLib);
  122. }
  123. BOOL CThemeLib::IsAvailable() const
  124. {
  125. return m_hThemeLib!=NULL;
  126. }
  127. //-------------------------------------------------------------------
  128. // class CPropPageFrameDefault
  129. //-------------------------------------------------------------------
  130. BEGIN_MESSAGE_MAP(CPropPageFrameDefault, CWnd)
  131. //{{AFX_MSG_MAP(CPropPageFrameDefault)
  132. ON_WM_PAINT()
  133. ON_WM_ERASEBKGND()
  134. //}}AFX_MSG_MAP
  135. END_MESSAGE_MAP()
  136. CPropPageFrameDefault::CPropPageFrameDefault()
  137. {
  138. }
  139. CPropPageFrameDefault::~CPropPageFrameDefault()
  140. {
  141. if (m_Images.GetSafeHandle())
  142. m_Images.DeleteImageList();
  143. }
  144. /////////////////////////////////////////////////////////////////////
  145. // Overridings
  146. BOOL CPropPageFrameDefault::Create(DWORD dwWindowStyle, const RECT &rect, CWnd *pwndParent, UINT nID)
  147. {
  148. return CWnd::Create(
  149. AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, AfxGetApp()->LoadStandardCursor(IDC_ARROW), GetSysColorBrush(COLOR_3DFACE)),
  150. _T("Page Frame"),
  151. dwWindowStyle, rect, pwndParent, nID);
  152. }
  153. CWnd* CPropPageFrameDefault::GetWnd()
  154. {
  155. return static_cast<CWnd*>(this);
  156. }
  157. void CPropPageFrameDefault::SetCaption(LPCTSTR lpszCaption, HICON hIcon /*= NULL*/)
  158. {
  159. CPropPageFrame::SetCaption(lpszCaption, hIcon);
  160. // build image list
  161. if (m_Images.GetSafeHandle())
  162. m_Images.DeleteImageList();
  163. if (hIcon)
  164. {
  165. ICONINFO ii;
  166. if (!GetIconInfo(hIcon, &ii))
  167. return;
  168. CBitmap bmMask;
  169. bmMask.Attach(ii.hbmMask);
  170. if (ii.hbmColor) DeleteObject(ii.hbmColor);
  171. BITMAP bm;
  172. bmMask.GetBitmap(&bm);
  173. if (!m_Images.Create(bm.bmWidth, bm.bmHeight, ILC_COLOR32|ILC_MASK, 0, 1))
  174. return;
  175. if (m_Images.Add(hIcon) == -1)
  176. m_Images.DeleteImageList();
  177. }
  178. }
  179. CRect CPropPageFrameDefault::CalcMsgArea()
  180. {
  181. CRect rect;
  182. GetClientRect(rect);
  183. if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive())
  184. {
  185. HTHEME hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab");
  186. if (hTheme)
  187. {
  188. CRect rectContent;
  189. CDC *pDc = GetDC();
  190. g_ThemeLib.GetThemeBackgroundContentRect(hTheme, pDc->m_hDC, TABP_PANE, 0, rect, rectContent);
  191. ReleaseDC(pDc);
  192. g_ThemeLib.CloseThemeData(hTheme);
  193. if (GetShowCaption())
  194. rectContent.top = rect.top+GetCaptionHeight()+1;
  195. rect = rectContent;
  196. }
  197. }
  198. else if (GetShowCaption())
  199. rect.top+= GetCaptionHeight()+1;
  200. return rect;
  201. }
  202. CRect CPropPageFrameDefault::CalcCaptionArea()
  203. {
  204. CRect rect;
  205. GetClientRect(rect);
  206. if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive())
  207. {
  208. HTHEME hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab");
  209. if (hTheme)
  210. {
  211. CRect rectContent;
  212. CDC *pDc = GetDC();
  213. g_ThemeLib.GetThemeBackgroundContentRect(hTheme, pDc->m_hDC, TABP_PANE, 0, rect, rectContent);
  214. ReleaseDC(pDc);
  215. g_ThemeLib.CloseThemeData(hTheme);
  216. if (GetShowCaption())
  217. rectContent.bottom = rect.top+GetCaptionHeight();
  218. else
  219. rectContent.bottom = rectContent.top;
  220. rect = rectContent;
  221. }
  222. }
  223. else
  224. {
  225. if (GetShowCaption())
  226. rect.bottom = rect.top+GetCaptionHeight();
  227. else
  228. rect.bottom = rect.top;
  229. }
  230. return rect;
  231. }
  232. void CPropPageFrameDefault::DrawCaption(CDC *pDc, CRect rect, LPCTSTR lpszCaption, HICON hIcon)
  233. {
  234. COLORREF clrLeft = GetSysColor(COLOR_INACTIVECAPTION);
  235. COLORREF clrRight = pDc->GetPixel(rect.right-1, rect.top);
  236. FillGradientRectH(pDc, rect, clrLeft, clrRight);
  237. // draw icon
  238. if (hIcon && m_Images.GetSafeHandle() && m_Images.GetImageCount() == 1)
  239. {
  240. IMAGEINFO ii;
  241. m_Images.GetImageInfo(0, &ii);
  242. CPoint pt(3, rect.CenterPoint().y - (ii.rcImage.bottom-ii.rcImage.top)/2);
  243. m_Images.Draw(pDc, 0, pt, ILD_TRANSPARENT);
  244. rect.left+= (ii.rcImage.right-ii.rcImage.left) + 3;
  245. }
  246. // draw text
  247. rect.left+= 2;
  248. COLORREF clrPrev = pDc->SetTextColor(GetSysColor(COLOR_CAPTIONTEXT));
  249. int nBkStyle = pDc->SetBkMode(TRANSPARENT);
  250. CFont *pFont = (CFont*)pDc->SelectStockObject(SYSTEM_FONT);
  251. CFont* pSysFont = pDc->GetCurrentFont();
  252. LOGFONT lf;
  253. pSysFont->GetLogFont(&lf);
  254. lf.lfHeight = rect.Height();
  255. lf.lfWidth = 0;
  256. _tcscpy(lf.lfFaceName, _T("Arial"));
  257. CFont f;
  258. f.CreateFontIndirect(&lf);
  259. pDc->SelectObject(&f);
  260. pDc->DrawText(lpszCaption, rect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS);
  261. pDc->SetTextColor(clrPrev);
  262. pDc->SetBkMode(nBkStyle);
  263. pDc->SelectObject(pFont);
  264. }
  265. /////////////////////////////////////////////////////////////////////
  266. // Implementation helpers
  267. void CPropPageFrameDefault::FillGradientRectH(CDC *pDc, const RECT &rect, COLORREF clrLeft, COLORREF clrRight)
  268. {
  269. // pre calculation
  270. int nSteps = rect.right-rect.left;
  271. int nRRange = GetRValue(clrRight)-GetRValue(clrLeft);
  272. int nGRange = GetGValue(clrRight)-GetGValue(clrLeft);
  273. int nBRange = GetBValue(clrRight)-GetBValue(clrLeft);
  274. double dRStep = (double)nRRange/(double)nSteps;
  275. double dGStep = (double)nGRange/(double)nSteps;
  276. double dBStep = (double)nBRange/(double)nSteps;
  277. double dR = (double)GetRValue(clrLeft);
  278. double dG = (double)GetGValue(clrLeft);
  279. double dB = (double)GetBValue(clrLeft);
  280. CPen *pPrevPen = NULL;
  281. for (int x = rect.left; x <= rect.right; ++x)
  282. {
  283. CPen Pen(PS_SOLID, 1, RGB((BYTE)dR, (BYTE)dG, (BYTE)dB));
  284. pPrevPen = pDc->SelectObject(&Pen);
  285. pDc->MoveTo(x, rect.top);
  286. pDc->LineTo(x, rect.bottom);
  287. pDc->SelectObject(pPrevPen);
  288. dR+= dRStep;
  289. dG+= dGStep;
  290. dB+= dBStep;
  291. }
  292. }
  293. /////////////////////////////////////////////////////////////////////
  294. // message handlers
  295. void CPropPageFrameDefault::OnPaint() 
  296. {
  297. CPaintDC dc(this);
  298. Draw(&dc);
  299. }
  300. BOOL CPropPageFrameDefault::OnEraseBkgnd(CDC* pDC) 
  301. {
  302. if (g_ThemeLib.IsAvailable() && g_ThemeLib.IsThemeActive())
  303. {
  304. HTHEME hTheme = g_ThemeLib.OpenThemeData(m_hWnd, L"Tab");
  305. if (hTheme)
  306. {
  307. CRect rect;
  308. GetClientRect(rect);
  309. g_ThemeLib.DrawThemeBackground(hTheme, pDC->m_hDC, TABP_PANE, 0, rect, NULL);
  310. g_ThemeLib.CloseThemeData(hTheme);
  311. }
  312. return TRUE;
  313. }
  314. else
  315. {
  316. return CWnd::OnEraseBkgnd(pDC);
  317. }
  318. }
  319. } //namespace TreePropSheet