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

对话框与窗口

开发平台:

Visual C++

  1. // XTPSkinObjectHeader.cpp: implementation of the CXTPSkinObjectHeader class.
  2. //
  3. // This file is a part of the XTREME SKINFRAMEWORK 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 "Common/XTPDrawHelpers.h"
  22. #include "XTPSkinObjectHeader.h"
  23. #include "XTPSkinManager.h"
  24. #ifdef _DEBUG
  25. #undef THIS_FILE
  26. static char THIS_FILE[]=__FILE__;
  27. #define new DEBUG_NEW
  28. #endif
  29. //////////////////////////////////////////////////////////////////////
  30. // Construction/Destruction
  31. //////////////////////////////////////////////////////////////////////
  32. IMPLEMENT_DYNCREATE(CXTPSkinObjectHeader, CXTPSkinObjectFrame)
  33. CXTPSkinObjectHeader::CXTPSkinObjectHeader()
  34. {
  35. m_strClassName = _T("HEADER");
  36. m_bLBtnDown = FALSE;
  37. m_nHotItem = -1;
  38. }
  39. CXTPSkinObjectHeader::~CXTPSkinObjectHeader()
  40. {
  41. }
  42. BEGIN_MESSAGE_MAP(CXTPSkinObjectHeader, CXTPSkinObjectFrame)
  43. //{{AFX_MSG_MAP(CXTPSkinObjectHeader)
  44. ON_WM_PAINT()
  45. ON_WM_LBUTTONDOWN()
  46. ON_WM_LBUTTONUP()
  47. ON_WM_MOUSEMOVE()
  48. ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
  49. ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
  50. //}}AFX_MSG_MAP
  51. END_MESSAGE_MAP()
  52. /////////////////////////////////////////////////////////////////////////////
  53. // CXTPSkinObjectHeader message handlers
  54. void CXTPSkinObjectHeader::OnLButtonDown(UINT nFlags, CPoint point)
  55. {
  56. UINT uFlags = 0;
  57. if (HitTest(point, &uFlags) != -1 && ((uFlags & HHT_ONHEADER) == HHT_ONHEADER))
  58. {
  59. m_bLBtnDown = TRUE;
  60. }
  61. CXTPSkinObjectFrame::OnLButtonDown(nFlags, point);
  62. }
  63. void CXTPSkinObjectHeader::OnLButtonUp(UINT nFlags, CPoint point)
  64. {
  65. if (m_bLBtnDown)
  66. {
  67. m_bLBtnDown = FALSE;
  68. Invalidate(FALSE);
  69. }
  70. CXTPSkinObjectFrame::OnLButtonUp(nFlags, point);
  71. }
  72. int CXTPSkinObjectHeader::HitTest(CPoint pt, UINT* pFlags /*=NULL*/) const
  73. {
  74. HDHITTESTINFO hti;
  75. hti.pt.x = pt.x;
  76. hti.pt.y = pt.y;
  77. int iItem = (int)::SendMessage(m_hWnd, HDM_HITTEST, 0, (LPARAM)(&hti));
  78. if (pFlags != NULL)
  79. *pFlags = hti.flags;
  80. return iItem;
  81. }
  82. void CXTPSkinObjectHeader::OnMouseMove(UINT nFlags, CPoint point)
  83. {
  84. int nHotItem = HitTest(point);
  85. if (nHotItem != m_nHotItem)
  86. {
  87. m_nHotItem = nHotItem;
  88. Invalidate(FALSE);
  89. if (m_nHotItem != -1)
  90. {
  91. TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd, HOVER_DEFAULT};
  92. _TrackMouseEvent(&tme);
  93. }
  94. }
  95. CXTPSkinObjectFrame::OnMouseMove(nFlags, point);
  96. }
  97. void CXTPSkinObjectHeader::OnMouseLeave()
  98. {
  99. OnMouseMove(0, CPoint(-1, -1));
  100. }
  101. #ifndef HDS_FILTERBAR
  102. #define HDS_FILTERBAR 0x0100
  103. #endif
  104. LRESULT CXTPSkinObjectHeader::OnPrintClient(WPARAM wParam, LPARAM lParam)
  105. {
  106. if ((lParam & PRF_CLIENT) == 0)
  107. return Default();
  108. CDC* pDC = CDC::FromHandle((HDC)wParam);
  109. if (pDC) OnDraw(pDC);
  110. return 1;
  111. }
  112. void CXTPSkinObjectHeader::OnPaint()
  113. {
  114. CXTPSkinObjectPaintDC dc(this);
  115. OnDraw(&dc);
  116. }
  117. void CXTPSkinObjectHeader::OnDraw(CDC* pDC)
  118. {
  119. CXTPClientRect rcClient(this);
  120. CRect rcBackground(rcClient);
  121. CXTPBufferDC dc(*pDC, rcClient);
  122. BOOL bFilterBar = (GetStyle() & HDS_FILTERBAR) && XTPSystemVersion()->GetComCtlVersion() >= MAKELONG(80, 5);
  123. CRect rcFilter(0, 0, 0, 0);
  124. dc.FillSolidRect(rcClient, GetColor(COLOR_3DFACE));
  125. if (bFilterBar)
  126. {
  127. INT cyFilter = (rcClient.Height() - 1)/2;
  128. rcFilter = rcClient;
  129. rcClient.bottom = rcClient.top + cyFilter;
  130. rcFilter.top = rcClient.bottom;
  131. DefWindowProc(WM_PAINT, (WPARAM)dc.GetSafeHdc(), 0);
  132. }
  133. CXTPSkinManagerClass* pClass = GetSkinClass();
  134. CXTPFontDC fontDC(&dc, GetFont());
  135. dc.SetTextColor(GetColor(COLOR_BTNTEXT));
  136. dc.SetBkMode(TRANSPARENT);
  137. CHeaderCtrl* pHeaderCtrl = (CHeaderCtrl*)this;
  138. int iItemCount = pHeaderCtrl->GetItemCount();
  139. // Draw each header item
  140. for (int iItem = 0; iItem < iItemCount; ++iItem)
  141. {
  142. int nIndex = Header_OrderToIndex(m_hWnd, iItem);
  143. // initialize draw item structure.
  144. CRect rcItem(0, 0, 0, 0);
  145. Header_GetItemRect(m_hWnd, nIndex, &rcItem);
  146. if ((rcItem.right < rcClient.left) || (rcItem.left > rcClient.right))
  147. continue;
  148. if (bFilterBar)
  149. {
  150. rcItem.bottom = rcFilter.top;
  151. }
  152. int nState = HIS_NORMAL;
  153. if (nIndex == m_nHotItem)
  154. {
  155. nState = m_bLBtnDown ? HIS_PRESSED : HIS_HOT;
  156. }
  157. rcBackground.left = max(rcBackground.left, rcItem.right);
  158. pClass->DrawThemeBackground(&dc, HP_HEADERITEM, nState, &rcItem);
  159. DrawItemEntry(&dc, nIndex, rcItem, nState);
  160. }
  161. if (rcBackground.left < rcBackground.right)
  162. pClass->DrawThemeBackground(&dc, 0, 0, &rcBackground);
  163. }
  164. #ifndef HDM_GETBITMAPMARGIN
  165. #define HDM_GETBITMAPMARGIN          (HDM_FIRST + 21)
  166. #endif
  167. #ifndef HDF_SORTUP
  168. #define HDF_SORTUP              0x0400
  169. #define HDF_SORTDOWN            0x0200
  170. #endif
  171. void CXTPSkinObjectHeader::DrawItemEntry(CDC* pDC, int nIndex, CRect rcItem, int nState)
  172. {
  173. CHeaderCtrl* pHeaderCtrl = (CHeaderCtrl*)this;
  174. CImageList* pImageList = CImageList::FromHandle((HIMAGELIST)
  175. ::SendMessage(pHeaderCtrl->m_hWnd, HDM_GETIMAGELIST, 0, 0L));
  176. // Set up the header item order array.
  177. HD_ITEM hdi;
  178. ::ZeroMemory(&hdi, sizeof(HD_ITEM));
  179. hdi.fmt = HDF_STRING | HDF_IMAGE;
  180. hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_IMAGE | HDI_LPARAM;
  181. // Get the header item text and format
  182. CString strCaption;
  183. LPTSTR pszText = strCaption.GetBuffer(256);
  184. pszText[0] = 0;
  185. hdi.pszText = pszText;
  186. hdi.cchTextMax = 255;
  187. BOOL bResult = pHeaderCtrl->GetItem(nIndex, &hdi);
  188. strCaption.ReleaseBuffer();
  189. #ifdef _UNICODE
  190. if (!bResult)
  191. {
  192. char tText[256];
  193. tText[0] = 0;
  194. HD_ITEMA hdia;
  195. ::ZeroMemory(&hdia, sizeof(HD_ITEMA));
  196. hdia.fmt = HDF_STRING | HDF_IMAGE;
  197. hdia.mask = HDI_TEXT | HDI_FORMAT | HDI_IMAGE | HDI_LPARAM;
  198. // Get the header item text and format
  199. hdia.pszText = tText;
  200. hdia.cchTextMax = 255;
  201. ::SendMessage(pHeaderCtrl->m_hWnd, HDM_GETITEMA, nIndex, (LPARAM)&hdia);
  202. strCaption = tText;
  203. hdi.fmt = hdia.fmt;
  204. hdi.iImage = hdia.iImage;
  205. hdi.lParam = hdia.lParam;
  206. }
  207. #else
  208. bResult;
  209. #endif
  210. if (hdi.fmt & HDF_OWNERDRAW)
  211. {
  212. DRAWITEMSTRUCT dis;
  213. dis.CtlType = ODT_HEADER;
  214. dis.CtlID = (UINT)GetDlgCtrlID();
  215. dis.itemID = nIndex;
  216. dis.itemAction = ODA_DRAWENTIRE;
  217. dis.itemState = (nState == HIS_PRESSED) ? ODS_SELECTED : 0;
  218. dis.hwndItem = m_hWnd;
  219. dis.hDC = pDC->GetSafeHdc();
  220. dis.rcItem = rcItem;
  221. dis.itemData = hdi.lParam;
  222. // Now send it off to my parent...
  223. if (GetParent()->SendMessage(WM_DRAWITEM, dis.CtlID,
  224.    (LPARAM)(DRAWITEMSTRUCT*)&dis))
  225. {
  226. return;
  227. }
  228. }
  229. CRect rcText(rcItem);
  230. if (pImageList && (hdi.fmt & HDF_IMAGE) && hdi.iImage >= 0 && hdi.iImage < pImageList->GetImageCount())
  231. {
  232. int iBitmapMargin = (int)SendMessage(HDM_GETBITMAPMARGIN);
  233. if (iBitmapMargin == 0)
  234. iBitmapMargin = GetMetrics()->m_cxEdge * 3;
  235. int cxBitmap = 16, cyBitmap = 16;
  236. ImageList_GetIconSize(pImageList->GetSafeHandle(), &cxBitmap, &cyBitmap);
  237. CPoint pt(rcItem.left + iBitmapMargin, (rcItem.bottom + rcItem.top - cyBitmap) / 2);
  238. if (hdi.fmt & HDF_BITMAP_ON_RIGHT)
  239. {
  240. CSize sz = pDC->GetTextExtent(strCaption);
  241. pt.x += sz.cx + iBitmapMargin + 9;
  242. if (pt.x + cxBitmap > rcItem.right - 3)
  243. pt.x = max(rcItem.left + 6, rcItem.right - 3 - cxBitmap);
  244. if (nState == HIS_PRESSED)
  245. pt.x ++;
  246. pImageList->Draw(pDC, hdi.iImage, pt, ILD_TRANSPARENT);
  247. rcText.right = pt.x + 6;
  248. }
  249. else
  250. {
  251. if (nState == HIS_PRESSED)
  252. pt.x ++;
  253. pImageList->Draw(pDC, hdi.iImage, pt, ILD_TRANSPARENT);
  254. rcText.left += cxBitmap + iBitmapMargin;
  255. }
  256. }
  257. if (((hdi.fmt & HDF_IMAGE) == 0) && ((hdi.fmt & HDF_SORTUP) || (hdi.fmt & HDF_SORTDOWN)))
  258. {
  259. int iBitmapMargin = GetMetrics()->m_cxEdge * 3;
  260. CSize sz = pDC->GetTextExtent(strCaption);
  261. CPoint pt(rcItem.left + iBitmapMargin, (rcItem.bottom + rcItem.top - 2) / 2);
  262. pt.x += sz.cx + iBitmapMargin + 9;
  263. if (pt.x + 9 > rcItem.right - 3)
  264. pt.x = max(rcItem.left + 6, rcItem.right - 3 - 9);
  265. if (hdi.fmt & HDF_SORTUP)
  266. {
  267. XTPDrawHelpers()->Triangle(pDC, CPoint(pt.x - 4, pt.y + 2),
  268. CPoint(pt.x, pt.y - 2), CPoint(pt.x + 4, pt.y + 2), GetColor(COLOR_3DSHADOW));
  269. }
  270. else
  271. {
  272. XTPDrawHelpers()->Triangle(pDC, CPoint(pt.x - 4, pt.y - 2),
  273. CPoint(pt.x, pt.y + 2), CPoint(pt.x + 4, pt.y - 2), GetColor(COLOR_3DSHADOW));
  274. }
  275. rcText.right = pt.x;
  276. }
  277. UINT nFormat = DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX;
  278. // determine justification for text.
  279. switch (hdi.fmt & HDF_JUSTIFYMASK)
  280. {
  281. case HDF_LEFT:
  282. nFormat |= DT_LEFT;
  283. rcText.DeflateRect(9, 0, 6, 0);
  284. break;
  285. case HDF_CENTER:
  286. nFormat |= DT_CENTER;
  287. rcText.DeflateRect(6, 0, 6, 0);
  288. break;
  289. case HDF_RIGHT:
  290. nFormat |= DT_RIGHT;
  291. rcText.DeflateRect(6, 0, 9, 0);
  292. break;
  293. }
  294. if (rcText.Width() > 0)
  295. {
  296. if (nState == HIS_PRESSED)
  297. rcText.OffsetRect(1, 1);
  298. // draw text.
  299. pDC->DrawText(strCaption, &rcText, nFormat);
  300. }
  301. }