SortHeaderCtrl.cpp
上传用户:xuemeng126
上传日期:2022-07-05
资源大小:454k
文件大小:5k
源码类别:

系统编程

开发平台:

Visual C++

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