CHKBOOK: Illustrates a Record-Based Document

Click to open or copy the CHKBOOK project files.

The CHKBOOK sample application primarily serves to illustrate the following Microsoft Foundation Class Library (MFC) features and programming techniques:

  1. Transaction-based file I/O, where the document (file) is written to on a per-transaction basis rather than on a load/save basis.

  2. Multiple views of a document, where (a) each view is of a different CView-derived class, and (b) each view is in a separate MDI child window.

  3. Using the CScrollView class, which supports viewing a document in a scrolling window.

  4. Using the CFormView class, which supports viewing a document using a form with controls laid out in a dialog template resource.

  5. Implementing page breaks during printing.

  6. Writing custom data exchange and validation (DDX/V) functions.

  7. Using a private .ini file to open a document automatically when the application is started.

  8. Use of the registry to associate the CHKBOOK data files with the CHKBOOK application, and to define a particular icon to represent the data in the Explorer in Windows® 95 and File Manager in Windows NT®3.51.

The CHKBOOK sample is a single document application in the sense that it allows only one checkbook file to be open at a time. But CHKBOOK uses MDI features of MFC to provide multiple views of the document via views in separate MDI child windows. To enforce that only one document is open at a time, CHKBOOK simply removes the File New and File Open commands from the menus and toolbars of the MDI children, which represent an already opened document.

The two views of the document are a check view and a book view. The check view, implemented in class CCheckView, provides a form for entering or viewing the data for a single check. The book view, implemented in CBookView, provides a scrolling window showing a summary of each check.

The CHKBOOK application supports the concept of current selection. The user can change the current selection in the book view by using up and down arrow keys, and by clicking a check with the mouse. The second check view always shows the current selection in the book view.

The check amount field in the check form view validates and converts a textual representation such as "19.98" to an internal DWORD representation. The use of DWORD facilitates money arithmetic better than, for example, floating point. CHKBOOK does not happen to do money arithmetic, but it easily could, for example, add up all the check amounts and display the total on a bottom line.

The check view shows an English text presentation of the check amount, such as "Nineteen and 98/100ths Dollars" as the user types in the numeric field.

The larger concepts CHKBOOK demonstrates are a record-based document, multiple views in separate MDI child windows, and custom data exchange (DDX).

Record-Based Document

A record-based document is one whose persistent data is updated each time the user adds, deletes, or modifies some portion of its data. Doing so requires overriding the framework's default implementation for file-based documents that are read entirely into memory upon File Open and are written entirely back to disk upon File Close.

Although CHKBOOK's document is a DOS file, the techniques employed also apply to documents whose persistent data is maintained in a database. CHKBOOK uses CFile::Read and Write.

CHKBOOK relies on a simple fixed-length record format for its file. This sample does not attempt to illustrate more sophisticated file organization. We have factored the design of CHKBOOK's document class into a generally reusable CFixedLenRecDoc class and a CHKBOOK-specific CChkBookDoc class, which is derived from CFixedLenRecDoc. You can follow CHKBOOK's example to derive your own document class from CFixedLenRecDoc.

Multiple Views of Distinct CView-Derived Classes, in Separate MDI Child Windows

CHKBOOK implements multiple views of a document, in which each view object is of a different CView-derived class and each view object is framed by a distinct MDI child window. CHKBOOK has two distinct CMultiDocTemplate objects — one corresponding to the check view and one to the book view.

The typical use of CMultiDocTemplate objects is to create an independent set of document frame and view objects. CHKBOOK has two CMultiDocTemplate objects, both using the same CChkBookDoc document class but having distinct view classes. The CChkBookApp::InitInstance function calls AddDocTemplate for both template objects, although only one is needed. To prevent the framework from presenting the user with the File New dialog box that lists two candidate file types, the DocTemplate string resource for the second (IDR_BOOKFRAME) document template does not have an entry corresponding to CDocTemplate::fileNewName.

CHKBOOK shows both views when the document is first opened. The user can later close one or the other view. To create the second frame and view and to ensure that it is attached to the first document, CHKBOOK overrides CWinApp::OpenDocumentFile. The override first calls the base class OpenDocumentFile, and the framework creates the first MDI child window and view. The override then explicitly calls CMultiDocTemplate::CreateNewFrame using the second document template object.

Custom Data Exchange (DDX) Function

CHKBOOK's DDX_DollarsCents function, implemented in DOLLCENT.CPP, is a custom DDX function. The m_dwCents member of CCheckView has a data map entry in CCheckView::DoDataExchange that calls this custom DDX_DollarsCents function. CHKBOOK's ClassWizard file, CHKBOOK.CLW, includes a hand-edited ExtraDDX1 entry that registers this custom DDX function with ClassWizard. For more information, see Technical Note 26!Alink("_MFCNOTES_TN026",0,_topic_not_found).

CHKBOOK Simplifications

The CHKBOOK sample has several simplifications to keep the code focused on the MFC features and techniques the sample is designed to illustrate. For example:

Running CHKBOOK

To install the necessary entries in your registration database, you must:

  1. Edit the CHKBOOK.REG file to provide the full path to CHKBOOK.EXE wherever it appears.

  2. Double-click the CHKBOOK.REG icon to merge the edited entries with the database.

Once the entries have been added, the CHKBOOK data files (.chb) will have their own distinctive icons. Double-clicking a data file will then run the CHKBOOK application, opening that particular file for editing.

This sample demonstrates the following keywords:

AfxFormatString1; AfxMessageBox; AfxThrowArchiveException; CArchive::GetFile; CArchive::IsStoring; CBrush::CreateSolidBrush; CCmdUI::Enable; CDC::DPtoLP; CDC::FillRect; CDC::GetClipBox; CDC::GetDeviceCaps; CDC::GetTextMetrics; CDC::IntersectClipRect; CDC::IsPrinting; CDC::LPtoDP; CDC::SetBkColor; CDC::SetTextColor; CDC::SetViewportOrg; CDC::TextOut; CDialog::DoModal; CDocTemplate::InitialUpdateFrame; CDocument::DeleteContents; CDocument::GetFirstViewPosition; CDocument::GetNextView; CDocument::OnOpenDocument; CDocument::OnSaveDocument; CDocument::SaveModified; CDocument::UpdateAllViews; CFile::Close; CFile::GetStatus; CFile::Open; CFile::Read; CFile::Seek; CFile::Write; CFrameWnd::ActivateFrame; CFrameWnd::Create; CFrameWnd::GetActiveDocument; CFrameWnd::LoadFrame; CMDIChildWnd::GetMDIFrame; CMDIFrameWnd::MDIGetActive; CMDIFrameWnd::MDITile; CObject::IsKindOf; CObject::Serialize; CPrintInfo::SetMaxPage; CRect::Height; CScrollView::SetScrollSizes; CString::Format; CString::GetBufferSetLength; CString::GetLength; CString::IsEmpty; CString::LoadString; CView::DoPreparePrinting; CView::GetDocument; CView::OnBeginPrinting; CView::OnDraw; CView::OnInitialUpdate; CView::OnPrepareDC; CView::OnPreparePrinting; CView::OnPrint; CView::OnUpdate; CWinApp::AddDocTemplate; CWinApp::Enable3dControls; CWinApp::GetProfileString; CWinApp::InitInstance; CWinApp::LoadStdProfileSettings; CWinApp::OnFileNew; CWinApp::OpenDocumentFile; CWinApp::WriteProfileString; CWnd::DoDataExchange; CWnd::GetClientRect; CWnd::GetDlgItem; CWnd::GetParentFrame; CWnd::GetScrollBarCtrl; CWnd::Invalidate; CWnd::InvalidateRect; CWnd::OnCreate; CWnd::OnKeyDown; CWnd::OnLButtonDown; CWnd::OnSize; CWnd::OnVScroll; CWnd::PreCreateWindow; CWnd::SetWindowText; CWnd::ShowWindow; CWnd::UpdateData; CWnd::UpdateWindow; GetFileTitle; GetSysColor; GetWindowText; LOWORD; LoadBitmap; MAKELONG; SetWindowText; free; malloc; max; min; wsprintf