6.10 Add Utility Member Functions

This section explains the twelfth step in writing Phone Book: add utility member functions. These are called by message-handler functions but are not message handlers themselves.

·To add the utility member functions:

1.Add the following FileDlg utility member function to the CMainWindow section of your VIEW.CPP file below the OnPaint member function and above Save:

// CMainWindow::FileDlg

// Call the commdlg routine to display File Open or File Save As

// dialogs. The setup is the same for either. If bOpen is TRUE

// then File Open is displayed otherwise File Save As is displayed.

// The File Name and File Title are stored at the string pointer

// passed in.

//

BOOL CMainWindow::FileDlg( BOOL bOpen, int nMaxFile, LPSTR szFile,

int nMaxFileTitle, LPSTR szFileTitle )

{

OPENFILENAME of;

char szDirName[SIZESTRING];

char * szFilter[] =

"Phone Book Files (*.pb)\0"

"*.pb\0"

"\0";

szDirName[0] = '.';

of.lStructSize = sizeof( OPENFILENAME );

of.hwndOwner = m_hWnd;

of.lpstrFilter = (LPSTR)szFilter;

of.lpstrCustomFilter = (LPSTR)NULL;

of.nMaxCustFilter = 0L;

of.nFilterIndex = 1L;

of.lpstrFile=szFile;

of.nMaxFile=nMaxFile;

of.lpszFileTitle = szFileTitle;

of.nMaxFileTitle = nMaxFileTitle;

of.lpstrInitialDir = szDirName;

of.lpstrTitle = (LPSTR)NULL;

of.nFileOffset = 0;

of.nFileExtension = 0;

of.lpstrDefExt = (LPSTR)"pb";

if ( bOpen )

{

of.Flags = OFN_HIDEREADONLY;

return GetOpenFileName( &of );

}

else

{

of.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;

return GetSaveFileName( &of );

}

}

FileDlg is a utility function that displays a standard Windows open
file dialog box. If the call is to open a file, FileDlg calls the
GetOpenFileName
function defined in COMMDLG.DLL. Otherwise,
it calls the GetSaveFileName function. For more discussion of FileDlg,
see “OnOpen” on page 214.

2.Add the following CheckForSave utility member function to the CMainWindow section of your VIEW.CPP file below the Save member function:

// CMainWindow::CheckForSave

// Whenever a new file is opened this routine will determine if

// there are unsaved changes in the current database. If so it

// will query the user and determine to save or not as appropriate.

//

BOOL CMainWindow::CheckForSave( const char* pszTitle,, const char* pszMessage )

{

if( m_people.IsDirty() )

{

UINT nButton = MessageBox( pszMessage,, pszTitle,,

MB_YESNOCANCEL );

if( nButton == IDYES )

{

if( !Save( m_people.IsNamed() )

return FALSE;

}

else if( nButton == IDCANCEL )

return FALSE;

}

return TRUE;

}

CheckForSave is called from a number of other member functions that need to check for a current database with unsaved changes. If there are unsaved changes, the function uses the MessageBox member function of class CWnd to query the user's wishes. If the user clicks the message box's Yes button, the Save member function is called to do the work.

3.Add the following SetMenu utility member function to the CMainWindow section of your VIEW.CPP file below the CheckForSave member function:

// CMainWindow::SetMenu

// Whenever the Existence of the DataBase is changed this

// routine will reset the menus so only the possible commands

// are accessible.

//

void CMainWindow::SetMenu()

{

CMenu* pMenu = GetMenu();

if ( m_people.IsPresent() )

{

if ( m_people.IsNamed() )

pMenu -> EnableMenuItem( IDM_SAVE, MF_ENABLED );

else

pMenu -> EnableMenuItem( IDM_SAVE, MF_GRAYED );

pMenu -> EnableMenuItem( IDM_SAVEAS, MF_ENABLED );

pMenu -> EnableMenuItem( IDM_CLOSE, MF_ENABLED );

pMenu -> EnableMenuItem( IDM_PRINT, MF_ENABLED );

pMenu -> EnableMenuItem( IDM_ADD, MF_ENABLED );

pMenu -> EnableMenuItem( IDM_DELETE, MF_ENABLED );

pMenu -> EnableMenuItem( IDM_FIND, MF_ENABLED );

pMenu -> EnableMenuItem( IDM_EDIT, MF_ENABLED );

}

else

{

pMenu -> EnableMenuItem( IDM_SAVE, MF_GRAYED );

pMenu -> EnableMenuItem( IDM_SAVEAS, MF_GRAYED );

pMenu -> EnableMenuItem( IDM_CLOSE, MF_GRAYED );

pMenu -> EnableMenuItem( IDM_PRINT, MF_GRAYED );

pMenu -> EnableMenuItem( IDM_ADD, MF_GRAYED );

pMenu -> EnableMenuItem( IDM_DELETE, MF_GRAYED );

pMenu -> EnableMenuItem( IDM_FIND, MF_GRAYED );

pMenu -> EnableMenuItem( IDM_FINDALL, MF_GRAYED );

pMenu -> EnableMenuItem( IDM_EDIT, MF_GRAYED );

}

}

SetMenu is a utility function that updates the menus to reflect the current context. It disables (grays or dims) menu commands that are not valid currently and enables menu commands that are valid.

4.Add the following InvalidateLine utility member function to the CMainWindow section of your VIEW.CPP file below the SetMenu member function:

// CMainWindow::InvalidateLine

// Marks the screen area of the currently selected person as

// invalid causing windows to call OnPaint to redraw the area.

// This is normally used when the selected line is being changed.

//

void CMainWindow::InvalidateLine()

{

CRect area( 0, ( m_nSelectLine - m_nVscrollPos ) * m_cyChar,

m_cxClient,

( m_nSelectLine + 1 - m_nVscrollPos ) * m_cyChar );

InvalidateRect( area );

}

InvalidateLine is a utility function that marks the screen area of the currently selected person as invalid. This causes Windows to send a WM_PAINT message so that OnPaint is called to repaint the area in the window.

This completes the code in file VIEW.CPP. You can compare your file to Listing 2 in Chapter 5. All code for VIEW.H and VIEW.CPP is now complete.

To continue the tutorial, see the next section.