Editing using hints - worked example
key : purple - original code / blue - new code
Step 1 :
Continue with the program names.
Step 2 :
Edit the original code in the AddNames() function within the Document. A Hint and a pointer to the required position should be included :
void
CNamesDoc::AddNames()
{
CEnterNamesDlg dlg;
if(dlg.DoModal() == IDOK)
{CName* temp = new CName(dlg.m_strTitle,
dlg.m_strFirstName, dlg.m_strSecondName);
m_NameList.AddTail(temp);
m_nCurrentPosition = m_NameList.GetTailPosition();
CName * pCurrentName = m_NameList.GetAt(m_nCurrentPosition);
UpdateAllViews(NULL, HINT_ADD_NAME, pCurrentName);}
}
Step 3 :
Edit the original code in the OnRemoveCurrentName() function within the Document. A Hint and a pointer to the required position should be included :
void
CNamesDoc::OnRemoveCurrentName()
{
if( !m_NameList.IsEmpty() )
{//Store current item to be deleted
CName * pCurrentName = GetCurrentName();
//First sort out new current item
POSITION nTemp = m_nCurrentPosition;
m_NameList.GetNext(m_nCurrentPosition);
if(m_nCurrentPosition==NULL)
{m_nCurrentPosition = nTemp;
m_NameList.GetPrev(m_nCurrentPosition);}
m_NameList.RemoveAt(nTemp);
UpdateAllViews(NULL,HINT_DELETE_NAME, pCurrentName);
delete pCurrentName;}
else
{AfxMessageBox("There are no items to delete.");
}
}
Step 4 :
Edit the original code in the OnRemoveAllNames() function within the Document. A Hint and should be included, a pointer in this case is not necessarry :
void
CNamesDoc::OnRemoveAllNames()
{
if( !m_NameList.IsEmpty() )
{// firstly delete all the pointers to avoid memory leaks
POSITION pos = m_NameList.GetHeadPosition();
while( pos != NULL )
{
delete m_NameList.GetNext( pos );
}
// now delete all the m_NameList
m_NameList.RemoveAll();
m_nCurrentPosition = NULL;
UpdateAllViews(NULL, HINT_DELETE_ALL_NAMES);
}
else
{AfxMessageBox("There are no items to delete.");
}
}
Step 5 :
The response to these hints must now be put into the OnUpdate() function within NameListView. A switch statement should be used. It should be observed that to delete all of the list only one line of code is required :
void
CNameListView::OnUpdate(CView* pSender, LPARAM lHint, CObject*
pHint)
{
CListCtrl& listCtrl = GetListCtrl(); // Get list ctrl
// first cast the pHint to a CName type
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;}
}
Step 6 :
Add the code to the AddNameToListCtrl() function :
void
CNameListView::AddNameToListCtrl(CName * pNameTemp)
{
CListCtrl& m_listCtrl = GetListCtrl();
LV_ITEM listItem;
listItem.mask = LVIF_TEXT | LVIF_IMAGE;
listItem.iSubItem = 0;
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();
}
Step 7 :
Now the AddInitialList() function may be simplified using the AddNameToListCtrl() function :
void
CNameListView::AddInitialList()
{
CListCtrl& m_listCtrl = GetListCtrl();
POSITION pos;
CNamesDoc* pDoc = (CNamesDoc*)m_pDocument;
pos = pDoc->GetHeadPosition();
while(pos != NULL)
{CName * pName = ((CNamesDoc*)m_pDocument)->GetNextItem(pos);
AddNameToListCtrl(pName);}
}
Step 8 :
Add the DeleteNameFromListCtrl() function :
void
CNameListView::DeleteNameFromListCtrl(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.DeleteItem(nItem);
}
}
}
Click here for the basic exercise
Click here for the source code
Click here to return to menu