Ever been annoyed at the amount of code you need just to insert a few rows and their
columns' text into a CListCtrl
while using the 'Report' style?
This little MFC subclassing tutorial provides a handy little enhancement to the
standard CListCtrl
, which can make life easier for both beginners and
not_so_beginners alike.
The code and text that follows assumes you have generated a typcal Dialog based
application with the MFC Application (.exe) Appwizard in MS Visual C++.
Derive a new CListCtrl
based class (here CMyListCtrl
).
In the VC IDE, this is as simple as selcting 'Add Class...' from the MFC Class wizard
then, in the new class dialog, naming the control and selecting CListCtrl
as
the base class in the drop down list.
To use the new class, start by adding a CListCtrl
to the dialog (be sure
to select 'Report' in the Styles page of the proprties for the new control) then, in the
Member Variables page of the MFC Class Wizard (ctrl+w), add a control variable for the
newly created item (IDC_LIST1
, or whatever ID you supplied) - but instead of
accepting the default CListCtrl
as the type, you will be able to select the
new CMyListCtrl
type. Call the variable m_myList
.
Specify
<font color="#0000FF">#include</font> "MyListCtrl.h"
in the header of the dialog class (in this case, the main dialog of the app) and you're
set.
In the code that VC generates for the new class, add the following:
<font color="#008040">
</font><font
color="#0000FF">int</font> InsertRow(<font color="#0000FF">int</font> nPos,<font
color="#0000FF">int</font> nNoOfCols, LPCTSTR pText, ...);
<font color="#008040">
<font
color="#0000FF">int</font> CMyListCtrl::InsertRow(<font color="#0000FF">int</font> nPos,<font
color="#0000FF">int</font> nNoOfCols, LPCTSTR pText, ...)
{
va_list argList;
va_start(argList, pText);
ASSERT(nNoOfCols >= 1); <font
color="#008040">
<font
color="#0000FF">int</font> nIndex = InsertItem(LVIF_TEXT|LVIF_STATE, nPos, pText,0,LVIS_SELECTED,0,0);
ASSERT(nIndex != -1);
<font
color="#0000FF">if</font> (nIndex < 0) <font color="#0000FF">return</font>(nIndex);
<font
color="#0000FF">for</font> (<font color="#0000FF">int</font> i = 1; i < nNoOfCols; i++) {
LPCSTR p = va_arg(argList,LPCSTR);
<font
color="#0000FF">if</font> (p != NULL) {
SetItemText(nIndex, i, p);
}
}
va_end(argList);
<font
color="#0000FF">return</font>(nIndex);
}
<font color="#008040">
</font>
myList.InsertRow(0,3,_T("Sample 1"),_T("Column 2 for row 1"),_T("Column 3 for row 1"));
myList.InsertRow(1,3,_T("Sample 2"),_T("Column 2 for row 2"),_T("Column 3 for row 2"));
myList.InsertRow(2,3,_T("Sample 3"),_T("Column 2 for row 3"),_T("Column 3 for row 3"));
myList.InsertRow(3,1,_T("Sample 4"));
myList.InsertRow(4,3,_T("Sample 5"),_T("Column 2 for row 5"),_T("Column 3 for row 5"));
myList.InsertRow(5,2,_T("Sample 6"),_T("Column 2 for row 6"));
To test, you might add a command button that executes the above code. Also, this
assumes that you have initialized the list with 3 columns - for the sake of this simple
example, you might provide the following in the OnInitDialog method of the dialog class:
<font color="#008040">
m_myList.InsertColumn(0, "Column 1");
m_myList.InsertColumn(1, "Column 2");
m_myList.InsertColumn(2, "Column 3");
m_myList.SetColumnWidth(0, 100);
m_myList.SetColumnWidth(1, 100);
m_myList.SetColumnWidth(2, 100);
Enjoy!
Professional IT developer since 1983. First projects with Cobol, then Pascal, Modula2, C and since Visual C++ 1.0 also with C++ and today C#. Works since 1986 as Consultant, between 1990 and 2008 for Infobrain in Switzerland, from 2008 until 2013 for enValue (also Switzerland) and currently working for Comfone (Bern, Switzerland).
Married, two grown-up daughters, Hobbies : Paragliding, Orienteering, Mountainbiking, Photography