MyHeaderCtrl.cpp
上传用户:popouu88
上传日期:2013-02-11
资源大小:2894k
文件大小:14k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. // MyHeaderCtrl.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "File.h"
  5. #include "MyHeaderCtrl.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CMyHeaderCtrl
  13. static const CString strOfficeFontName = _T("Tahoma");
  14. static const CString strDefaultFontName = _T("MS Sans Serif");
  15. static const CString strVertFontName = _T("Arial");
  16. static const CString strMarlettFontName = _T("Marlett");
  17. static int CALLBACK FontFamalyProcFonts (const LOGFONT FAR* lplf,
  18. const TEXTMETRIC FAR* /*lptm*/,
  19. ULONG /*ulFontType*/,
  20. LPARAM /*lParam*/)
  21. {
  22. ASSERT (lplf != NULL);
  23. CString strFont = lplf->lfFaceName;
  24. return strFont.CollateNoCase (strOfficeFontName) == 0 ? 0 : 1;
  25. }
  26. CMyHeaderCtrl::CMyHeaderCtrl()
  27. {
  28. m_bIsMousePressed = FALSE;
  29. m_bMultipleSort = FALSE;
  30. m_bAscending = TRUE;
  31. m_nHighlightedItem = -1;
  32. clrBtnFace = ::GetSysColor(COLOR_BTNFACE);
  33. clrBtnShadow = ::GetSysColor(COLOR_BTNSHADOW);
  34. clrBtnHilite = ::GetSysColor(COLOR_BTNHIGHLIGHT);
  35. clrBtnDkShadow = ::GetSysColor(COLOR_3DDKSHADOW);
  36. clrBtnLight = ::GetSysColor(COLOR_3DLIGHT);
  37. clrWindowFrame = ::GetSysColor(COLOR_WINDOWFRAME);
  38. clrBtnText = ::GetSysColor(COLOR_BTNTEXT);
  39. brBtnFace.Detach ();
  40. brBtnFace.CreateSysColorBrush (COLOR_BTNFACE);
  41. //------------------
  42. // Initialize fonts:
  43. //------------------
  44. NONCLIENTMETRICS info;
  45. info.cbSize = sizeof(info);
  46. ::SystemParametersInfo (SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
  47. LOGFONT lf;
  48. memset (&lf, 0, sizeof (LOGFONT));
  49. CWindowDC dc (NULL);
  50. lf.lfCharSet = (BYTE) GetTextCharsetInfo (dc.GetSafeHdc (), NULL, 0);
  51. lf.lfHeight = info.lfMenuFont.lfHeight;
  52. lf.lfWeight = info.lfMenuFont.lfWeight;
  53. lf.lfItalic = info.lfMenuFont.lfItalic;
  54. _tcscpy (lf.lfFaceName, info.lfMenuFont.lfFaceName);
  55. BOOL fUseSystemFont = (info.lfMenuFont.lfCharSet > SYMBOL_CHARSET);
  56. if (!fUseSystemFont)
  57. {
  58. if (::EnumFontFamilies (dc.GetSafeHdc (), NULL, FontFamalyProcFonts, 0) == 0)
  59. _tcscpy (lf.lfFaceName, strOfficeFontName);
  60. else _tcscpy (lf.lfFaceName, strDefaultFontName);
  61. }
  62. fontRegular.CreateFontIndirect (&lf);
  63. }
  64. CMyHeaderCtrl::~CMyHeaderCtrl()
  65. {
  66. }
  67. BEGIN_MESSAGE_MAP(CMyHeaderCtrl, CHeaderCtrl)
  68. //{{AFX_MSG_MAP(CMyHeaderCtrl)
  69. ON_WM_ERASEBKGND()
  70. ON_WM_PAINT()
  71. ON_WM_LBUTTONDOWN()
  72. ON_WM_LBUTTONUP()
  73. ON_WM_MOUSEMOVE()
  74. ON_WM_CANCELMODE()
  75. //}}AFX_MSG_MAP
  76. ON_MESSAGE(HDM_LAYOUT, OnLayout)
  77. ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
  78. END_MESSAGE_MAP()
  79. /////////////////////////////////////////////////////////////////////////////
  80. // CMyHeaderCtrl message handlers
  81. void CMyHeaderCtrl::OnDrawItem (CDC* pDC, int iItem, CRect rect, BOOL bIsPressed, BOOL bIsHighlighted)
  82. {
  83. ASSERT_VALID (this);
  84. ASSERT_VALID (pDC);
  85.  
  86.   const int nTextMargin = 5;
  87. //-------------
  88. // Draw border:
  89. //-------------
  90. if (bIsPressed)
  91. {
  92. pDC->Draw3dRect (rect,clrBtnShadow,clrBtnShadow);
  93. rect.left++; rect.top++;
  94. }else pDC->Draw3dRect (rect,clrBtnHilite,clrBtnShadow);
  95. if (iItem < 0) return;
  96. int nSortVal = 0;
  97. if (m_mapColumnsStatus.Lookup (iItem, nSortVal) && nSortVal != 0)
  98. {
  99. //-----------------
  100. // Draw sort arrow:
  101. //-----------------
  102. CRect rectArrow = rect;
  103. rectArrow.left = rectArrow.right - rectArrow.Height ();
  104. rect.right = rectArrow.left+1;
  105. m_bAscending = nSortVal > 0;
  106. OnDrawSortArrow (pDC, rectArrow);
  107. }
  108. HD_ITEM hdItem;
  109. memset (&hdItem, 0, sizeof (hdItem));
  110. hdItem.mask = HDI_FORMAT | HDI_BITMAP | HDI_TEXT | HDI_IMAGE;
  111. TCHAR szText [256];
  112. hdItem.pszText = szText;
  113. hdItem.cchTextMax = 255;
  114. if (!GetItem (iItem, &hdItem)) return;
  115. CBitmap bmp;
  116. bmp.LoadBitmap(IDB_BACK);
  117. BITMAP  bmpInfo;
  118. bmp.GetBitmap(&bmpInfo);
  119. CDC dcMem;
  120. dcMem.CreateCompatibleDC(pDC);
  121. CBitmap *pOldBitmap=dcMem.SelectObject(&bmp);
  122. pDC->StretchBlt(rect.left,rect.top,rect.Width()-1,rect.Height(),&dcMem,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY);
  123. dcMem.SelectObject(pOldBitmap);
  124. //-----------------------
  125. // Draw bitmap and image:
  126. //-----------------------
  127. if ((hdItem.fmt & HDF_IMAGE) && hdItem.iImage >= 0) 
  128. {
  129. //---------------------------------------
  130. // The column has a image from imagelist:
  131. //---------------------------------------
  132. CImageList* pImageList = GetImageList ();
  133. if (pImageList != NULL)
  134. {
  135. int cx = 0;
  136. int cy = 0;
  137. VERIFY (::ImageList_GetIconSize (*pImageList, &cx, &cy));
  138. CPoint pt = rect.TopLeft ();
  139. pt.x ++;
  140. pt.y = (rect.top + rect.bottom - cy) / 2;
  141. VERIFY (pImageList->Draw (pDC, hdItem.iImage, pt, ILD_NORMAL));
  142. rect.left += cx;
  143. }
  144. }
  145. if ((hdItem.fmt & (HDF_BITMAP | HDF_BITMAP_ON_RIGHT)) && hdItem.hbm != NULL)
  146. {
  147. CBitmap* pBmp = CBitmap::FromHandle (hdItem.hbm);
  148. ASSERT_VALID (pBmp);
  149. BITMAP bmp;
  150. pBmp->GetBitmap (&bmp);
  151. CRect rectBitmap = rect;
  152. if (hdItem.fmt & HDF_BITMAP_ON_RIGHT)
  153. {
  154. rectBitmap.right--;
  155. rect.right = rectBitmap.left = rectBitmap.right - bmp.bmWidth;
  156. }else
  157. {
  158. rectBitmap.left++;
  159. rect.left = rectBitmap.right = rectBitmap.left + bmp.bmWidth;
  160. }
  161. rectBitmap.top += max (0, (rectBitmap.Height () - bmp.bmHeight) / 2);
  162. rectBitmap.bottom = rectBitmap.top + bmp.bmHeight;
  163. pDC->DrawState (rectBitmap.TopLeft (), rectBitmap.Size (), pBmp, DSS_NORMAL);
  164. }
  165. //-----------
  166. // Draw text:
  167. //-----------
  168. if (hdItem.fmt & HDF_STRING)
  169. {
  170. CRect rectLabel = rect;
  171. rectLabel.DeflateRect (nTextMargin, 0);
  172. CString strLabel = hdItem.pszText;
  173. UINT uiTextFlags = DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX;
  174. if (hdItem.fmt & HDF_CENTER) uiTextFlags |= DT_CENTER;
  175. else if (hdItem.fmt & HDF_RIGHT) uiTextFlags |= DT_RIGHT;
  176.     pDC->SetTextColor(RGB(255,255,255));
  177. pDC->DrawText (strLabel, rectLabel, uiTextFlags);
  178. }
  179. }
  180. //***************************************************************************************
  181. void CMyHeaderCtrl::SetSortColumn (int iColumn, BOOL bAscending, BOOL bAdd)
  182. {
  183. ASSERT_VALID (this);
  184. if (iColumn < 0)
  185. {
  186. m_mapColumnsStatus.RemoveAll ();
  187. return;
  188. }
  189. if (bAdd)
  190. {
  191. if (!m_bMultipleSort)
  192. {
  193. ASSERT (FALSE);
  194. bAdd = FALSE;
  195. }
  196. }
  197. if (!bAdd)
  198. {
  199. m_mapColumnsStatus.RemoveAll ();
  200. }
  201. m_mapColumnsStatus.SetAt (iColumn, bAscending ? 1 : -1);
  202. RedrawWindow ();
  203. }
  204. //***************************************************************************************
  205. void CMyHeaderCtrl::RemoveSortColumn (int iColumn)
  206. {
  207. ASSERT_VALID (this);
  208. m_mapColumnsStatus.RemoveKey (iColumn);
  209. RedrawWindow ();
  210. }
  211. //***************************************************************************************
  212. BOOL CMyHeaderCtrl::OnEraseBkgnd(CDC* /*pDC*/)
  213. {
  214. return TRUE;
  215. }
  216. //***************************************************************************************
  217. void CMyHeaderCtrl::OnPaint() 
  218. {
  219. CPaintDC dc(this); // device context for painting
  220. CRect rectClip;
  221. dc.GetClipBox (rectClip);
  222. CRect rectClient;
  223. GetClientRect (rectClient);
  224. CDC* pDC = &dc;
  225. BOOL bMemDC = FALSE;
  226. CDC dcMem;
  227. CBitmap bmp;
  228. CBitmap* pOldBmp = NULL;
  229. if (dcMem.CreateCompatibleDC (&dc) &&bmp.CreateCompatibleBitmap (&dc, rectClient.Width (),rectClient.Height ()))
  230. {
  231. //-------------------------------------------------------------
  232. // Off-screen DC successfully created. Better paint to it then!
  233. //-------------------------------------------------------------
  234. bMemDC = TRUE;
  235. pOldBmp = dcMem.SelectObject (&bmp);
  236. pDC = &dcMem;
  237. }
  238. OnFillBackground (pDC);
  239. CFont* pOldFont = (CFont*) pDC->SelectObject (&fontRegular);
  240. ASSERT_VALID (pOldFont);
  241. pDC->SetTextColor (clrBtnText);
  242. pDC->SetBkMode (TRANSPARENT);
  243. CRect rect;
  244. GetClientRect(rect);
  245. CRect rectItem;
  246. int nCount = GetItemCount ();
  247. for (int i = 0; i < nCount; i++)
  248. {
  249. //------------------
  250. // Is item pressed?
  251. //------------------
  252. CPoint ptCursor;
  253. ::GetCursorPos (&ptCursor);
  254. ScreenToClient (&ptCursor);
  255. HDHITTESTINFO hdHitTestInfo;
  256. hdHitTestInfo.pt = ptCursor;
  257. int iHit = SendMessage (HDM_HITTEST, 0, (LPARAM) &hdHitTestInfo);
  258. BOOL bIsHighlighted = iHit == i && (hdHitTestInfo.flags & HHT_ONHEADER);
  259. BOOL bIsPressed = m_bIsMousePressed && bIsHighlighted;
  260. GetItemRect (i, rectItem);
  261. CRgn rgnClip;
  262. rgnClip.CreateRectRgnIndirect (&rectItem);
  263. pDC->SelectClipRgn (&rgnClip);
  264. //-----------
  265. // Draw item:
  266. //-----------
  267. OnDrawItem (pDC, i, rectItem, bIsPressed, m_nHighlightedItem == i);
  268. pDC->SelectClipRgn (NULL);
  269. }
  270. //--------------------
  271. // Draw "tail border":
  272. //--------------------
  273. if (nCount == 0)
  274. {
  275. rectItem = rect;
  276. rectItem.right++;
  277. }
  278. else
  279. {
  280. rectItem.left = rectItem.right;
  281. rectItem.right = rect.right + 1;
  282. }
  283. OnDrawItem (pDC, -1, rectItem, FALSE, FALSE);
  284. pDC->SelectObject (pOldFont);
  285. if (bMemDC)
  286. {
  287. //--------------------------------------
  288. // Copy the results to the on-screen DC:
  289. //-------------------------------------- 
  290. dc.BitBlt (rectClip.left, rectClip.top, rectClip.Width(), rectClip.Height(),
  291.    &dcMem, rectClip.left, rectClip.top, SRCCOPY);
  292. dcMem.SelectObject(pOldBmp);
  293. }
  294. }
  295. //***************************************************************************************
  296. void CMyHeaderCtrl::OnFillBackground (CDC* pDC)
  297. {
  298. ASSERT_VALID (this);
  299. ASSERT_VALID (pDC);
  300. CRect rectClient;
  301. GetClientRect (rectClient);
  302.     
  303. // pDC->FillRect (rectClient, &brBtnFace);
  304. CBrush b;
  305. CBitmap bmp;
  306. bmp.LoadBitmap( IDB_BACK );
  307. b.CreatePatternBrush( &bmp );
  308. pDC->FillRect (rectClient, &b);
  309. }
  310. //***************************************************************************************
  311. void CMyHeaderCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
  312. {
  313. m_bIsMousePressed = TRUE;
  314. CHeaderCtrl::OnLButtonDown(nFlags, point);
  315. }
  316. //***************************************************************************************
  317. void CMyHeaderCtrl::OnLButtonUp(UINT nFlags, CPoint point) 
  318. {
  319. m_bIsMousePressed = FALSE;
  320. CHeaderCtrl::OnLButtonUp(nFlags, point);
  321. }
  322. //***************************************************************************************
  323. void CMyHeaderCtrl::OnDrawSortArrow (CDC* pDC, CRect rectArrow)
  324. {
  325. ASSERT_VALID (pDC);
  326. ASSERT_VALID (this);
  327. CPen penLight (1, PS_SOLID,clrBtnHilite);
  328. CPen penDark (1, PS_SOLID,clrBtnDkShadow);
  329. CPen* pPenOld = pDC->SelectObject (&penLight);
  330. ASSERT_VALID (pPenOld);
  331. CBitmap bmp;
  332. if (!m_bAscending) bmp.LoadBitmap(IDB_SORT1);
  333. else bmp.LoadBitmap(IDB_SORT2);
  334. BITMAP  bmpInfo;
  335. bmp.GetBitmap(&bmpInfo);
  336. CDC dcMem;
  337. dcMem.CreateCompatibleDC(pDC);
  338. CBitmap *pOldBitmap=dcMem.SelectObject(&bmp);
  339. pDC->StretchBlt(rectArrow.left,rectArrow.top,rectArrow.Width(),rectArrow.Height(),&dcMem,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY);
  340. dcMem.SelectObject(pOldBitmap);
  341. pDC->SelectObject (pPenOld);
  342. }
  343. //*********************************************************************************
  344. void CMyHeaderCtrl::EnableMultipleSort (BOOL bEnable)
  345. {
  346. ASSERT_VALID (this);
  347. if (m_bMultipleSort == bEnable) return;
  348. m_bMultipleSort = bEnable;
  349. if (!m_bMultipleSort)
  350. {
  351. m_mapColumnsStatus.RemoveAll ();
  352. if (GetSafeHwnd () != NULL) RedrawWindow ();
  353. }
  354. }
  355. //*********************************************************************************
  356. int CMyHeaderCtrl::GetSortColumn () const
  357. {
  358. ASSERT_VALID (this);
  359. if (m_bMultipleSort)
  360. {
  361. TRACE0("Call CMyHeaderCtrl::GetColumnState for muliple sortn");
  362. ASSERT (FALSE);
  363. return -1;
  364. }
  365. int nCount = GetItemCount ();
  366. for (int i = 0; i < nCount; i++)
  367. {
  368. int nSortVal = 0;
  369. if (m_mapColumnsStatus.Lookup (i, nSortVal) && nSortVal != 0)
  370. {
  371. return i;
  372. }
  373. }
  374. return -1;
  375. }
  376. //*********************************************************************************
  377. BOOL CMyHeaderCtrl::IsAscending () const
  378. {
  379. ASSERT_VALID (this);
  380. if (m_bMultipleSort)
  381. {
  382. TRACE0("Call CBCGHeaderCtrl::GetColumnState for muliple sortn");
  383. ASSERT (FALSE);
  384. return -1;
  385. }
  386. int nCount = GetItemCount ();
  387. for (int i = 0; i < nCount; i++)
  388. {
  389. int nSortVal = 0;
  390. if (m_mapColumnsStatus.Lookup (i, nSortVal) &&
  391. nSortVal != 0)
  392. {
  393. return nSortVal > 0;
  394. }
  395. }
  396. return i;
  397. }
  398. //*********************************************************************************
  399. int CMyHeaderCtrl::GetColumnState (int iColumn) const
  400. {
  401. int nSortVal = 0;
  402. m_mapColumnsStatus.Lookup (iColumn, nSortVal);
  403. return nSortVal;
  404. }
  405. //**********************************************************************************
  406. void CMyHeaderCtrl::OnMouseMove(UINT nFlags, CPoint point) 
  407. {
  408. if ((nFlags & MK_LBUTTON) == 0)
  409. {
  410. HDHITTESTINFO hdHitTestInfo;
  411. hdHitTestInfo.pt = point;
  412. int nPrevHighlightedItem = m_nHighlightedItem;
  413. m_nHighlightedItem = SendMessage (HDM_HITTEST, 0, (LPARAM) &hdHitTestInfo);
  414. if ((hdHitTestInfo.flags & HHT_ONHEADER) == 0)
  415. {
  416. m_nHighlightedItem = -1;
  417. }
  418. if (nPrevHighlightedItem != m_nHighlightedItem)
  419. {
  420. RedrawWindow ();
  421. }
  422. }
  423. CHeaderCtrl::OnMouseMove(nFlags, point);
  424. }
  425. //*****************************************************************************************
  426. LRESULT CMyHeaderCtrl::OnMouseLeave(WPARAM,LPARAM)
  427. {
  428. if (m_nHighlightedItem >= 0)
  429. {
  430. m_nHighlightedItem = -1;
  431. RedrawWindow ();
  432. }
  433. return 0;
  434. }
  435. //*****************************************************************************************
  436. void CMyHeaderCtrl::OnCancelMode() 
  437. {
  438. CHeaderCtrl::OnCancelMode();
  439. if (m_nHighlightedItem >= 0)
  440. {
  441. m_nHighlightedItem = -1;
  442. RedrawWindow ();
  443. }
  444. }
  445. LRESULT CMyHeaderCtrl::OnLayout(WPARAM, LPARAM lParam)
  446. {
  447. LPHDLAYOUT lphdlayout = (LPHDLAYOUT)lParam;
  448. if (m_bStaticBorder)
  449. lphdlayout->prc->right += GetSystemMetrics(SM_CXBORDER)*2;
  450. return CHeaderCtrl::DefWindowProc(HDM_LAYOUT, 0, lParam);
  451. }