Introduction
Recently, in one of my projects, I needed a CListCtrl
derived class which has the ability to show/hide its columns dynamically. Using CListCtrl::DeleteColumn()
is not a good idea because in that case the index of the sub items will be changed from time to time, thus assessing the sub items will become very complicated. I searched the Internet and did not find an existing solution for this. At last, I had to write my own class - CListCtrlEx
to implement the feature.
The main features of CListCtrlEx
- Dynamically hide/show the columns.
- Provide a built-in context menu to select the columns and it is dynamically created based on the columns you insert.
- Drag-and-drop reorder columns (you must enable the
LVS_EX_HEADERDRAGDROP
style).
- Save/restore the columns' order, width and visibility in/from registry automatically.
- You do not need to change your existing code of
CListCtrl
derived classes. All you have to do is change their base class to CListCtrlEx
.
Using the CListCtrlEx class
- Add the following files to your project:
- HeaderCtrlEx.h
- HeaderCtrlEx.cpp
- ListCtrlEx.h
- ListCtrlEx.cpp
- Import the following two cursor files into you resource and change their ID as mentioned in the square brackets:
- res\VE_SPLIT.CUR [
IDC_HEADER_OPEN
]
- res\VE_SIZEB.CUR [
IDC_HEADER_SIZE
]
- Derive your own class, say
CMyListCtrl
, from CListCtrlEx
.
- Add a list control to your dialog in the resource editor and bind it to a member variable, say
m_wndList
. Of course the variable should be a CMyListCtrl
object.
void CTestListCtrlDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST, m_wndList);
}
- Save/restore the state of the columns.
BOOL CTestListCtrlDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_wndList.SetExtendedStyle(m_wndList.GetExtendedStyle()
| LVS_EX_HEADERDRAGDROP);
m_wndList.SetRegistryKey("MyListCtrl");
m_wndList.RestoreState();
}
void CTestListCtrlDlg::OnDestroy()
{
CDialog::OnDestroy();
m_wndList.SaveState();
}