📄 sortheaderctrl.cpp
字号:
/*----------------------------------------------------------------------
Copyright (C)2001 MJSoft. All Rights Reserved.
This source may be used freely as long as it is not sold for
profit and this copyright information is not altered or removed.
Visit the web-site at www.mjsoft.co.uk
e-mail comments to info@mjsoft.co.uk
The code for drawing the arrow in the header control was
written by Zafir Anjum
File: SortHeaderCtrl.cpp
Purpose: Provides the header control, with drawing of the arrows, for
the list control.
----------------------------------------------------------------------*/
#include "stdafx.h"
#include "SortHeaderCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CSortHeaderCtrl::CSortHeaderCtrl()
: m_iSortColumn( -1 )
, m_bSortAscending( TRUE )
{
}
CSortHeaderCtrl::~CSortHeaderCtrl()
{
}
BEGIN_MESSAGE_MAP(CSortHeaderCtrl, CHeaderCtrl)
//{{AFX_MSG_MAP(CSortHeaderCtrl)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSortHeaderCtrl message handlers
void CSortHeaderCtrl::SetSortArrow( const int iSortColumn, const BOOL bSortAscending )
{
m_iSortColumn = iSortColumn;
m_bSortAscending = bSortAscending;
// change the item to owner drawn.
HD_ITEM hditem;
hditem.mask = HDI_FORMAT;
VERIFY( GetItem( iSortColumn, &hditem ) );
hditem.fmt |= HDF_OWNERDRAW;
VERIFY( SetItem( iSortColumn, &hditem ) );
// invalidate the header control so it gets redrawn
Invalidate();
}
void CSortHeaderCtrl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
// attath to the device context.
CDC dc;
VERIFY( dc.Attach( lpDrawItemStruct->hDC ) );
// save the device context.
const int iSavedDC = dc.SaveDC();
// get the column rect.
CRect rc( lpDrawItemStruct->rcItem );
// set the clipping region to limit drawing within the column.
CRgn rgn;
VERIFY( rgn.CreateRectRgnIndirect( &rc ) );
(void)dc.SelectObject( &rgn );
VERIFY( rgn.DeleteObject() );
// draw the background,
CBrush brush( GetSysColor( COLOR_3DFACE ) );
dc.FillRect( rc, &brush );
// get the column text and format.
TCHAR szText[ 256 ];
HD_ITEM hditem;
hditem.mask = HDI_TEXT | HDI_FORMAT;
hditem.pszText = szText;
hditem.cchTextMax = 255;
VERIFY( GetItem( lpDrawItemStruct->itemID, &hditem ) );
// determine the format for drawing the column label.
UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER | DT_END_ELLIPSIS ;
if( hditem.fmt & HDF_CENTER)
uFormat |= DT_CENTER;
else if( hditem.fmt & HDF_RIGHT)
uFormat |= DT_RIGHT;
else
uFormat |= DT_LEFT;
// adjust the rect if the mouse button is pressed on it.
if( lpDrawItemStruct->itemState == ODS_SELECTED )
{
rc.left++;
rc.top += 2;
rc.right++;
}
CRect rcIcon( lpDrawItemStruct->rcItem );
const int iOffset = ( rcIcon.bottom - rcIcon.top ) / 4;
// adjust the rect further if the sort arrow is to be displayed.
if( lpDrawItemStruct->itemID == (UINT)m_iSortColumn )
rc.right -= 3 * iOffset;
rc.left += iOffset;
rc.right -= iOffset;
// draw the column label.
if( rc.left < rc.right )
(void)dc.DrawText( szText, -1, rc, uFormat );
// draw the sort arrow.
if( lpDrawItemStruct->itemID == (UINT)m_iSortColumn )
{
// set up the pens to use for drawing the arrow.
CPen penLight( PS_SOLID, 1, GetSysColor( COLOR_3DHILIGHT ) );
CPen penShadow( PS_SOLID, 1, GetSysColor( COLOR_3DSHADOW ) );
CPen* pOldPen = dc.SelectObject( &penLight );
if( m_bSortAscending )
{
// draw the arrow pointing upwards.
dc.MoveTo( rcIcon.right - 2 * iOffset, iOffset);
dc.LineTo( rcIcon.right - iOffset, rcIcon.bottom - iOffset - 1 );
dc.LineTo( rcIcon.right - 3 * iOffset - 2, rcIcon.bottom - iOffset - 1 );
(void)dc.SelectObject( &penShadow );
dc.MoveTo( rcIcon.right - 3 * iOffset - 1, rcIcon.bottom - iOffset - 1 );
dc.LineTo( rcIcon.right - 2 * iOffset, iOffset - 1);
}
else
{
// draw the arrow pointing downwards.
dc.MoveTo( rcIcon.right - iOffset - 1, iOffset );
dc.LineTo( rcIcon.right - 2 * iOffset - 1, rcIcon.bottom - iOffset );
(void)dc.SelectObject( &penShadow );
dc.MoveTo( rcIcon.right - 2 * iOffset - 2, rcIcon.bottom - iOffset );
dc.LineTo( rcIcon.right - 3 * iOffset - 1, iOffset );
dc.LineTo( rcIcon.right - iOffset - 1, iOffset );
}
// restore the pen.
(void)dc.SelectObject( pOldPen );
}
// restore the previous device context.
VERIFY( dc.RestoreDC( iSavedDC ) );
// detach the device context before returning.
(void)dc.Detach();
}
void CSortHeaderCtrl::Serialize( CArchive& ar )
{
if( ar.IsStoring() )
{
const int iItemCount = GetItemCount();
if( iItemCount != -1 )
{
ar << iItemCount;
HD_ITEM hdItem = { 0 };
hdItem.mask = HDI_WIDTH;
for( int i = 0; i < iItemCount; i++ )
{
VERIFY( GetItem( i, &hdItem ) );
ar << hdItem.cxy;
}
}
}
else
{
int iItemCount;
ar >> iItemCount;
if( GetItemCount() != iItemCount )
TRACE0( _T("Different number of columns in registry.") );
else
{
HD_ITEM hdItem = { 0 };
hdItem.mask = HDI_WIDTH;
for( int i = 0; i < iItemCount; i++ )
{
ar >> hdItem.cxy;
VERIFY( SetItem( i, &hdItem ) );
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -