Callback - worked example
key : purple - original code / blue - new code
Step 1 :
Continue with the program names.
Step 2 :
Set the pszText member of the ListCtrl to LPSTR_TEXTCALLBACK :
void
CNameListView::AddNameToListCtrl(CName * pNameTemp)
{
CListCtrl& m_listCtrl = GetListCtrl();
LV_ITEM listItem;
listItem.mask = LVIF_PARAM | LVIF_TEXT | LVIF_IMAGE;
listItem.iSubItem = 0;
listItem.lParam = (LPARAM)pNameTemp;
listItem.pszText = LPSTR_TEXTCALLBACK;
Step 3 :
Add the LVN_GETDISPINFO windows message handler to the ListCtrl.
void
CNameListView::OnGetDispInfo(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
*pResult = 0;
}
Step 4 :
Edit the code in this function to allow the text to be obtained from the old list.
void
CNameListView::OnGetDispInfo(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
if( pDispInfo->item.mask & LVIF_TEXT )
{CName* pName = (CName*)pDispInfo->item.lParam;
if( pDispInfo->item.iSubItem == 0 )
{strcpy( pDispInfo->item.pszText, pName->GetTitle() );
}
else if( pDispInfo->item.iSubItem == 1 )
{strcpy( pDispInfo->item.pszText, pName->GetFirstName() );
}
else if( pDispInfo->item.iSubItem == 2 )
{strcpy( pDispInfo->item.pszText, pName->GetSecondName() );
}
}
*pResult = 0;
}
Step 5 :
Use the same technique for the images :
void
CNameListView::AddNameToListCtrl(CName * pNameTemp)
{
CListCtrl& m_listCtrl = GetListCtrl();
LV_ITEM listItem;
listItem.mask = LVIF_PARAM | LVIF_TEXT | LVIF_IMAGE;
listItem.iSubItem = 0;
listItem.lParam = (LPARAM)pNameTemp;
listItem.pszText = LPSTR_TEXTCALLBACK;
listItem.iImage = I_IMAGECALLBACK;
Step 6 :
Add new code to the GetDispInfo() function :
void
CNameListView::OnGetDispInfo(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
CName* pName = (CName*)pDispInfo->item.lParam;
if( pDispInfo->item.mask & LVIF_TEXT )
{if( pDispInfo->item.iSubItem == 0 )
{strcpy( pDispInfo->item.pszText, pName->GetTitle() );
}
else if( pDispInfo->item.iSubItem == 1 )
{strcpy( pDispInfo->item.pszText, pName->GetFirstName() );
}
else if( pDispInfo->item.iSubItem == 2 )
{strcpy( pDispInfo->item.pszText, pName->GetSecondName() );
}
}
if( pDispInfo->item.mask & LVIF_IMAGE )
{if( pName->GetTitle() == "Mr" ||
pName->GetTitle() == "Sir")
{pDispInfo->item.iImage = 0;
}
else if( pName->GetTitle() == "Dr" ||
pName->GetTitle() == "Prof")
{pDispInfo->item.iImage = 2;
}
else // 99% certain that they must be female
{pDispInfo->item.iImage = 1;
}
}
*pResult = 0;
}
Step 7 :
Now delete the code that is no longer required (the code below in red) :
void
CNameListView::AddNameToListCtrl(CName * pNameTemp)
{
CListCtrl& m_listCtrl = GetListCtrl();
LV_ITEM listItem;
listItem.mask = LVIF_PARAM | LVIF_TEXT | LVIF_IMAGE;
listItem.iSubItem = 0;
listItem.lParam = (LPARAM)pNameTemp;
listItem.pszText = LPSTR_TEXTCALLBACK;
CString* temp = ((pNameTemp->GetTitleAddress()));
/* LPTSTR pBufTitle = (LPTSTR) temp->GetBuffer(temp->GetLength());
listItem.pszText = pBufTitle;
temp = ((pNameTemp->GetFirstNameAddress()));
LPTSTR pBufFirstName = (LPTSTR) temp->GetBuffer(temp->GetLength());
temp = ((pNameTemp->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;
}
listItem.iItem = m_listCtrl.GetItemCount();
m_listCtrl.InsertItem( &listItem );
//puts the firstname in col one, second name in col 2
/* m_listCtrl.SetItemText( listItem.iItem, 1, pBufFirstName );
m_listCtrl.SetItemText( listItem.iItem, 2, pBufSecondName );
temp->ReleaseBuffer();*/
}
void
CNameListView::EditNameInListCtrl(CObject *pHintTemp)
{
CListCtrl& m_listCtrl = GetListCtrl();
LVFINDINFO findStruct;
findStruct.flags = LVFI_PARAM;
// this is the item that we want to change
findStruct.lParam = (LPARAM)pHintTemp;
// now change the item text - code similar to Initial function
LV_ITEM editItem;
editItem.iItem = m_listCtrl.FindItem(&findStruct);
CName * pNameTemp = (CName*)pHintTemp;
/* CString* temp = ((pNameTemp->GetTitleAddress()));
LPTSTR pBufTitle = (LPTSTR) temp->GetBuffer(temp->GetLength());
editItem.pszText = pBufTitle;
temp = ((pNameTemp->GetFirstNameAddress()));
LPTSTR pBufFirstName = (LPTSTR) temp->GetBuffer(temp->GetLength());
temp = ((pNameTemp->GetSecondNameAddress()));
LPTSTR pBufSecondName = (LPTSTR) temp->GetBuffer(temp->GetLength());
*/
if( pNameTemp->GetTitle() == "Mr" ||
pNameTemp->GetTitle() == "Sir")
{editItem.iImage = 0;
}
else if( pNameTemp->GetTitle() == "Dr" ||
pNameTemp->GetTitle() == "Prof")
{editItem.iImage = 2;
}
else // 99% certain that they must be female
{editItem.iImage = 1;
}
// redraws one item - not all
m_listCtrl.RedrawItems(editItem.iItem, editItem.iItem);
// changes the text to the edited text
/* m_listCtrl.SetItemText( editItem.iItem, 0, pBufTitle );
m_listCtrl.SetItemText( editItem.iItem, 1, pBufFirstName );
m_listCtrl.SetItemText( editItem.iItem, 2, pBufSecondName );
temp->ReleaseBuffer();
*/
}
Click here for the basic exercise
Click here for the source code
Click here to return to menu