home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / advanced / chkbook / checkdoc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  8.1 KB  |  312 lines

  1. // checkdoc.cpp : implementation of the CChkBookDoc class
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13.  
  14. #include "stdafx.h"
  15. #include "chkbook.h"
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char BASED_CODE THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. #define FIRST_CHECK_NO 101
  23. #define CHECK_BOOK_FILE_SIGNATURE 0xd6f7e471
  24.  
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CChkBookDoc
  27. //
  28.  
  29. IMPLEMENT_DYNCREATE(CChkBookDoc, CFixedLenRecDoc)
  30.  
  31. BEGIN_MESSAGE_MAP(CChkBookDoc, CFixedLenRecDoc)
  32.     //{{AFX_MSG_MAP(CChkBookDoc)
  33.     ON_COMMAND(ID_EDIT_NEW_CHECK, NewCheck)
  34.     ON_COMMAND(ID_NEXT_CHECK, OnNextCheck)
  35.     ON_UPDATE_COMMAND_UI(ID_NEXT_CHECK, OnUpdateNextCheck)
  36.     ON_COMMAND(ID_PREV_CHECK, OnPrevCheck)
  37.     ON_UPDATE_COMMAND_UI(ID_PREV_CHECK, OnUpdatePrevCheck)
  38.     //}}AFX_MSG_MAP
  39. END_MESSAGE_MAP()
  40.  
  41. /////////////////////////////////////////////////////////////////////////////
  42. // CChkBookDoc construction/destruction
  43.  
  44. CChkBookDoc::CChkBookDoc()
  45. {
  46.     m_header.nRecordLength = sizeof(m_record);
  47.     m_header.nExtraHeaderLength = sizeof(m_extraHeader);
  48.     m_header.nRecordCount = 0;
  49.     m_nActiveRecord = 0;
  50.     m_extraHeader.nFirstCheckNo = FIRST_CHECK_NO;
  51.     m_extraHeader.dwFileSignature = CHECK_BOOK_FILE_SIGNATURE;
  52. #ifdef _UNICODE
  53.     m_extraHeader.bUnicode = TRUE;
  54. #else
  55.     m_extraHeader.bUnicode = FALSE;
  56. #endif
  57. }
  58.  
  59. CChkBookDoc::~CChkBookDoc()
  60. {
  61. }
  62.  
  63. /////////////////////////////////////////////////////////////////////////////
  64. // Overrides of CFixedLenRecDoc and CDocument
  65.  
  66. BOOL CChkBookDoc::OnOpenDocument(LPCTSTR lpszPathName)
  67. {
  68.     // Upon opening the document, tell the application object
  69.     // to save the path name in the private INI file.
  70.  
  71.     if (!CFixedLenRecDoc::OnOpenDocument(lpszPathName))
  72.         return FALSE;
  73.     UpdateIniFileWithDocPath(lpszPathName);
  74.     m_nActiveRecord = 0;
  75.     return TRUE;
  76. }
  77.  
  78. BOOL CChkBookDoc::OnSaveDocument(LPCTSTR lpszPathName)
  79. {
  80.     // Upon saving the document, tell the application object
  81.     // to save the path name in the private INI file.
  82.  
  83.     if (!CFixedLenRecDoc::OnSaveDocument(lpszPathName))
  84.         return FALSE;
  85.     UpdateIniFileWithDocPath(lpszPathName);
  86.     return TRUE;
  87. }
  88.  
  89. BOOL CChkBookDoc::SaveModified()
  90. {
  91.     // If the user has been editing a check in the check view
  92.     // but hasn't commited it yet, ask her whether she wants to
  93.     // commit the check.  She might response with 'Cancel', in
  94.     // which case MaybeCommitDirtyCheck() returns FALSE, which
  95.     // SaveModified() in turn returns to cancel the File Close.
  96.  
  97.     return MaybeCommitDirtyCheck();
  98. }
  99.  
  100. void CChkBookDoc::UpdateIniFileWithDocPath(LPCTSTR lpszPathName)
  101. {
  102.     theApp.UpdateIniFileWithDocPath(lpszPathName);
  103. }
  104.  
  105. void* CChkBookDoc::OnCreateNewRecord(int nNewRecordIndex)
  106. {
  107.     // The base class CFixedLenRecDoc calls this override to
  108.     // format a new record (in memory).
  109.  
  110.     DWORD dwCents = 0L;
  111.     TCHAR date[9];
  112.     _tstrdate(date);
  113.     CString strDate(date);
  114.     CString strPayTo;
  115.     CString strMemo;
  116.     PackRecord(dwCents, strPayTo, strDate, strMemo);
  117.     m_nActiveRecord = nNewRecordIndex;
  118.     return &m_record;
  119. }
  120.  
  121. BOOL CChkBookDoc::OnReadExtraHeader(CFile* pFile)
  122. {
  123.     // Read the ChkBook-specific portion of the file header,
  124.     // and verify the file signature to make sure we're not
  125.     // reading a non-ChkBook file.
  126.  
  127.     if (pFile->Read(&m_extraHeader, sizeof(m_extraHeader))
  128.         < sizeof(m_extraHeader))
  129.         return FALSE;
  130. #ifdef _UNICODE
  131.     if (!m_extraHeader.bUnicode)
  132.     {
  133.         AfxMessageBox(IDS_CANNOT_READ_UNICODE_FILE);
  134.         return FALSE;
  135.     }
  136. #else
  137.     if (m_extraHeader.bUnicode)
  138.     {
  139.         AfxMessageBox(IDS_CANNOT_READ_ANSI_FILE);
  140.         return FALSE;
  141.     }
  142. #endif
  143.     return (m_extraHeader.dwFileSignature == CHECK_BOOK_FILE_SIGNATURE);
  144. }
  145.  
  146. void CChkBookDoc::OnWriteExtraHeader(CFile* pFile, BOOL bNewHeader)
  147. {
  148.     pFile->Write(&m_extraHeader, sizeof(m_extraHeader));
  149.  
  150.     // If this is a new header (that is, if the first is first being
  151.     // created), then create the first record.
  152.  
  153.     if (bNewHeader)
  154.     {
  155.         ASSERT(pFile == &m_file);
  156.         CreateNewRecord();
  157.     }
  158. }
  159.  
  160. /////////////////////////////////////////////////////////////////////////////
  161. // Operations, called by book view and check view
  162.  
  163. void CChkBookDoc::GetCheck(UINT nCheckNo, DWORD& dwCents, CString& strPayTo,
  164.         CString& strDate, CString& strMemo)
  165. {
  166.     UINT nRecord = CheckNoToRecordIndex(nCheckNo);
  167.     GetRecord(nRecord, &m_record);
  168.     ParseRecord(dwCents, strPayTo, strDate, strMemo);
  169. }
  170.  
  171.  
  172. void CChkBookDoc::UpdateCheck(CView* pSourceView, UINT nCheckNo,
  173.         DWORD dwCents, LPCTSTR lpszPayTo, LPCTSTR lpszDate,
  174.         LPCTSTR lpszMemo)
  175. {
  176.     UINT nRecord = CheckNoToRecordIndex(nCheckNo);
  177.     PackRecord(dwCents, lpszPayTo, lpszDate, lpszMemo);
  178.     UpdateRecord(pSourceView, nRecord, &m_record);
  179.     ASSERT_VALID(GetDocTemplate());
  180. }
  181.  
  182.  
  183. void CChkBookDoc::ChangeSelectionNextCheckNo(BOOL bNext)
  184. {
  185.     if (bNext)
  186.     {
  187.         if (m_nActiveRecord < (GetRecordCount() - 1))
  188.         {
  189.             if (!MaybeCommitDirtyCheck())
  190.                 return;
  191.             UpdateAllViewsWithRecord(NULL, ++m_nActiveRecord);
  192.         }
  193.     }
  194.     else
  195.     {
  196.         if (m_nActiveRecord > 0)
  197.         {
  198.             if (!MaybeCommitDirtyCheck())
  199.                 return;
  200.             UpdateAllViewsWithRecord(NULL, --m_nActiveRecord);
  201.         }
  202.     }
  203. }
  204.  
  205. void CChkBookDoc::ChangeSelectionToCheckNo(UINT nNewActiveCheckNo)
  206. {
  207.     if (!MaybeCommitDirtyCheck())
  208.         return;
  209.     m_nActiveRecord = CheckNoToRecordIndex(nNewActiveCheckNo);
  210.     UpdateAllViewsWithRecord(NULL, m_nActiveRecord);
  211. }
  212.  
  213. BOOL CChkBookDoc::MaybeCommitDirtyCheck()
  214. {
  215.     CView* pView;
  216.     POSITION pos = GetFirstViewPosition();
  217.     while (pos != NULL)
  218.     {
  219.         pView = GetNextView(pos);
  220.         CCheckView* pCheckView = DYNAMIC_DOWNCAST(CCheckView, pView);
  221.         if (pCheckView != NULL)
  222.             return pCheckView->MaybeCommitDirtyCheck();
  223.     }
  224.     return TRUE;
  225. }
  226.  
  227. /////////////////////////////////////////////////////////////////////////////
  228. // Implementation
  229.  
  230. void CChkBookDoc::PackRecord(DWORD dwCents, LPCTSTR lpszPayTo,
  231.             LPCTSTR lpszDate, LPCTSTR lpszMemo)
  232. {
  233.     m_record.dwCents = dwCents;
  234.     _tcsncpy(m_record.szPayTo, lpszPayTo, sizeof(m_record.szPayTo)/sizeof(TCHAR) - 1);
  235.     m_record.szPayTo[sizeof(m_record.szPayTo)/sizeof(TCHAR) - 1] = 0;
  236.     _tcsncpy(m_record.szDate, lpszDate, sizeof(m_record.szDate)/sizeof(TCHAR) - 1);
  237.     m_record.szDate[sizeof(m_record.szDate)/sizeof(TCHAR) - 1] = 0;
  238.     _tcsncpy(m_record.szMemo, lpszMemo, sizeof(m_record.szMemo)/sizeof(TCHAR) - 1);
  239.     m_record.szMemo[sizeof(m_record.szMemo)/sizeof(TCHAR) - 1] = 0;
  240.  
  241. }
  242.  
  243. void CChkBookDoc::ParseRecord(DWORD& dwCents, CString& strPayTo,
  244.             CString& strDate, CString& strMemo)
  245. {
  246.     dwCents = m_record.dwCents;
  247.     strPayTo = m_record.szPayTo;
  248.     strDate = m_record.szDate;
  249.     strMemo = m_record.szMemo;
  250. }
  251.  
  252. UINT CChkBookDoc::CheckNoToRecordIndex(UINT nCheckNo)
  253. {
  254.     return (nCheckNo - m_extraHeader.nFirstCheckNo);
  255. }
  256.  
  257. UINT CChkBookDoc::RecordIndexToCheckNo(UINT nRecordIndex)
  258. {
  259.     return (nRecordIndex + m_extraHeader.nFirstCheckNo);
  260. }
  261.  
  262. UINT CChkBookDoc::GetActiveCheckNo()
  263. {
  264.     return (m_nActiveRecord + m_extraHeader.nFirstCheckNo);
  265. }
  266.  
  267. UINT CChkBookDoc::GetFirstCheckNo()
  268. {
  269.     return m_extraHeader.nFirstCheckNo;
  270. }
  271.  
  272. UINT CChkBookDoc::GetLastCheckNo()
  273. {
  274.     return (m_extraHeader.nFirstCheckNo + GetRecordCount() - 1);
  275. }
  276.  
  277. /////////////////////////////////////////////////////////////////////////////
  278. // CChkBookDoc commands
  279.  
  280. void CChkBookDoc::NewCheck()
  281. {
  282.     // Before creating a new record, which will become the new selection,
  283.     // ask the user whether she wants to commit data entered in the
  284.     // check view for the previously selected check.
  285.  
  286.     if (!MaybeCommitDirtyCheck())
  287.         return;
  288.  
  289.     m_nActiveRecord = CreateNewRecord();
  290. }
  291.  
  292. void CChkBookDoc::OnNextCheck()
  293. {
  294.     ChangeSelectionNextCheckNo(TRUE);
  295. }
  296.  
  297. void CChkBookDoc::OnUpdateNextCheck(CCmdUI* pCmdUI)
  298. {
  299.     pCmdUI->Enable(m_nActiveRecord < (GetRecordCount() - 1));
  300. }
  301.  
  302. void CChkBookDoc::OnPrevCheck()
  303. {
  304.     ChangeSelectionNextCheckNo(FALSE);
  305. }
  306.  
  307. void CChkBookDoc::OnUpdatePrevCheck(CCmdUI* pCmdUI)
  308. {
  309.     pCmdUI->Enable(m_nActiveRecord > 0);
  310.  
  311. }
  312.