1,头文件实现:
#if !defined(AFX_LISTCTRLEX_H__FD8138BA_775E_4491_ACCA_B5265EC70DBC__INCLUDED_)
#define AFX_LISTCTRLEX_H__FD8138BA_775E_4491_ACCA_B5265EC70DBC__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//
// ListCtrlEx.h : header file
//
/
// CListCtrlEx window
//
// 1,排序支持:按字符串不区分大小写顺序;必须预先设置唯一 lparam 参数。
// 2,删除支持:快捷键“Delete”删除选定条目(多选)。
//
class CListCtrlEx : public CListCtrl
{
public:
BOOL EnableFunc(DWORD dwMask); // 打开功能(使生效,默认不开任何功能)
public:
static const DWORD funcAll; // 功能掩码:所有功能 0xffffffff
static const DWORD funcSort; // 功能掩码:排序支持 0x00000001
static const DWORD funcDelete; // 功能掩码:删除支持 0x00000002
protected:
// 排序的比较函数
static int CALLBACK CompareByParam(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
// 成员变量:功能掩码(默认不开任何功能)
DWORD m_dwFuncMask;
// 成员变量:记录排序的升降序
BOOL m_bAscending;
// 成员变量:记录排序的列
int m_iSortCol;
// Construction
public:
CListCtrlEx();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CListCtrlEx)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CListCtrlEx();
// Generated message map functions
protected:
//{{AFX_MSG(CListCtrlEx)
afx_msg void OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_LISTCTRLEX_H__FD8138BA_775E_4491_ACCA_B5265EC70DBC__INCLUDED_)
2,类实现文件:
// ListCtrlEx.cpp : implementation file
//
#include "stdafx.h"
#include "ListCtrlEx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CListCtrlEx
const DWORD CListCtrlEx::funcAll = 0xffffffff;
const DWORD CListCtrlEx::funcSort = 0x00000001;
const DWORD CListCtrlEx::funcDelete = 0x00000002;
CListCtrlEx::CListCtrlEx():m_dwFuncMask(0), m_bAscending(TRUE), m_iSortCol(-2)
{
}
CListCtrlEx::~CListCtrlEx()
{
}
BEGIN_MESSAGE_MAP(CListCtrlEx, CListCtrl)
//{{AFX_MSG_MAP(CListCtrlEx)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
ON_WM_KEYDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CListCtrlEx message handlers
BOOL CListCtrlEx::EnableFunc(DWORD dwMask)
{
m_dwFuncMask = m_dwFuncMask | dwMask;
return TRUE;
}
int CALLBACK CListCtrlEx::CompareByParam(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
CListCtrlEx* pListView = (CListCtrlEx*)lParamSort;
int iCol = pListView->m_iSortCol;
int iFactor = (pListView->m_bAscending) ? 1 : (-1);
if ( (-1) == iCol )
{
return iFactor * (lParam1 - lParam2);
}
else
{
LVFINDINFO info;
info.flags = LVFI_PARAM;
info.lParam = lParam1;
int iIndex1 = pListView->FindItem(&info);
info.lParam = lParam2;
int iIndex2 = pListView->FindItem(&info);
CString strItem1 = pListView->GetItemText(iIndex1, iCol);
CString strItem2 = pListView->GetItemText(iIndex2, iCol);
return iFactor * _tcsicmp(strItem1, strItem2);
}
}
void CListCtrlEx::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
if (m_dwFuncMask & CListCtrlEx::funcSort)
{
// 获取排序的列
int iColumn = pNMListView->iSubItem;
// 设置升降序
if (m_iSortCol == iColumn)
{
m_bAscending = !m_bAscending;
}
else
{
m_bAscending = TRUE;
m_iSortCol = iColumn;
}
SortItems(CompareByParam, (LPARAM)this);
}
*pResult = 0;
}
void CListCtrlEx::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
if ((nChar == VK_DELETE)
&& (m_dwFuncMask & CListCtrlEx::funcDelete)
)
{
CDWordArray arrDel;
POSITION pos = GetFirstSelectedItemPosition();
// 循环处理多个选择的情况
while (pos)
{
int nItem = GetNextSelectedItem(pos);
// record to delete the selected
// we can not delete them here
arrDel.Add(nItem);
}
for (int i = 0; i < arrDel.GetSize(); i++)
{
DeleteItem(arrDel[arrDel.GetSize() - 1 - i]);
}
}
CListCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
3,在单文档中使用:(可以直接使用该类,也可以使用 ClassWizard 来建立 CListCtrlEx 的派生类)
/
// CSD_FileScannerView message handlers
int CSD_FileScannerView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// create listctrl
RECT rect;
GetClientRect(&rect);
m_listCtrl.Create( WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_AUTOARRANGE | LVS_SHOWSELALWAYS
, rect
, this
, 1
);
m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT);
m_listCtrl.EnableFunc(CListCtrlEx::funcSort);
// set columns
int iWidth = rect.right - rect.left;
m_listCtrl.InsertColumn(0, _T("# NO."), LVCFMT_RIGHT, 60);
m_listCtrl.InsertColumn(1, _T("File"), LVCFMT_LEFT, iWidth*6/10);
m_listCtrl.InsertColumn(2, _T("Status"), LVCFMT_LEFT, 80);
m_listCtrl.InsertColumn(3, _T("Last Modify Time"), LVCFMT_LEFT, 130);
m_listCtrl.InsertColumn(4, _T("Size(Bytes)"), LVCFMT_RIGHT, iWidth*1/10);
return 0;
}