SortHeaderCtrl.cpp
上传用户:shouhua
上传日期:2014-12-06
资源大小:5685k
文件大小:5k
源码类别:

杀毒

开发平台:

Visual C++

  1. /*********************************
  2. 添加人       :n0bele
  3. 创建日期     :2008/2/15
  4. 模块功能描述 :List排序
  5. **********************************/
  6. //#include "..stdafx.h"//Release模式路径
  7. #include "stdafx.h"//Debug模式路径
  8. #include "SortHeaderCtrl.h"
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. CSortHeaderCtrl::CSortHeaderCtrl()
  15. : m_iSortColumn( -1 )
  16. , m_bSortAscending( TRUE )
  17. {
  18. }
  19. CSortHeaderCtrl::~CSortHeaderCtrl()
  20. {
  21. }
  22. BEGIN_MESSAGE_MAP(CSortHeaderCtrl, CHeaderCtrl)
  23. //{{AFX_MSG_MAP(CSortHeaderCtrl)
  24. // NOTE - the ClassWizard will add and remove mapping macros here.
  25. //}}AFX_MSG_MAP
  26. END_MESSAGE_MAP()
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CSortHeaderCtrl message handlers
  29. void CSortHeaderCtrl::SetSortArrow( const int iSortColumn, const BOOL bSortAscending )
  30. {
  31. m_iSortColumn = iSortColumn;
  32. m_bSortAscending = bSortAscending;
  33. HD_ITEM hditem;
  34. hditem.mask = HDI_FORMAT;
  35. VERIFY(GetItem(iSortColumn, &hditem));
  36. hditem.fmt |= HDF_OWNERDRAW;
  37. VERIFY(SetItem(iSortColumn, &hditem));
  38. // invalidate the header control so it gets redrawn
  39. Invalidate();
  40. }
  41. void CSortHeaderCtrl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
  42. {
  43. // attath to the device context.
  44. CDC dc;
  45. VERIFY( dc.Attach( lpDrawItemStruct->hDC ) );
  46. // save the device context.
  47. const int iSavedDC = dc.SaveDC();
  48. // get the column rect.
  49. CRect rc( lpDrawItemStruct->rcItem );
  50.   CRgn rgn;
  51.   VERIFY(rgn.CreateRoundRectRgn( rc.left, rc.top, rc.right, rc.bottom, 20, 20 ));
  52. (void)dc.SelectObject( &rgn );
  53. // draw the background,
  54. CBrush brush( GetSysColor(COLOR_3DFACE) );
  55. dc.FillRgn(&rgn,&brush);
  56. VERIFY( rgn.DeleteObject() );
  57. // get the column text and format.
  58. TCHAR szText[ 256 ];
  59. HD_ITEM hditem;
  60. hditem.mask = HDI_TEXT | HDI_FORMAT;
  61. hditem.pszText = szText;
  62. hditem.cchTextMax = 255;
  63. VERIFY( GetItem( lpDrawItemStruct->itemID, &hditem ) );
  64. // determine the format for drawing the column label.
  65. UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER | DT_END_ELLIPSIS ;
  66. if( hditem.fmt & HDF_CENTER)
  67. uFormat |= DT_CENTER;
  68. else if( hditem.fmt & HDF_RIGHT)
  69. uFormat |= DT_RIGHT;
  70. else
  71. uFormat |= DT_LEFT;
  72. // adjust the rect if the mouse button is pressed on it.
  73. if( lpDrawItemStruct->itemState == ODS_SELECTED )
  74. {
  75. rc.left++;
  76. rc.top += 2;
  77. rc.right++;
  78. }
  79. CRect rcIcon( lpDrawItemStruct->rcItem );
  80. const int iOffset = ( rcIcon.bottom - rcIcon.top ) / 4;
  81. // adjust the rect further if the sort arrow is to be displayed.
  82. if( lpDrawItemStruct->itemID == (UINT)m_iSortColumn )
  83. rc.right -= 3 * iOffset;
  84. rc.left += iOffset;
  85. rc.right -= iOffset;
  86. // draw the column label.
  87. int noldBkMode = dc.SetBkMode(TRANSPARENT);
  88. if( rc.left < rc.right )
  89. {
  90. if( lpDrawItemStruct->itemID == (UINT)m_iSortColumn )
  91. {
  92. long oldcolor = dc.SetTextColor(RGB(0,0,255));
  93. (void)dc.DrawText( szText, -1, rc, uFormat );
  94. dc.SetTextColor(oldcolor);
  95. }
  96. else
  97. (void)dc.DrawText( szText, -1, rc, uFormat );
  98. }
  99. dc.SetBkMode(noldBkMode);
  100. // draw the sort arrow.
  101. if( lpDrawItemStruct->itemID == (UINT)m_iSortColumn )
  102. {
  103. // set up the pens to use for drawing the arrow.
  104. CPen penLight( PS_SOLID, 1, GetSysColor( COLOR_3DHILIGHT ) );
  105. CPen penShadow( PS_SOLID, 1, GetSysColor( COLOR_3DSHADOW ) );
  106. CPen* pOldPen = dc.SelectObject( &penLight );
  107. if( m_bSortAscending )
  108. {
  109. // draw the arrow pointing upwards.
  110. dc.MoveTo( rcIcon.right - 2 * iOffset, iOffset);
  111. dc.LineTo( rcIcon.right - iOffset, rcIcon.bottom - iOffset - 1 );
  112. dc.LineTo( rcIcon.right - 3 * iOffset - 2, rcIcon.bottom - iOffset - 1 );
  113. (void)dc.SelectObject( &penShadow );
  114. dc.MoveTo( rcIcon.right - 3 * iOffset - 1, rcIcon.bottom - iOffset - 1 );
  115. dc.LineTo( rcIcon.right - 2 * iOffset, iOffset - 1);
  116. }
  117. else
  118. {
  119. // draw the arrow pointing downwards.
  120. dc.MoveTo( rcIcon.right - iOffset - 1, iOffset );
  121. dc.LineTo( rcIcon.right - 2 * iOffset - 1, rcIcon.bottom - iOffset );
  122. (void)dc.SelectObject( &penShadow );
  123. dc.MoveTo( rcIcon.right - 2 * iOffset - 2, rcIcon.bottom - iOffset );
  124. dc.LineTo( rcIcon.right - 3 * iOffset - 1, iOffset );
  125. dc.LineTo( rcIcon.right - iOffset - 1, iOffset );
  126. }
  127. // restore the pen.
  128. (void)dc.SelectObject( pOldPen );
  129. }
  130. // restore the previous device context.
  131. VERIFY( dc.RestoreDC( iSavedDC ) );
  132. // detach the device context before returning.
  133. (void)dc.Detach();
  134. }
  135. void CSortHeaderCtrl::Serialize( CArchive& ar )
  136. {
  137. if( ar.IsStoring() )
  138. {
  139. const int iItemCount = GetItemCount();
  140. if( iItemCount != -1 )
  141. {
  142. ar << iItemCount;
  143. HD_ITEM hdItem = { 0 };
  144. hdItem.mask = HDI_WIDTH;
  145. for( int i = 0; i < iItemCount; i++ )
  146. {
  147. VERIFY( GetItem( i, &hdItem ) );
  148. ar << hdItem.cxy;
  149. }
  150. }
  151. }
  152. else
  153. {
  154. int iItemCount;
  155. ar >> iItemCount;
  156. if( GetItemCount() != iItemCount )
  157. TRACE0( _T("Different number of columns in registry.") );
  158. else
  159. {
  160. HD_ITEM hdItem = { 0 };
  161. hdItem.mask = HDI_WIDTH;
  162. for( int i = 0; i < iItemCount; i++ )
  163. {
  164. ar >> hdItem.cxy;
  165. VERIFY( SetItem( i, &hdItem ) );
  166. }
  167. }
  168. }
  169. }