Selecting items in the list - worked example
key : purple - original code / blue - new code
Step 1 :
Continue with the program names.
Step 2 :
Edit the MoveCurrentBack() (and MoveCurrentForward()) functions by adding the following hint :
void
CNamesDoc::MoveCurrentBack()
{
if( !m_NameList.IsEmpty() )
{m_NameList.GetPrev(m_nCurrentPosition);
if( m_nCurrentPosition == NULL )
{AfxMessageBox("End of list reached");
m_nCurrentPosition = m_NameList.GetHeadPosition();}
CName * pCurrentName = m_NameList.GetAt(m_nCurrentPosition);
UpdateAllViews(NULL, HINT_MOVE_CURRENT, pCurrentName);}
else
{AfxMessageBox("There are no items in the list.");
}
}
Step 3 :
Edit the OnUpdate() function to call a new function on this hint :
void
CNameListView::OnUpdate(CView* pSender, LPARAM lHint, CObject*
pHint)
{
CListCtrl& listCtrl = GetListCtrl(); // Get list ctrl
CName * pName = (CName *)pHint;
long messageType = (long)lHint;
switch (lHint)
{case HINT_DELETE_ALL_NAMES:
//do not need seperate function as just one line of code
listCtrl.DeleteAllItems();
break;
case HINT_ADD_NAME:
AddNameToListCtrl(pName);
break;
case HINT_DELETE_NAME:
DeleteNameFromListCtrl(pName);
break;
case HINT_MOVE_CURRENT:
SelectNewItem(pName);
break;}
}
Step 4 :
Add the function SelectNewItem(pName). LVIS_SELECTED is of type UINT and signifies that it is the selected item that has changed :
void
CNameListView::SelectNewItem(CName *pNameTemp)
{
CListCtrl& m_listCtrl = GetListCtrl();
LV_ITEM listItem;
listItem.mask = LVIF_TEXT | LVIF_IMAGE;
listItem.iSubItem = 0;
CString strtempTitle = (pNameTemp->GetTitle());
CString strtempFirstName = (pNameTemp->GetFirstName());
CString strtempSecondName = (pNameTemp->GetSecondName());
for( int nItem = 0; nItem < m_listCtrl.GetItemCount(); nItem++)
{if(strtempTitle == m_listCtrl.GetItemText(nItem, 0) &&
strtempFirstName == m_listCtrl.GetItemText(nItem, 1) &&
strtempSecondName == m_listCtrl.GetItemText(nItem, 2))
{m_listCtrl.SetItemState(nItem, LVIS_SELECTED,
LVIS_SELECTED)}
}
}
Step 5 :
Add a Windows Message Handler to the NameListView. This creates the function OnItemChanged(). The if statements check that all of the states are correct.
void
CNameListView::OnItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
CListCtrl& m_listCtrl = GetListCtrl();
// TODO: Add your control notification handler code here
if( pNMListView->uChanged & LVIF_STATE )
{if(!( pNMListView->uOldState & LVIS_SELECTED))
{if( pNMListView->uNewState & LVIS_SELECTED)
{LV_ITEM listItem;
listItem.mask = LVIF_TEXT | LVIF_IMAGE;
CString strTitle = m_listCtrl.GetItemText(pNMListView->iItem, 0);
CString strFirstName = m_listCtrl.GetItemText(pNMListView->iItem, 1);
CString strSecondName = m_listCtrl.GetItemText(pNMListView->iItem, 2);
CNamesDoc* pDoc = (CNamesDoc*)m_pDocument;
pDoc->ChangeToNewCurrent(strTitle, strFirstName, strSecondName);
*pResult = 0;}
}
}
}
Step 6 :
Add the ChangeToNewCurrent() function to the Document :
void
CNamesDoc::ChangeToNewCurrent(CString strTitle,
CString strFirstName, CString strSecondName)
{
m_nCurrentPosition = GetHeadPosition();
POSITION pos = m_nCurrentPosition;while(pos!=NULL)
{CName * pNameTemp = m_NameList.GetAt(pos);
if( pNameTemp->GetTitle()== strTitle &&
pNameTemp->GetFirstName() == strFirstName &&
pNameTemp->GetSecondName() == strSecondName )
{m_nCurrentPosition = pos;
}
m_NameList.GetNext(pos);
}UpdateAllViews(NULL);
}
Click here for the basic exercise
Click here for the source code
Click here to return to menu