123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- // ListSortCtrl.cpp : 实现文件
- //
- #include "stdafx.h"
- #include "ListSortCtrl.h"
- #include "..\MD5\MD5.h"
- #include <strsafe.h>
- // CListSortCtrl
- bool CListSortCtrl::IsNumber( LPCTSTR pszText )
- {
- ASSERT_VALID_STRING( pszText );
- for( int i = 0; i < lstrlen( pszText ); i++ )
- if( ! (_istdigit( pszText[ i ] )||pszText[ i ]=='.'||pszText[ i ]=='-') )
- return false;
- return true;
- }
- int CListSortCtrl::NumberCompare( LPCTSTR pszNumber1, LPCTSTR pszNumber2 )
- {
- ASSERT_VALID_STRING( pszNumber1 );
- ASSERT_VALID_STRING( pszNumber2 );
- const float iNumber1 = _tstof( pszNumber1 );
- const float iNumber2 = _tstof( pszNumber2 );
- if( iNumber1 < iNumber2 )
- return -1;
- if( iNumber1 > iNumber2 )
- return 1;
- return 0;
- }
- bool CListSortCtrl::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 ] )
- && _istdigit( pszText[ 2 ] )
- && _istdigit( pszText[ 3 ] )
- && pszText[ 4 ] == _T('-')
- && _istdigit( pszText[ 5 ] )
- && _istdigit( pszText[ 6 ] )
- && pszText[ 7 ] == _T('-')
- && _istdigit( pszText[ 8 ] )
- && _istdigit( pszText[ 9 ] );
- }
- int CListSortCtrl::DateCompare( const CString& strDate1, const CString& strDate2 )
- {
- if(strDate1.GetLength ()!=10)return -1;
- if(strDate2.GetLength ()!=10)return -1;
- const int iYear1 = _tstoi( strDate1.Mid( 0, 4 ) );
- const int iYear2 = _tstoi( strDate2.Mid( 0, 4 ) );
- if( iYear1 < iYear2 )
- return -1;
- if( iYear1 > iYear2 )
- return 1;
- const int iMonth1 = _tstoi( strDate1.Mid( 5, 2 ) );
- const int iMonth2 = _tstoi( strDate2.Mid( 5, 2 ) );
- if( iMonth1 < iMonth2 )
- return -1;
- if( iMonth1 > iMonth2 )
- return 1;
- const int iDay1 = _tstoi( strDate1.Mid( 8, 2 ) );
- const int iDay2 = _tstoi( strDate2.Mid( 8, 2 ) );
- if( iDay1 < iDay2 )
- return -1;
- if( iDay1 > iDay2 )
- return 1;
- return 0;
- }
- int CListSortCtrl::CompareByLabel( const void *elem1, const void *elem2)
- {
- CStringArray *p1 = (CStringArray*)elem1;
- CStringArray *p2 = (CStringArray*)elem2;
- if( IsDate( p1->ElementAt (CListSortCtrl::m_nCompareColumn) ) )
- return CListSortCtrl::m_bSortAscending ? DateCompare( p1->ElementAt (CListSortCtrl::m_nCompareColumn), p2->ElementAt (CListSortCtrl::m_nCompareColumn) ) : DateCompare( p2->ElementAt (CListSortCtrl::m_nCompareColumn), p1->ElementAt (CListSortCtrl::m_nCompareColumn) );
- else if( IsNumber( p1->ElementAt (CListSortCtrl::m_nCompareColumn) ) )
- return CListSortCtrl::m_bSortAscending ? NumberCompare( p1->ElementAt (CListSortCtrl::m_nCompareColumn), p2->ElementAt (CListSortCtrl::m_nCompareColumn) ) : NumberCompare( p2->ElementAt (CListSortCtrl::m_nCompareColumn), p1->ElementAt (CListSortCtrl::m_nCompareColumn) );
- else
- // text.
- return CListSortCtrl::m_bSortAscending ? lstrcmp( p1->ElementAt (CListSortCtrl::m_nCompareColumn), p2->ElementAt (CListSortCtrl::m_nCompareColumn) ) : lstrcmp( p2->ElementAt (CListSortCtrl::m_nCompareColumn), p1->ElementAt (CListSortCtrl::m_nCompareColumn) );
- return true;
- }
- //////////////////////////////////////////////////////////////////////////
- // 静态变量;
- INT CListSortCtrl::m_nCompareColumn = 0;
- BOOL CListSortCtrl::m_bSortAscending = FALSE;
- IMPLEMENT_DYNAMIC(CListSortCtrl, CListCtrl)
- CListSortCtrl::CListSortCtrl()
- :m_bSortSupport(TRUE)
- ,m_nSortColumns(-1)
- ,m_strSection(_T(""))
- ,m_nNumColumns(0)
- ,m_clrLightGrid(RGB(204,204,204))
- ,m_clrDarkGrid(RGB(190,190,190))
- {
- m_strSection = _T("");
- m_nCompareColumn = -1;
- }
- CListSortCtrl::~CListSortCtrl()
- {
-
- }
- BEGIN_MESSAGE_MAP(CListSortCtrl, CListCtrl)
- ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, &CListSortCtrl::OnLvnColumnclick)
- ON_NOTIFY_REFLECT(LVN_GETDISPINFO, &CListSortCtrl::OnLvnGetdispinfo)
- #ifndef __LIST_DRAW__
- ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CListSortCtrl::OnNMCustomdraw)
- #endif
- ON_WM_DESTROY()
- END_MESSAGE_MAP()
- // CListSortCtrl 消息处理程序
- void CListSortCtrl::PreSubclassWindow()
- {
- // TODO: 在此添加专用代码和/或调用基类
- ASSERT( GetStyle() & LVS_REPORT );
- CListCtrl::PreSubclassWindow();
- VERIFY( m_Ctrlheader.SubclassWindow( GetHeaderCtrl()->GetSafeHwnd() ) );
- }
- void CListSortCtrl::RemoveAll()
- {
- DeleteAllItems();
- for ( int i = 0; i < m_AryList.GetSize(); i++)
- {
- m_AryList.ElementAt(i).RemoveAll();
- }
- m_AryList.RemoveAll();
- }
- /************************************************************************/
- /* 函数:[10/21/2016 IT];
- /* 描述:;
- /* 参数:;
- /* [IN] :;
- /* [OUT] :;
- /* [IN/OUT] :;
- /* 返回:void;
- /* 注意:最后一个参数,必须以NULL结尾(请看示例);
- /* 示例:CListSortCtrl::SetHeadings(_T("示例1,100"),_T("示例2,100"),NULL);
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- BOOL CListSortCtrl::SetHeadings( IN LPCTSTR pszText, ... )
- {
- if ( pszText == NULL ) return FALSE;
- va_list list;
- INT nCommaPos = 0; // 逗号位置;
- CString strColumn = _T("");
- va_start( list, pszText );
- do
- {
- strColumn = pszText;
- if ( -1 != (nCommaPos = strColumn.Find(_T(","))))
- {
- m_strSection += strColumn.Left(nCommaPos);
- if( InsertColumn( m_nNumColumns++, strColumn.Left(nCommaPos), LVCFMT_LEFT, _tstoi( strColumn.Mid( nCommaPos + 1) ) ) == -1 )
- {
- va_end( list );
- return FALSE;
- }
- }
- pszText = va_arg( list, LPCTSTR );
- } while (pszText != NULL);
- va_end( list );
- LoadColumnInfo();
- SetExtendedStyle(LVS_EX_FLATSB|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP);
- SetListFont(_T("宋体"), 11);
- return TRUE;
- }
- /************************************************************************/
- /* 函数:SetTextFont[3/6/2017 Jeff];
- /* 描述:设置文本字体;
- /* 参数:;
- /* [IN] nTextFontSize:字体大小;
- /* [IN] bBold:是否粗体;
- /* [IN] bItalic:是否斜体;
- /* [IN] strTextFontName:字体名称,如楷体;
- /* 返回:void;
- /* 注意:;
- /* 示例:;
- /*
- /* 修改:;
- /* 日期:;
- /* 内容:;
- /************************************************************************/
- void CListSortCtrl::SetListFont(IN CString strFontName, IN int nFontSize, IN BOOL bBold, IN BOOL bItalic)
- {
- LOGFONT lf;
- CClientDC dc(this);
- int dpy = GetDeviceCaps(dc, LOGPIXELSY); // Pixel per inch
- lf.lfHeight = -MulDiv(nFontSize, dpy, 72);
- lf.lfWeight = 0;
- lf.lfEscapement = 0;
- lf.lfOrientation = 0;
- if (bBold)
- lf.lfWeight = FW_BLACK;
- else
- lf.lfWeight = FW_NORMAL;
- lf.lfItalic = bItalic;
- lf.lfUnderline = FALSE;
- lf.lfStrikeOut = 0;
- lf.lfCharSet = ANSI_CHARSET;
- lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
- lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- lf.lfQuality = DEFAULT_QUALITY;
- lf.lfPitchAndFamily = DEFAULT_PITCH | FF_ROMAN;
- _tcscpy_s(lf.lfFaceName, strFontName);
- // 创建字体;
- //m_cfont = GetFont();// 局部变量会导致字体设置失败,必须是全局或成员变量;
- VERIFY(m_cfont.CreateFontIndirect(&lf));
- // 选入字体;
- this->SetFont(&m_cfont);
- }
- void CListSortCtrl::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)
- {
- // 不排序或无数据时退出;
- if ( !m_bSortSupport || m_AryList.GetSize() == 0)
- return;
- LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
- m_bSortAscending = !m_bSortAscending;
- for (int i = 0; i < m_nNumColumns; i++)
- {
- if( i == pNMLV->iSubItem )
- {
- SortByCol(i);
- m_Ctrlheader.SetSortArrow( i, m_bSortAscending );
- }
- }
- Invalidate();
-
- *pResult = 0;
- }
- void CListSortCtrl::OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult)
- {
- NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
- LV_ITEM *pItem = &pDispInfo->item;
- ASSERT(pItem);
- if (m_AryList.GetSize() > pItem->iItem && (pItem->mask & LVIF_TEXT) )//valid text buffer?
- {
- //_tcscpy_s(pItem->pszText, pItem->cchTextMax, m_AryList.ElementAt(pItem->iItem).ElementAt(pItem->iSubItem));
- StringCbCopy(pItem->pszText, pItem->cchTextMax, m_AryList.ElementAt(pItem->iItem).ElementAt(pItem->iSubItem));
- }
- *pResult = 0;
- }
- #ifndef __LIST_DRAW__
- void CListSortCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
- {
- NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
- *pResult = 0;
- if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
- {
- *pResult = CDRF_NOTIFYITEMDRAW;
- }
- else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
- {
- INT npos = pLVCD->nmcd.dwItemSpec;
- if ( npos % 2 )
- pLVCD->clrTextBk = m_clrLightGrid;
- else
- pLVCD->clrTextBk = m_clrDarkGrid;
- *pResult = CDRF_DODEFAULT;
- }
- }
- #endif
- void CListSortCtrl::SortByCol(IN const int nColIndex)
- {
- m_nCompareColumn = nColIndex;
- ::AfxGetApp()->DoWaitCursor(TRUE);
- qsort( static_cast<void*>(&m_AryList[0]), m_AryList.GetSize(), sizeof(m_AryList[nColIndex]), CompareByLabel);
- ::AfxGetApp()->DoWaitCursor(FALSE);
- }
- void CListSortCtrl::LoadColumnInfo()
- {
- ASSERT( m_nNumColumns > 0 );
- UINT nBytes = 0;
- BYTE* buf = NULL;
- CMD5 md5;
- md5.SetBYTEText((BYTE*)m_strSection.GetString(), m_strSection.GetLength()*sizeof(TCHAR));
- m_strSection = md5.GetMD5Digest();
- if( AfxGetApp()->GetProfileBinary( _T("sortlist"), m_strSection, &buf, &nBytes ) )
- {
- if( nBytes > 0 )
- {
- CMemFile memFile( buf, nBytes );
- CArchive ar( &memFile, CArchive::load );
- m_Ctrlheader.Serialize( ar );
- ar.Close();
- m_Ctrlheader.Invalidate();
- }
- delete[] buf;
- }
- }
- void CListSortCtrl::SaveColumnInfo()
- {
- ASSERT( m_nNumColumns > 0 );
- CMemFile memFile;
- CArchive ar( &memFile, CArchive::store );
- m_Ctrlheader.Serialize( ar );
- ar.Close();
- DWORD dwLen = memFile.GetLength();
- BYTE* buf = memFile.Detach();
- VERIFY( AfxGetApp()->WriteProfileBinary( _T("sortlist"), m_strSection, buf, dwLen ) );
- free( buf );
- }
- void CListSortCtrl::OnDestroy()
- {
- SaveColumnInfo();
- CListCtrl::OnDestroy();
- }
|