XTHeaderCtrlTheme.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:20k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTHeaderCtrlTheme.cpp: implementation of the CXTHeaderCtrlTheme class.
  2. //
  3. // This file is a part of the XTREME CONTROLS MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Resource.h"
  22. #include "Common/XTPWinThemeWrapper.h"
  23. #include "Common/XTPColorManager.h"
  24. #include "Common/XTPDrawHelpers.h"
  25. #include "Common/XTPImageManager.h"
  26. #include "XTVC50Helpers.h"
  27. #include "XTHeaderCtrl.h"
  28. #include "XTThemeManager.h"
  29. #include "XTHeaderCtrlTheme.h"
  30. #ifdef _DEBUG
  31. #undef THIS_FILE
  32. static char THIS_FILE[] = __FILE__;
  33. #define new DEBUG_NEW
  34. #endif
  35. IMPLEMENT_THEME_FACTORY(CXTHeaderCtrlTheme)
  36. //=============================================================================
  37. // CXTHeaderCtrlTheme
  38. //=============================================================================
  39. CXTHeaderCtrlTheme::CXTHeaderCtrlTheme()
  40. : m_sizePadding(6, 0)
  41. , m_sizeArrow(8, 7)
  42. , m_dwDrawStyle(0)
  43. , m_iArrowPadding(10)
  44. , m_bUseWinThemes(false)
  45. {
  46. m_dwDrawStyle = XTTHEME_WINXPTHEMES | XTTHEME_HOTTRACKING | XTTHEME_SORTARROW;
  47. }
  48. CXTHeaderCtrlTheme::~CXTHeaderCtrlTheme()
  49. {
  50. }
  51. void CXTHeaderCtrlTheme::RefreshMetrics()
  52. {
  53. CXTThemeManagerStyle ::RefreshMetrics();
  54. m_crText = GetXtremeColor(COLOR_BTNTEXT);
  55. m_cr3DFace = GetXtremeColor(COLOR_3DFACE);
  56. m_cr3DShadow = GetXtremeColor(COLOR_3DSHADOW);
  57. m_cr3DDkShadow = GetXtremeColor(COLOR_3DDKSHADOW);
  58. m_cr3DHighLight = GetXtremeColor(COLOR_3DHIGHLIGHT);
  59. m_themeWrapper.OpenThemeData(0, L"HEADER");
  60. }
  61. void CXTHeaderCtrlTheme::OnDrawBackground(LPDRAWITEMSTRUCT lpDIS)
  62. {
  63. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  64. CRect rcItem = lpDIS->rcItem;
  65. // fill background
  66. pDC->FillSolidRect(&rcItem, m_cr3DFace);
  67. rcItem.right += 2;
  68. // draw 3D borders.
  69. pDC->Draw3dRect(&rcItem, m_cr3DHighLight, m_cr3DDkShadow);
  70. rcItem.DeflateRect(1, 1);
  71. pDC->Draw3dRect(&rcItem, m_cr3DFace, m_cr3DShadow);
  72. }
  73. void CXTHeaderCtrlTheme::OnDrawItemBackground(LPDRAWITEMSTRUCT lpDIS)
  74. {
  75. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  76. if (lpDIS->itemState == ODS_SELECTED)
  77. {
  78. pDC->Draw3dRect(&lpDIS->rcItem, m_cr3DShadow, m_cr3DShadow);
  79. CXTPPenDC penDC(pDC->m_hDC, m_cr3DHighLight);
  80. pDC->MoveTo(lpDIS->rcItem.right, 1);
  81. pDC->LineTo(lpDIS->rcItem.right, lpDIS->rcItem.bottom-1);
  82. penDC.Color(m_cr3DFace);
  83. pDC->MoveTo(lpDIS->rcItem.left+1, lpDIS->rcItem.bottom-2);
  84. pDC->LineTo(lpDIS->rcItem.right-1, lpDIS->rcItem.bottom-2);
  85. }
  86. else
  87. {
  88. CXTPPenDC penDC(pDC->m_hDC, m_cr3DShadow);
  89. pDC->MoveTo(lpDIS->rcItem.right-2, 1);
  90. pDC->LineTo(lpDIS->rcItem.right-2, lpDIS->rcItem.bottom-1);
  91. penDC.Color(m_cr3DDkShadow);
  92. pDC->MoveTo(lpDIS->rcItem.right-1, 0);
  93. pDC->LineTo(lpDIS->rcItem.right-1, lpDIS->rcItem.bottom-1);
  94. penDC.Color(m_cr3DHighLight);
  95. pDC->MoveTo(lpDIS->rcItem.right, 1);
  96. pDC->LineTo(lpDIS->rcItem.right, lpDIS->rcItem.bottom-1);
  97. }
  98. }
  99. BOOL CXTHeaderCtrlTheme::OnDrawBackgroundWinThemed(LPDRAWITEMSTRUCT lpDIS)
  100. {
  101. if ((GetDrawStyle() & XTTHEME_HOTTRACKING) == 0)
  102. return FALSE;
  103. if (m_themeWrapper.DrawThemeBackground(lpDIS->hDC,
  104. 0, HIS_NORMAL, &lpDIS->rcItem, NULL) != S_OK)
  105. {
  106. TRACE0("Error drawing background using WinTheme API.n");
  107. return FALSE;
  108. }
  109. return TRUE;
  110. }
  111. BOOL CXTHeaderCtrlTheme::OnDrawItemBackgroundWinThemed(LPDRAWITEMSTRUCT lpDIS)
  112. {
  113. int iState = HIS_NORMAL;
  114. if (lpDIS->itemState & ODS_HOTLIGHT)
  115. iState = HIS_HOT;
  116. if (lpDIS->itemState & ODS_SELECTED)
  117. iState = HIS_PRESSED;
  118. if (m_themeWrapper.DrawThemeBackground(lpDIS->hDC,
  119. HP_HEADERITEM, iState, &lpDIS->rcItem, NULL) != S_OK)
  120. {
  121. TRACE0("Error drawing background using WinTheme API.n");
  122. return FALSE;
  123. }
  124. return TRUE;
  125. }
  126. void CXTHeaderCtrlTheme::DrawSortArrow(CDC* pDC, LPPOINT ptsArrow, BOOL bAscending)
  127. {
  128. CXTPPenDC dcPen(pDC->m_hDC, bAscending ? m_cr3DHighLight : m_cr3DShadow);
  129. pDC->MoveTo(ptsArrow[2]);
  130. pDC->LineTo(ptsArrow[bAscending ? 1 : 0]);
  131. pDC->LineTo(ptsArrow[bAscending ? 0 : 1]);
  132. dcPen.Color(bAscending ? m_cr3DShadow : m_cr3DHighLight);
  133. pDC->MoveTo(ptsArrow[bAscending ? 0 : 2]);
  134. pDC->LineTo(ptsArrow[bAscending ? 2 : 1]);
  135. }
  136. void CXTHeaderCtrlTheme::OnDrawItemSortArrow(LPDRAWITEMSTRUCT lpDIS, BOOL bAscending)
  137. {
  138. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  139. CRect rcItem = lpDIS->rcItem;
  140. CPoint point;
  141. point.x = rcItem.right + m_iArrowPadding;
  142. point.y = (rcItem.top - 1) + (rcItem.Height() - m_sizeArrow.cy) / 2;
  143. if (point.x < rcItem.left)
  144. return;
  145. if (lpDIS->itemState == ODS_SELECTED)
  146. point.Offset(1, 1);
  147. CRect rcArrow;
  148. rcArrow.left = point.x;
  149. rcArrow.top = point.y;
  150. rcArrow.right = point.x + m_sizeArrow.cx;
  151. rcArrow.bottom = point.y + m_sizeArrow.cy;
  152. int x = point.x + (m_sizeArrow.cx/2);
  153. //  int y = point.y + (m_sizeArrow.cy/2);
  154. POINT ptsArrow[3];
  155. ptsArrow[0].x = x-m_sizeArrow.cx/2;
  156. ptsArrow[0].y = bAscending ? rcArrow.bottom : rcArrow.top;
  157. ptsArrow[1].x = x+m_sizeArrow.cx/2;
  158. ptsArrow[1].y = bAscending ? rcArrow.bottom : rcArrow.top;
  159. ptsArrow[2].x = x;
  160. ptsArrow[2].y = bAscending ? rcArrow.top : rcArrow.bottom;
  161. DrawSortArrow(pDC, ptsArrow, bAscending);
  162. }
  163. void CXTHeaderCtrlTheme::OnDrawItemText(LPDRAWITEMSTRUCT lpDIS, CXTHeaderCtrl* pHeaderCtrl)
  164. {
  165. ASSERT_VALID(pHeaderCtrl);
  166. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  167. LPHDITEM lpHDI = (LPHDITEM)lpDIS->itemData;
  168. // prepare the device context to draw text.
  169. CXTPFontDC fontDC(pDC, pHeaderCtrl->GetFont());
  170. // construct text size.
  171. CRect rcItem(lpDIS->rcItem);
  172. rcItem.DeflateRect(m_sizePadding.cx, 0);
  173. BOOL bSortAsc;
  174. UINT nSortItem = pHeaderCtrl->GetSortedCol(&bSortAsc);
  175. if (nSortItem == lpDIS->itemID)
  176. rcItem.right -= m_sizeArrow.cx + m_iArrowPadding*2;
  177. CRect rcText(rcItem);
  178. CSize sizeText = pDC->GetTextExtent(lpHDI->pszText);
  179. rcText.top = (m_sizePadding.cy > 0) ?
  180. m_sizePadding.cy : (rcItem.Height()-sizeText.cy)/2;
  181. rcText.bottom = rcText.top + sizeText.cy;
  182. if ((lpHDI->fmt & HDF_BITMAP && lpHDI->hbm != NULL) || (lpHDI->fmt & HDF_IMAGE))
  183. {
  184. if (lpHDI->fmt & HDF_BITMAP_ON_RIGHT)
  185. {
  186. CRect rcImage(rcText);
  187. rcImage.left += sizeText.cx + m_sizePadding.cx;
  188. OnDrawItemBitmap(lpDIS, rcImage, pHeaderCtrl);
  189. }
  190. else
  191. {
  192. OnDrawItemBitmap(lpDIS, rcText, pHeaderCtrl);
  193. }
  194. }
  195. // determine justification for text.
  196. switch (lpHDI->fmt & HDF_JUSTIFYMASK)
  197. {
  198. case HDF_LEFT:
  199. rcText.right = rcText.left + sizeText.cx;
  200. break;
  201. case HDF_CENTER:
  202. rcText.left += (rcItem.Width()-sizeText.cx)/2;
  203. rcText.right = rcText.left + sizeText.cx;
  204. break;
  205. case HDF_RIGHT:
  206. rcText.left = rcText.right - sizeText.cx;
  207. break;
  208. }
  209. // size text to fit available display area.
  210. rcText.left = __max(rcText.left, rcItem.left);
  211. rcText.right = __min(rcText.right, rcItem.right);
  212. // check if we are sorting.
  213. if (HasSortArrow() && nSortItem == lpDIS->itemID)
  214. {
  215. lpDIS->rcItem = rcText;
  216. OnDrawItemSortArrow(lpDIS, bSortAsc);
  217. }
  218. if (rcText.Width() > 0)
  219. {
  220. if (lpDIS->itemState == ODS_SELECTED)
  221. rcText.OffsetRect(1, 1);
  222. // draw text.
  223. pDC->DrawText(lpHDI->pszText, &rcText,
  224. DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS);
  225. }
  226. }
  227. void CXTHeaderCtrlTheme::DrawHeader(CDC* pDC, CXTHeaderCtrl* pHeaderCtrl)
  228. {
  229. ASSERT_VALID(pHeaderCtrl);
  230. CXTPClientRect rcClient(pHeaderCtrl);
  231. DRAWITEMSTRUCT dis;
  232. dis.CtlType = ODT_BUTTON;
  233. dis.CtlID = 0;
  234. dis.itemID = 0;
  235. dis.itemAction = ODA_DRAWENTIRE;
  236. dis.itemState = 0;
  237. dis.hwndItem = pHeaderCtrl->m_hWnd;
  238. dis.hDC = pDC->m_hDC;
  239. dis.rcItem = rcClient;
  240. dis.itemData = 0;
  241. // draw background.
  242. if (!m_bUseWinThemes || !OnDrawBackgroundWinThemed(&dis))
  243. OnDrawBackground(&dis);
  244. // set text attributes.
  245. CXTPFontDC fontDC(pDC, pHeaderCtrl->GetFont());
  246. pDC->SetBkColor(m_cr3DFace);
  247. pDC->SetTextColor(m_crText);
  248. pDC->SetBkMode(TRANSPARENT);
  249. // Set up the header item order array.
  250. HD_ITEM hdi;
  251. ::ZeroMemory(&hdi, sizeof(HD_ITEM));
  252. hdi.fmt = HDF_STRING | HDF_LEFT | HDF_BITMAP;
  253. hdi.mask = HDI_WIDTH | HDI_TEXT | HDI_FORMAT | HDI_ORDER | HDI_BITMAP | HDI_LPARAM;
  254. int cxy = 0;
  255. int iItem = 0;
  256. int iItemCount = pHeaderCtrl->GetItemCount();
  257. int *plItems = new int[iItemCount];
  258. for (iItem = 0; iItem < iItemCount; iItem++)
  259. {
  260. pHeaderCtrl->GetItem(iItem, &hdi);
  261. plItems[hdi.iOrder] = iItem;
  262. }
  263. hdi.fmt = HDF_STRING | HDF_LEFT | HDF_BITMAP;
  264. hdi.mask = HDI_WIDTH | HDI_TEXT | HDI_FORMAT | HDI_BITMAP | HDI_LPARAM;
  265. // get cursor position.
  266. CPoint point;
  267. ::GetCursorPos(&point);
  268. pHeaderCtrl->ScreenToClient(&point);
  269. // Draw each header item
  270. for (iItem = 0; iItem < iItemCount; ++iItem)
  271. {
  272. // Get the header item text and format
  273. TCHAR szBuffer[256];
  274. hdi.pszText = szBuffer;
  275. hdi.cchTextMax = 255;
  276. pHeaderCtrl->GetItem(plItems[iItem], &hdi);
  277. // initialize draw item structure.
  278. dis.itemID = plItems[iItem];
  279. dis.itemState = 0;
  280. dis.rcItem = rcClient;
  281. dis.rcItem.left = cxy;
  282. dis.rcItem.right = dis.rcItem.left + hdi.cxy;
  283. dis.itemData = (DWORD_PTR)&hdi;
  284. // if hot tracking is enabled, set the state.
  285. if (GetDrawStyle() & XTTHEME_HOTTRACKING)
  286. {
  287. if (pHeaderCtrl->HitTest(point) == plItems[iItem])
  288. dis.itemState = ODS_HOTLIGHT;
  289. }
  290. // check if the item is selected
  291. if (pHeaderCtrl->ItemPressed(plItems[iItem]))
  292. dis.itemState = ODS_SELECTED;
  293. // draw the item background.
  294. if (!m_bUseWinThemes || !OnDrawItemBackgroundWinThemed(&dis))
  295. OnDrawItemBackground(&dis);
  296. // draw the item text.
  297. OnDrawItemText(&dis, pHeaderCtrl);
  298. cxy += hdi.cxy;
  299. }
  300. delete [] plItems;
  301. }
  302. BOOL CXTHeaderCtrlTheme::UseWinXPThemes(CXTHeaderCtrl* pHeaderCtrl)
  303. {
  304. ASSERT_VALID(pHeaderCtrl);
  305. // if windows xp themes are not allowed, return FALSE.
  306. if ((GetDrawStyle() & XTTHEME_WINXPTHEMES) == 0)
  307. return FALSE;
  308. // if we got this far then we try to load the theme data for
  309. // this control if it is not currently open.
  310. if (!m_themeWrapper.ThemeDataOpen())
  311. m_themeWrapper.OpenThemeData(pHeaderCtrl->m_hWnd, L"HEADER");
  312. // if our application is not "Theme Ready" meaning that we cannot
  313. // display Windows XP themes, then return FALSE.
  314. if (!m_themeWrapper.IsAppThemeReady())
  315. return FALSE;
  316. // this will return TRUE if we can display visual styles.
  317. return m_themeWrapper.ThemeDataOpen();
  318. }
  319. void CXTHeaderCtrlTheme::SetDrawStyle(DWORD dwDrawStyle, CXTHeaderCtrl* pHeaderCtrl)
  320. {
  321. m_dwDrawStyle = dwDrawStyle;
  322. m_bUseWinThemes = UseWinXPThemes(pHeaderCtrl) && ((m_dwDrawStyle & XTTHEME_WINXPTHEMES) != 0);
  323. }
  324. DWORD CXTHeaderCtrlTheme::GetDrawStyle() const
  325. {
  326. return m_dwDrawStyle;
  327. }
  328. BOOL CXTHeaderCtrlTheme::Layout(LPHDLAYOUT lpHDL, CXTHeaderCtrl* pHeaderCtrl)
  329. {
  330. ASSERT_VALID(pHeaderCtrl);
  331. return (BOOL)pHeaderCtrl->DefWindowProc(HDM_LAYOUT,
  332. (WPARAM)0, (LPARAM)lpHDL);
  333. }
  334. BOOL CXTHeaderCtrlTheme::SetBitmap(int iCol, UINT uBitmapID, BOOL bRemove, COLORREF crMask, CXTHeaderCtrl* pHeaderCtrl)
  335. {
  336. ASSERT_VALID(pHeaderCtrl);
  337. // reset header image list
  338. HD_ITEM hdi;
  339. ::ZeroMemory(&hdi, sizeof(HD_ITEM));
  340. hdi.mask = HDI_BITMAP | HDI_FORMAT;
  341. pHeaderCtrl->GetItem(iCol, &hdi);
  342. // free previous GDI resources.
  343. if (hdi.fmt & HDF_BITMAP && hdi.hbm != NULL)
  344. ::ImageList_Destroy((HIMAGELIST)hdi.hbm);
  345. hdi.hbm = NULL;
  346. hdi.fmt &= ~HDF_BITMAP;
  347. pHeaderCtrl->SetItem(iCol, &hdi);
  348. pHeaderCtrl->RedrawWindow();
  349. // add new image list
  350. if (!bRemove)
  351. {
  352. HBITMAP hBitmap = (HBITMAP)::LoadImage(AfxGetResourceHandle(),
  353. MAKEINTRESOURCE(uBitmapID), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
  354. if (hBitmap == NULL)
  355. return FALSE;
  356. BITMAP bmpInfo;
  357. ZeroMemory(&bmpInfo, sizeof(BITMAP));
  358. if (::GetObject(hBitmap, sizeof(BITMAP), &bmpInfo) == 0)
  359. return FALSE;
  360. HIMAGELIST hImageList = ::ImageList_Create(bmpInfo.bmWidth,
  361. bmpInfo.bmHeight, ILC_MASK | ILC_COLOR24, 0, 1);
  362. if (hImageList == NULL)
  363. return FALSE;
  364. if (::ImageList_AddMasked(hImageList, hBitmap, crMask) == -1)
  365. {
  366. ::ImageList_Destroy(hImageList);
  367. ::DeleteObject(hBitmap);
  368. return FALSE;
  369. }
  370. // we are actually storing a handle to the image list and
  371. // not the bitmap so we can draw using the mask.
  372. hdi.hbm = (HBITMAP)hImageList;
  373. hdi.fmt = HDF_BITMAP;
  374. pHeaderCtrl->SetItem(iCol, &hdi);
  375. pHeaderCtrl->RedrawWindow();
  376. ::DeleteObject(hBitmap);
  377. return TRUE;
  378. }
  379. return FALSE;
  380. }
  381. void CXTHeaderCtrlTheme::OnDrawItemBitmap(LPDRAWITEMSTRUCT lpDIS, CRect& rcText, CXTHeaderCtrl* pHeaderCtrl)
  382. {
  383. ASSERT_VALID(pHeaderCtrl);
  384. HDITEM hdi;
  385. hdi.mask = HDI_BITMAP | HDI_FORMAT | HDI_IMAGE;
  386. pHeaderCtrl->GetItem(lpDIS->itemID, &hdi);
  387. HIMAGELIST hImageList = 0;
  388. int nIndex = -1;
  389. if (hdi.fmt & HDF_BITMAP && hdi.hbm != NULL)
  390. {
  391. hImageList = (HIMAGELIST)hdi.hbm;
  392. nIndex = 0;
  393. }
  394. else if (hdi.fmt & HDF_IMAGE)
  395. {
  396. hImageList = (HIMAGELIST)pHeaderCtrl->SendMessage(HDM_GETIMAGELIST);
  397. nIndex = hdi.iImage;
  398. }
  399. if (nIndex != -1 && (hdi.fmt & HDF_IMAGE) && pHeaderCtrl->GetImageManager())
  400. {
  401. CXTPImageManagerIcon* pIcon = pHeaderCtrl->GetImageManager()->GetImage(nIndex, 0);
  402. if (pIcon)
  403. {
  404. CRect rcItem(lpDIS->rcItem);
  405. CPoint point(rcText.left,  (rcItem.Height() - pIcon->GetHeight()) / 2);
  406. rcText.left += pIcon->GetWidth() + m_sizePadding.cx;
  407. XTPImageState imageState = (lpDIS->itemState & ODS_SELECTED) ? xtpImageChecked :
  408. (lpDIS->itemState & ODS_HOTLIGHT) ? xtpImageHot : xtpImageNormal;
  409. if (lpDIS->itemState == ODS_SELECTED)
  410. point.Offset(1, 1);
  411. if (point.x + pIcon->GetWidth() > lpDIS->rcItem.right)
  412. return;
  413. // draw image transparently.
  414. pIcon->Draw(CDC::FromHandle(lpDIS->hDC), point, pIcon->GetIcon(imageState));
  415. return;
  416. }
  417. }
  418. if (hImageList)
  419. {
  420. int cx, cy;
  421. if (::ImageList_GetIconSize(hImageList, &cx, &cy) && (nIndex < ImageList_GetImageCount(hImageList)))
  422. {
  423. CRect rcItem(lpDIS->rcItem);
  424. CPoint point(rcText.left,  (rcItem.Height() - cy) / 2);
  425. rcText.left += cx + m_sizePadding.cx;
  426. if (lpDIS->itemState == ODS_SELECTED)
  427. point.Offset(1, 1);
  428. if (point.x + cx > lpDIS->rcItem.right)
  429. return;
  430. // draw image transparently.
  431. ::ImageList_Draw(hImageList, nIndex, lpDIS->hDC, point.x, point.y, ILD_TRANSPARENT);
  432. }
  433. }
  434. }
  435. void CXTHeaderCtrlTheme::CleanUp(CXTHeaderCtrl* pHeaderCtrl)
  436. {
  437. ASSERT_VALID(pHeaderCtrl);
  438. // free GDI resources
  439. for (int i = 0; i < pHeaderCtrl->GetItemCount(); ++i)
  440. {
  441. HDITEM hdi;
  442. hdi.mask = HDI_FORMAT | HDI_BITMAP;
  443. pHeaderCtrl->GetItem(i, &hdi);
  444. if (hdi.fmt & HDF_BITMAP && hdi.hbm != NULL)
  445. {
  446. ::ImageList_Destroy((HIMAGELIST)hdi.hbm);
  447. }
  448. }
  449. }
  450. //=============================================================================
  451. // CXTHeaderCtrlThemeOfficeXP
  452. //=============================================================================
  453. CXTHeaderCtrlThemeOfficeXP::CXTHeaderCtrlThemeOfficeXP()
  454. {
  455. m_dwDrawStyle = XTTHEME_SORTARROW;
  456. }
  457. CXTHeaderCtrlThemeOfficeXP::~CXTHeaderCtrlThemeOfficeXP()
  458. {
  459. }
  460. void CXTHeaderCtrlThemeOfficeXP::OnDrawBackground(LPDRAWITEMSTRUCT lpDIS)
  461. {
  462. CRect rcItem(lpDIS->rcItem);
  463. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  464. // fill background
  465. pDC->FillSolidRect(&rcItem, m_cr3DFace);
  466. rcItem.right += 2;
  467. // draw 3D borders.
  468. pDC->Draw3dRect(&rcItem, m_cr3DHighLight, m_cr3DShadow);
  469. }
  470. void CXTHeaderCtrlThemeOfficeXP::OnDrawItemBackground(LPDRAWITEMSTRUCT lpDIS)
  471. {
  472. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  473. if (lpDIS->itemState == ODS_SELECTED)
  474. {
  475. CXTPPenDC penDC(lpDIS->hDC, m_cr3DShadow);
  476. pDC->MoveTo(lpDIS->rcItem.right-2, 2);
  477. pDC->LineTo(lpDIS->rcItem.right-2, lpDIS->rcItem.bottom-2);
  478. penDC.Color(m_cr3DHighLight);
  479. pDC->MoveTo(lpDIS->rcItem.right-1, 2);
  480. pDC->LineTo(lpDIS->rcItem.right-1, lpDIS->rcItem.bottom-2);
  481. }
  482. else
  483. {
  484. CXTPPenDC penDC(lpDIS->hDC, m_cr3DShadow);
  485. pDC->MoveTo(lpDIS->rcItem.right-2, 2);
  486. pDC->LineTo(lpDIS->rcItem.right-2, lpDIS->rcItem.bottom-2);
  487. penDC.Color(m_cr3DHighLight);
  488. pDC->MoveTo(lpDIS->rcItem.right-1, 2);
  489. pDC->LineTo(lpDIS->rcItem.right-1, lpDIS->rcItem.bottom-2);
  490. }
  491. }
  492. //=============================================================================
  493. // CXTHeaderCtrlThemeOffice2003
  494. //=============================================================================
  495. CXTHeaderCtrlThemeOffice2003::CXTHeaderCtrlThemeOffice2003()
  496. {
  497. m_dwDrawStyle = XTTHEME_SORTARROW;
  498. m_sizePadding = CSize(6, 0);
  499. }
  500. CXTHeaderCtrlThemeOffice2003::~CXTHeaderCtrlThemeOffice2003()
  501. {
  502. }
  503. void CXTHeaderCtrlThemeOffice2003::OnDrawBackground(LPDRAWITEMSTRUCT lpDIS)
  504. {
  505. CRect rcItem(lpDIS->rcItem);
  506. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  507. // fill background
  508. pDC->FillSolidRect(&rcItem, m_cr3DFace);
  509. rcItem.right += 2;
  510. // draw 3D borders.
  511. pDC->Draw3dRect(&rcItem, m_cr3DHighLight, MixColor(m_cr3DFace, m_cr3DShadow, 0.6));
  512. CXTPPenDC penDC(lpDIS->hDC, MixColor(m_cr3DFace, m_cr3DShadow, 0.4));
  513. pDC->MoveTo(rcItem.left, rcItem.bottom-2);
  514. pDC->LineTo(rcItem.right, rcItem.bottom-2);
  515. penDC.Color(MixColor(m_cr3DFace, m_cr3DShadow, 0.25));
  516. pDC->MoveTo(rcItem.left, rcItem.bottom-3);
  517. pDC->LineTo(rcItem.right, rcItem.bottom-3);
  518. }
  519. void CXTHeaderCtrlThemeOffice2003::OnDrawItemBackground(LPDRAWITEMSTRUCT lpDIS)
  520. {
  521. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  522. if (lpDIS->itemState == ODS_SELECTED)
  523. {
  524. CXTPPenDC penDC(lpDIS->hDC, m_cr3DShadow);
  525. pDC->MoveTo(lpDIS->rcItem.right-2, 2);
  526. pDC->LineTo(lpDIS->rcItem.right-2, lpDIS->rcItem.bottom-4);
  527. penDC.Color(m_cr3DHighLight);
  528. pDC->MoveTo(lpDIS->rcItem.right-1, 2);
  529. pDC->LineTo(lpDIS->rcItem.right-1, lpDIS->rcItem.bottom-4);
  530. }
  531. else
  532. {
  533. CXTPPenDC penDC(lpDIS->hDC, m_cr3DShadow);
  534. pDC->MoveTo(lpDIS->rcItem.right-2, 2);
  535. pDC->LineTo(lpDIS->rcItem.right-2, lpDIS->rcItem.bottom-4);
  536. penDC.Color(m_cr3DHighLight);
  537. pDC->MoveTo(lpDIS->rcItem.right-1, 2);
  538. pDC->LineTo(lpDIS->rcItem.right-1, lpDIS->rcItem.bottom-4);
  539. }
  540. }
  541. BOOL CXTHeaderCtrlThemeOffice2003::Layout(LPHDLAYOUT lpHDL, CXTHeaderCtrl* pHeaderCtrl)
  542. {
  543. ASSERT_VALID(pHeaderCtrl);
  544. LPRECT      pRC = lpHDL->prc;
  545. LPWINDOWPOS pWP = lpHDL->pwpos;
  546. CWindowDC dc(NULL);
  547. CXTPFontDC fontDC(&dc, pHeaderCtrl->GetFont());
  548. TEXTMETRIC tm;
  549. dc.GetTextMetrics(&tm);
  550. int iHeight = tm.tmHeight + 10;
  551. pWP->hwndInsertAfter = 0;
  552. pWP->x = pRC->left;
  553. pWP->cx = pRC->right - pRC->left;
  554. pWP->cy = iHeight;
  555. pWP->y = pRC->top;
  556. pRC->top += iHeight;
  557. pWP->flags = SWP_NOACTIVATE | SWP_NOZORDER;
  558. return TRUE;
  559. }
  560. //=============================================================================
  561. // CXTHeaderCtrlThemeExplorer
  562. //=============================================================================
  563. CXTHeaderCtrlThemeExplorer::CXTHeaderCtrlThemeExplorer()
  564. {
  565. m_dwDrawStyle = XTTHEME_WINXPTHEMES | XTTHEME_HOTTRACKING | XTTHEME_SORTARROW;
  566. m_sizePadding = CSize(6, 0);
  567. m_sizeArrow = CSize(8, 4);
  568. }
  569. CXTHeaderCtrlThemeExplorer::~CXTHeaderCtrlThemeExplorer()
  570. {
  571. }
  572. BOOL CXTHeaderCtrlThemeExplorer::OnDrawItemBackgroundWinThemed(LPDRAWITEMSTRUCT lpDIS)
  573. {
  574. return CXTHeaderCtrlTheme::OnDrawItemBackgroundWinThemed(lpDIS);
  575. }
  576. BOOL CXTHeaderCtrlThemeExplorer::Layout(LPHDLAYOUT lpHDL, CXTHeaderCtrl* pHeaderCtrl)
  577. {
  578. ASSERT_VALID(pHeaderCtrl);
  579. LPRECT      pRC = lpHDL->prc;
  580. LPWINDOWPOS pWP = lpHDL->pwpos;
  581. CWindowDC dc(NULL);
  582. CXTPFontDC fontDC(&dc, pHeaderCtrl->GetFont());
  583. TEXTMETRIC tm;
  584. dc.GetTextMetrics(&tm);
  585. int iHeight = tm.tmHeight + 6;
  586. pWP->hwndInsertAfter = 0;
  587. pWP->x = pRC->left;
  588. pWP->cx = pRC->right - pRC->left;
  589. pWP->cy = iHeight;
  590. pWP->y = pRC->top;
  591. pRC->top += iHeight;
  592. pWP->flags = SWP_NOACTIVATE | SWP_NOZORDER;
  593. return TRUE;
  594. }
  595. void CXTHeaderCtrlThemeExplorer::DrawSortArrow(CDC* pDC, LPPOINT ptsArrow, BOOL /*bAscending*/)
  596. {
  597. CXTPPenDC   dcPen(pDC->m_hDC, RGB(172, 168, 153));
  598. CXTPBrushDC dcBrush(pDC->m_hDC, RGB(172, 168, 153));
  599. pDC->SetPolyFillMode(WINDING);
  600. pDC->Polygon(ptsArrow, 3);
  601. }