Listctrl - worked example
key : purple - original code / blue - new code
Step 1 :
Continue with the program names.
Step 2 :
Add a new class to the project, this will be the view in which the List Control is housed. Call this class CNameListView, it should inherit from the MFC CListView class. This new class needs the following include statement within its header :
#include <afxcview.h>
Step 3 :
To allow this class to be displayed the appropriate code must be added to the Application and the MainFrame. Link this to the menu and tool bar. These steps were covered previously in Task 4 (view) steps 5 to 10.
Step 4 :
An image list should be created. Click Insert / Resouce / Bitmap. For this example three 16 x 16 bitmaps are required (and three 32 x 32 bitmaps for later). Each list of three should be combined into one image as shown below :
The large view is what the user sees when in the bitmap editor, the view shown on the left is the image actual size. (The three images represent male, female or academic)
Define the corresponding member variables for the CImageList :
protected:
CImageList
m_imageLarge;
CImageList m_imageSmall;
Step 5 :
The virtual function OnInitialUpdate() should be added to the new class. This should then be given two void functions, the first SetListStyle() to set the list up, the second AddInitialList() to add the data to the list :
void
CNameListView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
SetListStyle();
AddInitialList();
}
Step 6 :
The SetListStyle() function is given below :
void
CNameListView::SetListStyle()
{
CListCtrl& m_listCtrl = GetListCtrl();
SetListView( LVS_REPORT );
m_imageLarge.Create( IDB_LARGE, 32, 1, RGB(255, 255, 255) );
m_imageSmall.Create( IDB_SMALL, 16, 1, RGB(255, 255, 255) );
m_listCtrl.SetImageList( &m_imageLarge, LVSIL_NORMAL );
m_listCtrl.SetImageList( &m_imageSmall, LVSIL_SMALL );
// Create list view columns and give them titles
LV_COLUMN listColumn;
char* arColumns[3] = { "Title", "First Name", "Second Name" };
listColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
listColumn.fmt = LVCFMT_LEFT;
listColumn.cx = 80;
for( int nColumn = 0; nColumn < 3; nColumn++ )
{listColumn.iSubItem = nColumn;
listColumn.pszText = arColumns[nColumn];
m_listCtrl.InsertColumn( nColumn, &listColumn );}
}
Step 7 :
To initialise the SetListStyle() function to display the data in Report format requires the SetListView() function :
void
CNameListView::SetListView(DWORD dwNewStyle)
{
DWORD dwOldStyle;
HWND hWndList;
CListCtrl& m_listCtrl = GetListCtrl();
hWndList = m_listCtrl.GetSafeHwnd();
dwOldStyle = GetWindowLong( hWndList, GWL_STYLE );
if( (dwOldStyle & LVS_TYPEMASK) != dwNewStyle )
{dwOldStyle &= ~LVS_TYPEMASK;
dwNewStyle |= dwOldStyle;
SetWindowLong( hWndList, GWL_STYLE, dwNewStyle );}
}
Step 8 :
The SetListStyle() function is given below :
void
CNameListView::AddInitialList()
{
CListCtrl& m_listCtrl = GetListCtrl();
//Add list items
LV_ITEM listItem;
listItem.mask = LVIF_TEXT | LVIF_IMAGE;
listItem.iSubItem = 0;
POSITION pos;
CNamesDoc* pDoc = (CNamesDoc*)m_pDocument;
pos = pDoc->GetHeadPosition();
int nLoop = 0;
while(pos!=NULL)
{CName * pName = ((CNamesDoc*)m_pDocument)->GetNextItem(pos);
listItem.iItem = nLoop;
CString* temp = ((pName->GetTitleAddress()));
LPTSTR pBufTitle = (LPTSTR) temp->GetBuffer(temp->GetLength());
listItem.pszText = pBufTitle;
temp = ((pName->GetFirstNameAddress()));
LPTSTR pBufFirstName = (LPTSTR) temp->GetBuffer(temp->GetLength());
temp = ((pName->GetSecondNameAddress()));
LPTSTR pBufSecondName = (LPTSTR) temp->GetBuffer(temp->GetLength());
if( pNameTemp->GetTitle() == "Mr" ||
pNameTemp->GetTitle() == "Sir")
{listItem.iImage = 0;
}
else if( pNameTemp->GetTitle() == "Dr" ||
pNameTemp->GetTitle() == "Prof")
{listItem.iImage = 2;
}
else // 99% certain that they must be female
{listItem.iImage = 1;
}
m_listCtrl.InsertItem( &listItem );
m_listCtrl.SetItemText( nLoop, 1, pBufFirstName );
m_listCtrl.SetItemText( nLoop, 2, pBufSecondName );
temp->ReleaseBuffer();
nLoop ++;}
}
Step 9 :
As the m_listCtrl needs the address of the CStrings from the original list and not the actual CString, three new functions must be added to the CName class :
CString *
CName::GetTitleAddress()
{
return &m_strTitle;
}
CString *
CName::GetFirstNameAddress()
{
return &m_strFirstName;
}
CString *
CName::GetSecondNameAddress()
{
return &m_strSecondName;
}
Click here for the basic exercise
Click here for the source code
Click here to return to menu