Introduction
While creating a List Control using CListCtrl
class, we need to specify the column width for all the columns in the very beginning, when we have little idea about the width required by the actual text that is going to come in the columns. So we leave it to the user to adjust the widths to see the entire text. This little enhancement over the CListCtrl
class makes the column widths auto adjusting to keep the entire text of all the columns visible.
Make a new Dialog based application with MFC AppWizard (EXE). Then add a new class to it (Insert -> New Class). Give any fancy name you wish (I chose CMyListCtrl
) and in the base class dropdown, select CListCtrl
. After clicking OK, you have a CListCtrl
derived class. Now add the following two public
functions to this class:
void AdjustColumnWidth();
int GetColumnCount();
void CMyListCtrl::AdjustColumnWidth()
{
SetRedraw(FALSE);
int nColumnCount = GetColumnCount();
for (int i = 0; i < nColumnCount; i++)
{
SetColumnWidth(i, LVSCW_AUTOSIZE);
int nColumnWidth = GetColumnWidth(i);
SetColumnWidth(i, LVSCW_AUTOSIZE_USEHEADER);
int nHeaderWidth = GetColumnWidth(i);
SetColumnWidth(i, max(nColumnWidth, nHeaderWidth));
}
SetRedraw(TRUE);
}
int CMyListCtrl::GetColumnCount()
{
CHeaderCtrl* pHeaderCtrl = GetHeaderCtrl();
return (pHeaderCtrl->GetItemCount());
}
As we can see, this function calculates the widths of the Column Headers as well as the Items and sets the width to the larger of the two, so that the complete header is visible even if no item is inserted. Also note that the last column will take all the remaining space.
To use our newly created class, first add a List Control to your dialog box (be sure to select 'Report' in the Styles page of the properties for the new control). Now, add a control variable for the newly created item (IDC_LIST1
, or whatever ID you supplied) in the Member Variables page of the MFC Class Wizard (ctrl+W), but instead of accepting the default CListCtrl
as the Variable type, select the new CMyListCtrl
type. Call the variable m_myList
. The wizard will suggest you to include the header file of your ListCtrl
class in the dialog class. Do this by adding this line in the header file of your dialog class:
#include <MyListCtrl.h>
After this, let’s insert some columns and rows to this ListCtrl
. Add the following lines at the end of OnInitDialog()
of your dialog class (or wherever you need):
m_myList.InsertColumn(0, _T("First column, which is very long"));
m_myList.InsertColumn(1, _T("2nd column"));
m_myList.InsertColumn(2, _T("Third column"));
m_myList.InsertColumn(3, _T("Forth column"));
m_myList.InsertItem(0, _T("Item 1"));
m_myList.InsertItem(1, _T("Item 2"));
m_myList.InsertItem(2, _T("Item 3"));
m_myList.SetItemText(0, 1, _T("This text is long."));
m_myList.SetItemText(0, 3, _T("This text is even longer."));
m_myList.SetItemText(1, 1, _T("Small text."));
m_myList.SetItemText(2, 3, _T("Some text here."));
If it feels a little too involved to add the rows in a List Control, you can refer to this article for a simpler way. Now, call the function AdjustColumnWidth()
after inserting all rows.
m_myList.AdjustColumnWidth();
The call to this function makes sure all items and their headers are visible. You can play around with this example by putting different strings in the columns.
Enjoy!
History
- 29th August, 2005: Initial post