16,471
社区成员
发帖
与我相关
我的任务
分享
#ifndef _SORTLISTCTRL_INCLUDE__
#define _SORTLISTCTRL_INCLUDE__
/////////////////////////////////////////////////////////////////////////////////////////
//一个点击列头时可以排序的列表类
class CSortListCtrl : public CListCtrl
{
// Construction
public:
CSortListCtrl();
// Attributes
public:
struct Info
{
CListCtrl* pListCtrl;
int nSubItem;
BOOL bAsc;
};
int ModiHeardCtrl(CHeaderCtrl* pHeardCtrl,int nItem,int nMode);
static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
// Operations
public:
CImageList m_ImageList;
BOOL m_bInit;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSortListCtrl)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CSortListCtrl();
// Generated message map functions
protected:
CBitmap* MakeColorBoxImage(BOOL bUp);
//{{AFX_MSG(CSortListCtrl)
afx_msg void OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif
/*
创建人: iamshuke
创建日期: 2002.06.28
说明: 一个单击表头时能排序的列表控件
*/
#include "stdAfx.h"
#include "sortlistctrl.h"
/////////////////////////////////////////////////////////////////////////////
// CSortListCtrl
CSortListCtrl::CSortListCtrl()
{
m_bInit = FALSE;
}
CSortListCtrl::~CSortListCtrl()
{
}
BEGIN_MESSAGE_MAP(CSortListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CSortListCtrl)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSortListCtrl message handlers
//单击表头时进行排序
void CSortListCtrl::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
*pResult = 0;
if(m_bInit == FALSE)
{
m_bInit = TRUE;
m_ImageList.Create(8,8,ILC_COLOR24|ILC_MASK,2,0);
m_ImageList.Add(MakeColorBoxImage(TRUE),RGB(0,0,255));
m_ImageList.Add(MakeColorBoxImage(FALSE),RGB(0,0,255));
GetHeaderCtrl()->SetImageList(&m_ImageList);
}
CHeaderCtrl *pHeardCtrl=GetHeaderCtrl();
for(int i=pHeardCtrl->GetItemCount()-1; i>=0; i--)
{
if(i == pNMListView->iSubItem)
{
continue;
}
ModiHeardCtrl(pHeardCtrl, i, -1);
}
int nMode = ModiHeardCtrl(pHeardCtrl,pNMListView->iSubItem,-2);
Info SortInfo;
SortInfo.pListCtrl = this;
SortInfo.nSubItem = pNMListView->iSubItem;
if(nMode == 0 )
{
SortInfo.bAsc=1;
}
else if(nMode == 1)
{
SortInfo.bAsc=0;
}
else
{
return;
}
int nItemCount = GetItemCount();
DWORD *buf = new DWORD[nItemCount];
for(i=0; i<nItemCount; i++)
{
buf[i] = GetItemData(i);
SetItemData(i,i);
}
//如果只有一列,ListCtrl将不能正确排序,所以添加一临时列,这是ListCtrl的一个BUG。
BOOL bOnlyOneColumn = FALSE;
if(pHeardCtrl->GetItemCount() == 1)
{
InsertColumn(1,"");
bOnlyOneColumn = TRUE;
}
SortItems(MyCompareProc,(DWORD)&SortInfo);
if(bOnlyOneColumn)
{
DeleteColumn(1);//去掉临时列
}
for(i=0; i<nItemCount; i++)
{
SetItemData(i, buf[GetItemData(i)]);
}
delete []buf;
}
int CALLBACK
CSortListCtrl::MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
// lParamSort contains a pointer to the list view control.
// The lParam of an item is just its index.
Info *pSortInfo;
pSortInfo=(Info*)lParamSort;
CString strItem1 = pSortInfo->pListCtrl->GetItemText(lParam1, pSortInfo->nSubItem);
CString strItem2 = pSortInfo->pListCtrl->GetItemText(lParam2, pSortInfo->nSubItem);
if(pSortInfo->bAsc)
return strItem1.CompareNoCase(strItem2);
else
return strItem2.CompareNoCase(strItem1);
}
int CSortListCtrl::ModiHeardCtrl(CHeaderCtrl* pHeardCtrl,int nItem,int nMode)
{
HDITEM hdi;
TCHAR lpBuffer[256];
hdi.mask = HDI_TEXT | HDI_IMAGE | HDI_LPARAM | HDI_FORMAT;
hdi.pszText = lpBuffer;
hdi.cchTextMax = 256;
if(pHeardCtrl->GetItem(nItem,&hdi) == FALSE)
{
return -2;
}
if((nMode < -1) || (nMode > 1))
{
nMode= (hdi.lParam == 0 ? 1 : 0) ;
}
hdi.lParam = nMode;
if(nMode == -1)
{
hdi.fmt &= ~HDF_BITMAP_ON_RIGHT;
hdi.fmt &= ~HDF_IMAGE;
hdi.mask &= ~HDI_IMAGE;
}
else
{
hdi.iImage = nMode;
hdi.fmt |= HDF_BITMAP_ON_RIGHT|HDF_IMAGE;
}
pHeardCtrl->SetItem(nItem,&hdi);
return nMode;
}
//生成表头上"向上箭头"和"向下箭头"两个位图
CBitmap* CSortListCtrl::MakeColorBoxImage(BOOL bUp)
{
CClientDC dc(this);
CBitmap* pBitmap = new CBitmap;
pBitmap->CreateCompatibleBitmap(&dc,8,8);
CDC tempDC;
tempDC.CreateCompatibleDC(&dc);
CBitmap* pOldBitmap;
pOldBitmap = tempDC.SelectObject(pBitmap);
CPen penLight,penShadow,*pOldPen;
tempDC.FillSolidRect(0,0,8,8,RGB(0,0,255));
if(bUp == TRUE)
{
static POINT s_PtShadow[9]={{3,0},{3,1},{2,1},{2,2},{2,3},{1,3},{1,4},{1,5},{0,5}};
static POINT s_PtLight[9]={{4,0},{4,1},{5,1},{5,2},{5,3},{6,3},{6,4},{6,5},{7,5}};
penLight.CreatePen(PS_SOLID,1,RGB(255,255,255));
pOldPen = tempDC.SelectObject(&penLight);
tempDC.MoveTo(0,6);
tempDC.LineTo(7,6);
for(int i=0;i<9;i++)
{
tempDC.SetPixel(s_PtLight[i],RGB(255,255,255));
}
for(i=0;i<9;i++)
{
tempDC.SetPixel(s_PtShadow[i],RGB(100,100,100));
}
tempDC.SelectObject(pOldPen);
}
else if(bUp == FALSE)
{
static POINT s_PtShadow[9]={{0,1},{1,1},{1,2},{1,3},{2,3},{2,4},{2,5},{3,5},{3,6}};
static POINT s_PtLight[9]={{7,1},{6,1},{6,2},{6,3},{5,3},{5,4},{5,5},{3,5},{4,6}};
penShadow.CreatePen(PS_SOLID,1,RGB(100,100,100));
pOldPen = tempDC.SelectObject(&penShadow);
tempDC.MoveTo(7,0);
tempDC.LineTo(0,0);
for(int i=0;i<9;i++)
{
tempDC.SetPixel(s_PtLight[i],RGB(255,255,255));
}
for(i=0;i<9;i++)
{
tempDC.SetPixel(s_PtShadow[i],RGB(100,100,100));
}
tempDC.SelectObject(pOldPen);
}
else
{
//空白位图
}
tempDC.SelectObject(pOldBitmap);
return pBitmap;
}
int i, nItemCount = GetItemCount();
DWORD *buf = new DWORD[nItemCount];
for(i=0; i<nItemCount; i++)
{
buf[i] = GetItemData(i);
SetItemData(i, i);
}
SortItems(..., ...);
for(i=0; i<nItemCount; i++)
{
SetItemData(i, buf[GetItemData(i)]);
}
delete []buf;