Discussion: Person Menu Message Handlers

This section explains the Person menu message-handler member functions.

OnAdd

With a database open, the user can add new persons to the list. If the user chooses the Add command in the Person menu, the main window object's OnAdd member function is called.

OnAdd constructs a new CPerson object in the heap with new and displays a CEditDialog box to get information for the person. If the dialog returns IDOK, the new person object is added to the database and the window is repainted.

The function uses a CEditDialog dialog object to fill the new person object with data. The dialog object is constructed on the frame of the function and its DoModal member function is called to run the dialog. DoModal returns IDOK if the user clicked the OK button.

The new person object is added to the database by calling the AddPerson member function of the CDataBase object, which is stored in the main window object's m_people member variable. At this point, the function calls the main window object's OnSize member to recalibrate the scroll bars for the new number of persons in the database. (If the size of the data has exceeded the size of the window's client area, Windows automatically adds scroll bars.) Notice this explicit use of OnSize, which is normally called in response to a Windows WM_SIZE message. For more information on OnSize, see page 226.

After adding the new person to the database and recalibrating the scroll bars, OnAdd invalidates the entire client area of the window.

OnDelete

In addition to adding new persons, the user can delete existing persons from the database. If the user first selects a line of the display representing a person and then chooses the Delete command in the Person menu, the main window object's OnDelete member function is called.

A person must be selected before it's possible to delete that person from the database. So OnDelete first checks to see if there is a current selection. If there isn't, the m_nSelectLine member variable of the main window object has the value –1. In that case, OnDelete displays a Windows message box requesting that the user make a selection first, and returns.

If there is a selection, the function calls its CDataBase object's DeletePerson member, through the main window object's m_people member variable, passing the selection line number as an index to use in finding the correct person in the database. The Delete command can only be selected from the Person menu when the main database is being viewed. Then OnDelete locates the correct record in the database, deletes the person object there, and removes the entry from the list.

Once the indicated person has been deleted from the database, OnDelete continues by resetting the selection. Unless the person deleted was the last in the database, the function moves the selection to the next person. Otherwise, it moves the selection to the new last person. With the selection reset, OnDelete invalidates the client area of the window.

OnEdit

Besides adding and deleting persons, the user can edit persons in the database. If the user selects a person on the display and chooses the Edit command in the Person menu (or presses the ENTER key or double clicks the line with the mouse), the main window object's OnEdit member function is called.

As with OnDelete, a person must first be selected. If one isn't, OnEdit displays a Windows message box asking the user to make a selection first, then returns.

If a person is selected, OnEdit calls the database object's GetPerson member function, through m_people, passing the line number of the selection, which is used as an index into the list. This call returns a pointer to the selected person object.

OnEdit constructs a new, empty CPerson object, person, on the frame of the function and uses the overloaded assignment operator of class CPerson to assign the value of the person object retrieved from the list to the new person object. This allows the user to edit a copy rather than the original. Only if the user finishes editing the copy and clicks the OK button in the edit dialog box does the copy replace the original person object in the list.

The function constructs a CEditDialog object, passing it a pointer to the copy. While the dialog box runs, the user can edit the person object's first name, last name, or phone number. If the dialog box returns IDOK, the OnEdit calls the CDataBase object's ReplacePerson member to replace the original person object with the edited one. ReplacePerson copies the edited person's data into the old person object, gets the current date and time, and calls the new CPerson object's SetModTime member function to record the modification date.

After replacing the original person object in the database with the edited one, OnEdit invalidates the line that was changed.

OnFind and OnFindAll

While a database is open, the user can search it for persons with a given last name. If the user chooses the Find command in the Person menu, the main window object's OnFind member function is called. After OnFind has displayed a list of found persons in the window, the user can choose the FindAll command in the Person menu to redisplay the full database. This menu command calls the main window object's OnFindAll member function.

OnFind displays a CFindDialog box to get a last name to search for. The function then passes this name string as the argument in a call to the CDataBase object's DoFind member, through m_people. The database object's DoFind member function operates differently depending on the string passed to it. If the string argument passed is NULL, DoFind deletes any existing found list from a previous search.

If a string containing a last name is passed in, the database object's DoFind
member function calls the FindPerson member function of the CPersonList
object in m_pDataList to return a new CPersonList object containing pointers to all found objects. This list is assigned to the CDataBase object's m_pFindList member variable.

While the search is being conducted, the window title changes to the text “Phone Book - [database name] Found: [Search string]”.

OnFind next updates the menus, using an object of class CMenu, to enable the Find All command in the Person menu and disable the Add and Delete commands in the Person menu. The function constructs a CMenu object on the frame of the function and calls the Windows function GetMenu to obtain a pointer to the program's menus. Then the function calls member functions of the CMenu object to adjust the menus.

After updating menus, OnFind invalidates the client area so the window will be repainted to display the found list.

The main window object's OnFindAll member function works similarly, except that it doesn't need to get a search string from the user. The function calls the CDataBase object's DoFind member function, through m_people. The argument in this call to DoFind defaults to NULL, which causes DoFind to destroy the existing found list. When the window's contents are redisplayed the next time OnPaint is called, the full database is displayed.

OnFindAll also updates the menus, as in OnFind, and invalidates the client area so the window will be repainted to display the full database.