/*----------------------------------------------------------------------
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
File: SortListCtrl.cpp
Purpose: Provides a sortable list control, it will sort text, numbers
and dates, ascending or descending, and will even draw the
arrows just like windows explorer!
----------------------------------------------------------------------*/
#include "stdafx.h"
#include "SortListCtrl.h"
#include "resource.h"
#include "SortListCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
LPCTSTR g_pszSection = _T("ListCtrls");
struct ItemData
{
public:
ItemData() : arrpsz( NULL ), dwData( NULL ) {}
LPTSTR* arrpsz;
DWORD dwData;
private:
// ban copying.
ItemData( const ItemData& );
ItemData& operator=( const ItemData& );
};
CSortListCtrl::CSortListCtrl()
: m_iNumColumns( 0 )
, m_iSortColumn( -1 )
, m_bSortAscending( TRUE )
{
}
CSortListCtrl::~CSortListCtrl()
{
}
BEGIN_MESSAGE_MAP(CSortListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CSortListCtrl)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick)
ON_WM_DESTROY()
ON_WM_CONTEXTMENU()
ON_COMMAND(ID_MENUITEM_PING, OnMenuitemPing)
ON_COMMAND(ID_MENUITEM_TRACERT, OnMenuitemTracert)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSortListCtrl message handlers
void CSortListCtrl::PreSubclassWindow()
{
// the list control must have the report style.
ASSERT( GetStyle() & LVS_REPORT );
CListCtrl::PreSubclassWindow();
VERIFY( m_ctlHeader.SubclassWindow( GetHeaderCtrl()->GetSafeHwnd() ) );
}
BOOL CSortListCtrl::SetHeadings( UINT uiStringID )
{
CString strHeadings;
VERIFY( strHeadings.LoadString( uiStringID ) );
return SetHeadings( strHeadings );
}
// the heading text is in the format column 1 text,column 1 width;column 2 text,column 3 width;etc.
BOOL CSortListCtrl::SetHeadings( const CString& strHeadings )
{
int iStart = 0;
for( ;; )
{
const int iComma = strHeadings.Find( _T(','), iStart );
if( iComma == -1 )
break;
const CString strHeading = strHeadings.Mid( iStart, iComma - iStart );
iStart = iComma + 1;
int iSemiColon = strHeadings.Find( _T(';'), iStart );
if( iSemiColon == -1 )
iSemiColon = strHeadings.GetLength();
const int iWidth = atoi( strHeadings.Mid( iStart, iSemiColon - iStart ) );
iStart = iSemiColon + 1;
if( InsertColumn( m_iNumColumns++, strHeading, LVCFMT_LEFT, iWidth ) == -1 )
return FALSE;
}
return TRUE;
}
int CSortListCtrl::AddItem( LPCTSTR pszText, ... )
{
const int iIndex = InsertItem( GetItemCount(), pszText );
LPTSTR* arrpsz = new LPTSTR[ m_iNumColumns ];
arrpsz[ 0 ] = new TCHAR[ lstrlen( pszText ) + 1 ];
(void)lstrcpy( arrpsz[ 0 ], pszText );
va_list list;
va_start( list, pszText );
for( int iColumn = 1; iColumn < m_iNumColumns; iColumn++ )
{
pszText = va_arg( list, LPCTSTR );
ASSERT_VALID_STRING( pszText );
VERIFY( CListCtrl::SetItem( iIndex, iColumn, LVIF_TEXT, pszText, 0, 0, 0, 0 ) );
arrpsz[ iColumn ] = new TCHAR[ lstrlen( pszText ) + 1 ];
(void)lstrcpy( arrpsz[ iColumn ], pszText );
}
va_end( list );
VERIFY( SetTextArray( iIndex, arrpsz ) );
return iIndex;
}
void CSortListCtrl::FreeItemMemory( const int iItem )
{
ItemData* pid = reinterpret_cast<ItemData*>( CListCtrl::GetItemData( iItem ) );
LPTSTR* arrpsz = pid->arrpsz;
for( int i = 0; i < m_iNumColumns; i++ )
delete[] arrpsz[ i ];
delete[] arrpsz;
delete pid;
VERIFY( CListCtrl::SetItemData( iItem, NULL ) );
}
BOOL CSortListCtrl::DeleteItem( int iItem )
{
FreeItemMemory( iItem );
return CListCtrl::DeleteItem( iItem );
}
BOOL CSortListCtrl::DeleteAllItems()
{
for( int iItem = 0; iItem < GetItemCount(); iItem ++ )
FreeItemMemory( iItem );
return CListCtrl::DeleteAllItems();
}
bool IsNumber( LPCTSTR pszText )
{
ASSERT_VALID_STRING( pszText );
for( int i = 0; i < lstrlen( pszText ); i++ )
if( !_istdigit( pszText[ i ] ) )
return false;
return true;
}
int NumberCompare( LPCTSTR pszNumber1, LPCTSTR pszNumber2 )
{
ASSERT_VALID_STRING( pszNumber1 );
ASSERT_VALID_STRING( pszNumber2 );
const int iNumber1 = atoi( pszNumber1 );
const int iNumber2 = atoi( pszNumber2 );
if( iNumber1 < iNumber2 )
return -1;
if( iNumber1 > iNumber2 )
return 1;
return 0;
}
bool IsDate( LPCTSTR pszText )
{
ASSERT_VALID_STRING( pszText );
// format should be 99/99/9999.
if( lstrlen( pszText ) != 10 )
return false;
return _istdigit( pszText[ 0 ] )
&& _istdigit( pszText[ 1 ] )
&& pszText[ 2 ] == _T('/')
&& _istdigit( pszText[ 3 ] )
&& _istdigit( pszText[ 4 ] )
&& pszText[ 5 ] == _T('/')
&& _istdigit( pszText[ 6 ] )
&& _istdigit( pszText[ 7 ] )
&& _istdigit( pszText[ 8 ] )
&& _istdigit( pszText[ 9 ] );
}
int DateCompare( const CString& strDate1, const CString& strDate2 )
{
const int iYear1 = atoi( strDate1.Mid( 6, 4 ) );
const int iYear2 = atoi( strDate2.Mid( 6, 4 ) );
if( iYear1 < iYear2 )
return -1;
if( iYear1 > iYear2 )
return 1;
const int iMonth1 = atoi( strDate1.Mid( 3, 2 ) );
const int iMonth2 = atoi( strDate2.Mid( 3, 2 ) );
if( iMonth1 < iMonth2 )
return -1;
if( iMonth1 > iMonth2 )
return 1;
const int iDay1 = atoi( strDate1.Mid( 0, 2 ) );
const int iDay2 = atoi( strDate2.Mid( 0, 2 ) );
if( iDay1 < iDay2 )
return -1;
if( iDay1 > iDay2 )
return 1;
return 0;
}
int CALLBACK CSortListCtrl::CompareFunction( LPARAM lParam1, LPARAM lParam2, LPARAM lParamData )
{
CSortListCtrl* pListCtrl = reinterpret_cast<CSortListCtrl*>( lParamData );
ASSERT( pListCtrl->IsKindOf( RUNTIME_CLASS( CListCtrl ) ) );
ItemData* pid1 = reinterpret_cast<ItemData*>( lParam1 );
ItemData* pid2 = reinterpret_cast<ItemData*>( lParam2 );
ASSERT( pid1 );
ASSERT( pid2 );
LPCTSTR pszText1 = pid1->arrpsz[ pListCtrl->m_iSortColumn ];
LPCTSTR pszText2 = pid2->arrpsz[ pListCtrl->m_iSortColumn ];
ASSERT_VALID_STRING( pszText1 );
ASSERT_VALID_STRING( pszText2 );
if( IsNumber( pszText1 ) )
return pListCtrl->m_bSortAscending ? NumberCompare( pszText1, pszText2 ) : NumberCompare( pszText2, pszText1 );
else if( IsDate( pszText1 ) )
return pListCtrl->m_bSortAscending ? DateCompare( pszText1, pszText2 ) : DateCompare( pszText2, pszText1 );
else
// text.
return pListCtrl->m_bSortAscending ? lstrcmp( pszText1, pszText2 ) : lstrcmp( pszText2, pszText1 );
}
void CSortListCtrl::OnColumnClick( NMHDR* pNMHDR, LRESULT* pResult )
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
const int iColumn = pNMListView->iSubItem;
// if it's a second click on the same column then reverse the sort order,
// otherwise sort the new column in ascending order.
Sort( iColumn, iColumn == m_iSortColumn ? !m_bSortAscending : TRUE );
*pResult = 0;
}
void CSortListCtrl::Sort( int iColumn, BOOL bAscending )
{
m_iSortColumn = iColumn;
m_bSortAscending = bAscending;
// show the appropriate arrow in the header control.
m_ctlHeader.SetSortArrow( m_iSortColumn, m_bSortAscending );
VERIFY( SortItems( CompareFunction, reinterpret_cast<DWORD>( this ) ) );
}
void CSortListCtrl::LoadColumnInfo()
{
// you must call this after setting the column headings.
ASSERT( m_iNumColumns > 0 );
CString strKey;
strKey.Format( _T("%d"), GetDlgCtrlID() );
UINT nBytes = 0;
BYTE* buf = NULL;
if( AfxGetApp()->GetProfileBinary( g_pszSection, strKey, &buf, &nBytes ) )
{
if( nBytes > 0 )
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
ListCtrl.zip (39个子文件)
StdAfx.cpp 212B
resource.h 695B
SortListCtrlTest.plg 266B
SortListCtrlTest.aps 20KB
SortListCtrlTest.cpp 2KB
SortListCtrlTest.clw 1KB
SortListCtrl.h 3KB
SortListCtrlTest.dsp 4KB
Debug
SortListCtrlTest.obj 14KB
SortListCtrlTest.sbr 0B
vc60.pdb 356KB
SortHeaderCtrl.sbr 0B
SortListCtrlTestDlg.sbr 0B
vc60.idb 225KB
SortListCtrl.sbr 0B
SortHeaderCtrl.obj 19KB
SortListCtrlTest.ilk 308KB
SortListCtrlTest.exe 116KB
SortListCtrlTest.pch 6.62MB
SortListCtrlTestDlg.obj 24KB
SortListCtrlTest.bsc 2.99MB
StdAfx.obj 103KB
SortListCtrlTest.pdb 449KB
SortListCtrl.obj 51KB
StdAfx.sbr 1.31MB
SortListCtrlTest.res 3KB
StdAfx.h 1KB
SortListCtrlTestDlg.cpp 4KB
SortListCtrlTest.h 1KB
SortListCtrlTestDlg.h 2KB
SortListCtrlTest.ncb 129KB
SortListCtrlTest.dsw 555B
SortListCtrlTest.rc 5KB
SortListCtrlTest.opt 55KB
SortHeaderCtrl.h 2KB
res
SortListCtrlTest.rc2 408B
SortListCtrlTest.ico 1KB
SortListCtrl.cpp 11KB
SortHeaderCtrl.cpp 5KB
共 39 条
- 1
资源评论
liyan881226
- 粉丝: 2
- 资源: 11
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功