SortHeaderCtrl.cpp
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:6k
源码类别:

P2P编程

开发平台:

Visual C++

  1. /*
  2.  *  Openmysee
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  *
  18.  */
  19. /*----------------------------------------------------------------------
  20. Copyright (C)2001 MJSoft. All Rights Reserved.
  21.           This source may be used freely as long as it is not sold for
  22. profit and this copyright information is not altered or removed.
  23. Visit the web-site at www.mjsoft.co.uk
  24. e-mail comments to info@mjsoft.co.uk
  25. The code for drawing the arrow in the header control was
  26. written by Zafir Anjum
  27. File:     SortHeaderCtrl.cpp
  28. Purpose:  Provides the header control, with drawing of the arrows, for
  29.           the list control.
  30. ----------------------------------------------------------------------*/
  31. #include "stdafx.h"
  32. #include "SortHeaderCtrl.h"
  33. #ifdef _DEBUG
  34. #define new DEBUG_NEW
  35. #undef THIS_FILE
  36. static char THIS_FILE[] = __FILE__;
  37. #endif
  38. CSortHeaderCtrl::CSortHeaderCtrl()
  39. : m_iSortColumn( -1 )
  40. , m_bSortAscending( TRUE )
  41. {
  42. }
  43. CSortHeaderCtrl::~CSortHeaderCtrl()
  44. {
  45. }
  46. BEGIN_MESSAGE_MAP(CSortHeaderCtrl, CHeaderCtrl)
  47. //{{AFX_MSG_MAP(CSortHeaderCtrl)
  48. // NOTE - the ClassWizard will add and remove mapping macros here.
  49. //}}AFX_MSG_MAP
  50. END_MESSAGE_MAP()
  51. /////////////////////////////////////////////////////////////////////////////
  52. // CSortHeaderCtrl message handlers
  53. void CSortHeaderCtrl::SetSortArrow( const int iSortColumn, const BOOL bSortAscending )
  54. {
  55. m_iSortColumn = iSortColumn;
  56. m_bSortAscending = bSortAscending;
  57. // change the item to owner drawn.
  58. HD_ITEM hditem;
  59. hditem.mask = HDI_FORMAT;
  60. VERIFY( GetItem( iSortColumn, &hditem ) );
  61. hditem.fmt |= HDF_OWNERDRAW;
  62. VERIFY( SetItem( iSortColumn, &hditem ) );
  63. // invalidate the header control so it gets redrawn
  64. Invalidate();
  65. }
  66. void CSortHeaderCtrl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
  67. {
  68. // attath to the device context.
  69. CDC dc;
  70. VERIFY( dc.Attach( lpDrawItemStruct->hDC ) );
  71. // save the device context.
  72. const int iSavedDC = dc.SaveDC();
  73. // get the column rect.
  74. CRect rc( lpDrawItemStruct->rcItem );
  75. // set the clipping region to limit drawing within the column.
  76. CRgn rgn;
  77. VERIFY( rgn.CreateRectRgnIndirect( &rc ) );
  78. (void)dc.SelectObject( &rgn );
  79. VERIFY( rgn.DeleteObject() );
  80. // draw the background,
  81. CBrush brush( GetSysColor( COLOR_3DFACE ) );
  82. dc.FillRect( rc, &brush );
  83. // get the column text and format.
  84. TCHAR szText[ 256 ];
  85. HD_ITEM hditem;
  86. hditem.mask = HDI_TEXT | HDI_FORMAT;
  87. hditem.pszText = szText;
  88. hditem.cchTextMax = 255;
  89. VERIFY( GetItem( lpDrawItemStruct->itemID, &hditem ) );
  90. // determine the format for drawing the column label.
  91. UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER | DT_END_ELLIPSIS ;
  92. if( hditem.fmt & HDF_CENTER)
  93. uFormat |= DT_CENTER;
  94. else if( hditem.fmt & HDF_RIGHT)
  95. uFormat |= DT_RIGHT;
  96. else
  97. uFormat |= DT_LEFT;
  98. // adjust the rect if the mouse button is pressed on it.
  99. if( lpDrawItemStruct->itemState == ODS_SELECTED )
  100. {
  101. rc.left++;
  102. rc.top += 2;
  103. rc.right++;
  104. }
  105. CRect rcIcon( lpDrawItemStruct->rcItem );
  106. const int iOffset = ( rcIcon.bottom - rcIcon.top ) / 4;
  107. // adjust the rect further if the sort arrow is to be displayed.
  108. if( lpDrawItemStruct->itemID == (UINT)m_iSortColumn )
  109. rc.right -= 3 * iOffset;
  110. rc.left += iOffset;
  111. rc.right -= iOffset;
  112. // draw the column label.
  113. if( rc.left < rc.right )
  114. (void)dc.DrawText( szText, -1, rc, uFormat );
  115. // draw the sort arrow.
  116. if( lpDrawItemStruct->itemID == (UINT)m_iSortColumn )
  117. {
  118. // set up the pens to use for drawing the arrow.
  119. CPen penLight( PS_SOLID, 1, GetSysColor( COLOR_3DHILIGHT ) );
  120. CPen penShadow( PS_SOLID, 1, GetSysColor( COLOR_3DSHADOW ) );
  121. CPen* pOldPen = dc.SelectObject( &penLight );
  122. if( m_bSortAscending )
  123. {
  124. // draw the arrow pointing upwards.
  125. dc.MoveTo( rcIcon.right - 2 * iOffset, iOffset);
  126. dc.LineTo( rcIcon.right - iOffset, rcIcon.bottom - iOffset - 1 );
  127. dc.LineTo( rcIcon.right - 3 * iOffset - 2, rcIcon.bottom - iOffset - 1 );
  128. (void)dc.SelectObject( &penShadow );
  129. dc.MoveTo( rcIcon.right - 3 * iOffset - 1, rcIcon.bottom - iOffset - 1 );
  130. dc.LineTo( rcIcon.right - 2 * iOffset, iOffset - 1);
  131. }
  132. else
  133. {
  134. // draw the arrow pointing downwards.
  135. dc.MoveTo( rcIcon.right - iOffset - 1, iOffset );
  136. dc.LineTo( rcIcon.right - 2 * iOffset - 1, rcIcon.bottom - iOffset );
  137. (void)dc.SelectObject( &penShadow );
  138. dc.MoveTo( rcIcon.right - 2 * iOffset - 2, rcIcon.bottom - iOffset );
  139. dc.LineTo( rcIcon.right - 3 * iOffset - 1, iOffset );
  140. dc.LineTo( rcIcon.right - iOffset - 1, iOffset );
  141. }
  142. // restore the pen.
  143. (void)dc.SelectObject( pOldPen );
  144. }
  145. // restore the previous device context.
  146. VERIFY( dc.RestoreDC( iSavedDC ) );
  147. // detach the device context before returning.
  148. (void)dc.Detach();
  149. }
  150. void CSortHeaderCtrl::Serialize( CArchive& ar )
  151. {
  152. if( ar.IsStoring() )
  153. {
  154. const int iItemCount = GetItemCount();
  155. if( iItemCount != -1 )
  156. {
  157. ar << iItemCount;
  158. HD_ITEM hdItem = { 0 };
  159. hdItem.mask = HDI_WIDTH;
  160. for( int i = 0; i < iItemCount; i++ )
  161. {
  162. VERIFY( GetItem( i, &hdItem ) );
  163. ar << hdItem.cxy;
  164. }
  165. }
  166. }
  167. else
  168. {
  169. int iItemCount;
  170. ar >> iItemCount;
  171. if( GetItemCount() != iItemCount )
  172. TRACE0( _T("Different number of columns in registry.") );
  173. else
  174. {
  175. HD_ITEM hdItem = { 0 };
  176. hdItem.mask = HDI_WIDTH;
  177. for( int i = 0; i < iItemCount; i++ )
  178. {
  179. ar >> hdItem.cxy;
  180. VERIFY( SetItem( i, &hdItem ) );
  181. }
  182. }
  183. }
  184. }