home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK11 / MFC / SAMPLES / TUTORIAL / CMDBOOK.CP$ / cmdbook
Encoding:
Text File  |  1992-01-10  |  9.1 KB  |  393 lines

  1. // cmdbook.cpp : A character interface to the CPerson Databaes
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992 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 Microsoft
  9. // QuickHelp documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include <iostream.h>
  14. #include <afx.h>
  15. #include <afxcoll.h>
  16.  
  17. // Define the database class to handle all the transactions for us
  18. #include "database.h"
  19.  
  20. #define INPUTSIZE 80
  21.  
  22. // This viewer can only handle on database at a time so we declare it
  23. // globally to simplify the code
  24. CDataBase db;
  25.  
  26. // Command Function prototypes
  27. BOOL OnNew();
  28. BOOL OnOpen();
  29. BOOL OnAdd();
  30. BOOL OnEnd();
  31. BOOL OnHelp();
  32. BOOL OnFind();
  33. BOOL OnList();
  34. BOOL OnSave();
  35. BOOL OnQuit();
  36. BOOL OnWrite();
  37.  
  38. // Helper Function prototypes
  39. BOOL CheckFile();
  40. BOOL Save( BOOL bNamed = FALSE );
  41.  
  42. struct commandmap
  43. {
  44.     char* verb;
  45.     char* description;
  46.     BOOL (*cmd)();
  47. };
  48.  
  49. // A static array that contains the the commandmap structure.  There is
  50. // one structure per command.  Each structure contains the text of the
  51. // command, the help text for that command, and the address of the function
  52. // that performs that command.
  53. //
  54. static commandmap commands[] =
  55. {
  56.     { "help",  "displays this text",                              OnHelp },
  57.     { "new",   "creates a new database for entry",                OnNew },
  58.     { "open",  "opens a file on the disk",                        OnOpen },
  59.     { "quit",  "leaves the program without saving the book file", OnQuit },
  60.     { "add",   "adds a new person to the book file",              OnAdd },
  61.     { "end",   "saves the book file and leaves the program",      OnEnd },
  62.     { "find",  "finds all people with a given last name",         OnFind },
  63.     { "list",  "lists the people in the book file",               OnList },
  64.     { "save",  "saves the book file",                             OnSave },
  65.     { "write", "saves the book file to a new filename",           OnWrite },
  66.     { NULL  ,   "matches any verb and displays help",             OnHelp }
  67. };
  68.  
  69. /////////////////////////////////////////////////////////////////////////////
  70. //  The command functions
  71.  
  72. //////////////////////////////////////////////////
  73. //  OnNew
  74. //  Checks to see if the current list should be saved and then
  75. //  allocations a new list.
  76. //
  77. BOOL OnNew()
  78. {
  79.     if ( CheckFile() )
  80.         db.New();
  81.     
  82.     return TRUE;
  83. }
  84.  
  85. //////////////////////////////////////////////////
  86. //  OnOpen
  87. //  Checks to see if the current list should be saved and then
  88. //  open a new file using the filename provided by the user.
  89. //
  90. BOOL OnOpen()
  91. {
  92.     if ( CheckFile() )
  93.     {
  94.         CString bookfile;
  95.     
  96.         cout << "book file: ";
  97.         cin >> bookfile.GetBuffer( INPUTSIZE ); bookfile.ReleaseBuffer();
  98.     
  99.         TRY
  100.         {
  101.             db.DoOpen( bookfile );
  102.         }
  103.         CATCH( CFileException, e )
  104.         {
  105.             cout << "Not able to open " << bookfile << " as a database\n";
  106.         }
  107.         AND_CATCH( CArchiveException, e )
  108.         {
  109.             cout << "Not able to open " << bookfile << " as a database\n";
  110.         }
  111.         END_CATCH
  112.     
  113.         return OnList();
  114.     }
  115.     else
  116.         return TRUE;
  117. }
  118.  
  119. //////////////////////////////////////////////////
  120. //  OnAdd
  121. //  Add a person into the current list.
  122. //
  123. BOOL OnAdd()
  124. {
  125.     if ( !db.IsPresent() )
  126.     {
  127.         cout << "There is no current database to add to.\n";
  128.         return FALSE;
  129.     }
  130.     
  131.     CPerson* p = new CPerson();
  132.     CString input;
  133.  
  134.     cout << "last name:";
  135.     cin >> input.GetBuffer( INPUTSIZE ); input.ReleaseBuffer();
  136.     p->SetLastName( input );
  137.  
  138.     cout << "first name:";
  139.     cin >> input.GetBuffer( INPUTSIZE ); input.ReleaseBuffer();
  140.     p->SetFirstName( input );
  141.  
  142.     cout << "phone number (no spaces):";
  143.     cin >> input.GetBuffer( INPUTSIZE ); input.ReleaseBuffer();
  144.     p->SetPhoneNumber( input );
  145.  
  146.     db.AddPerson( p );
  147.  
  148.     return TRUE;
  149. }
  150.  
  151. //////////////////////////////////////////////////
  152. //  OnEnd
  153. //  End the program saving the file.
  154. //
  155. BOOL OnEnd()
  156. {
  157.     if ( db.IsDirty() )
  158.         if ( !Save( db.IsNamed() ) )
  159.         {
  160.             cout << "An error occurred while saving file!  Abort Program[y/n]?";
  161.             CString answer;
  162.             cin >> answer.GetBuffer( INPUTSIZE );
  163.             answer.ReleaseBuffer();
  164.             answer.MakeUpper();
  165.             if ( answer[0] == 'N' )
  166.                 return TRUE;
  167.         }
  168.     
  169.     return FALSE;
  170. }
  171.  
  172. //////////////////////////////////////////////////
  173. //  OnFind
  174. //  Gets filter text from the user and then lists all the
  175. //  CPerson objects that match that filter.  Note that after
  176. //  it calls OnList it calls DoFind with no input clearing the
  177. //  stored find list.
  178. //
  179. BOOL OnFind()
  180. {
  181.     if ( !db.IsPresent() )
  182.     {
  183.         cout << "There is no current database to search.\n";
  184.         return FALSE;
  185.     }
  186.     
  187.     CString lastname;
  188.  
  189.     cout << "find last name: ";
  190.     cin >> lastname.GetBuffer( INPUTSIZE ); lastname.ReleaseBuffer();
  191.  
  192.     db.DoFind( lastname );
  193.     OnList();
  194.     db.DoFind();
  195.  
  196.     return TRUE;
  197. }
  198.  
  199. //////////////////////////////////////////////////
  200. //  OnHelp
  201. //  Displays the text for all the command verbs followed by
  202. //  their help strings.
  203. //
  204. BOOL OnHelp()
  205. {
  206.     commandmap* cmd;
  207.  
  208.     cout << "available commands are:\n";
  209.  
  210.     for ( cmd = commands; cmd->verb != NULL; cmd++ )
  211.         cout << "\t" << cmd->verb << "\t" << cmd->description << "\n";
  212.  
  213.     return TRUE;
  214. }
  215.  
  216. //////////////////////////////////////////////////
  217. //  OnList
  218. //  Iterates over the list writing each CPerson object out
  219. //  to cout.
  220. //
  221. BOOL OnList()
  222. {
  223.  
  224.     if ( !db.IsPresent() )
  225.     {
  226.         cout << "There is no current database to list.\n";
  227.     }
  228.     else
  229.     {
  230.         CPerson* pCurrent;
  231.         
  232.         cout << "  List contains:\n";
  233.         for ( int i = 0; i < db.GetCount(); i++ )
  234.         {
  235.             pCurrent = db.GetPerson( i );
  236.             cout << '\t' << pCurrent->GetLastName() << ", " <<
  237.                     pCurrent->GetFirstName() << '\t' <<
  238.                     pCurrent->GetPhoneNumber() << '\n';
  239.         }
  240.     }
  241.     return TRUE;
  242. }
  243.  
  244. //////////////////////////////////////////////////
  245. //  OnSave
  246. //  Saves the database with the current name.  If there is no
  247. //  current name then the user will be prompted for one.
  248. //
  249. BOOL OnSave()
  250. {
  251.     if ( !Save( db.IsNamed() ) )
  252.     {
  253.         cout << "An error occurred while saving file!  Abort Program[y/n]?";
  254.         CString answer;
  255.         cin >> answer.GetBuffer( INPUTSIZE );
  256.         answer.ReleaseBuffer();
  257.         answer.MakeUpper();
  258.         if ( answer[0] == 'Y' )
  259.             return FALSE;
  260.     }
  261.     
  262.     return TRUE;
  263. }
  264.  
  265. //////////////////////////////////////////////////
  266. //  OnQuit
  267. //  Quits the program without saving changes to the database.
  268. //
  269. BOOL OnQuit()
  270. {
  271.     return FALSE;
  272. }
  273.  
  274. //////////////////////////////////////////////////
  275. //  OnWrite
  276. //  Gets a filename from the user and writes the database
  277. //  to the file.
  278. //
  279. BOOL OnWrite()
  280. {
  281.     if ( !Save() )
  282.     {
  283.         cout << "An error occurred while saving file!  Abort Program[y/n]?";
  284.         CString answer;
  285.         cin >> answer.GetBuffer( INPUTSIZE );
  286.         answer.ReleaseBuffer();
  287.         answer.MakeUpper();
  288.         if ( answer[0] == 'Y' )
  289.             return FALSE;
  290.     }
  291.     
  292.     return TRUE;
  293. }
  294.  
  295. //////////////////////////////////////////////////
  296. //  CheckFile
  297. //  Determines if there currently is a database that needs
  298. //  to be saved.  If so it calls Save.
  299. //
  300. BOOL CheckFile()
  301. {
  302.     if ( db.IsDirty() )
  303.     {
  304.         CString answer;
  305.         cout << "Save File[ync] " << db.GetName();
  306.         cin >> answer.GetBuffer( INPUTSIZE );
  307.         answer.ReleaseBuffer();
  308.         answer.MakeUpper();
  309.         if ( answer[0] == 'Y' )
  310.         {
  311.             if ( !Save( db.IsNamed() ) )
  312.                 return FALSE;
  313.         }
  314.         else if ( answer[0] == 'C' )
  315.             return FALSE;
  316.     }
  317.     return TRUE;
  318. }
  319.  
  320. //////////////////////////////////////////////////
  321. //  Save
  322. //  If provided with a name it saves the database to that file
  323. //  otherwise it prompts the user for a name to save to.
  324. //
  325. BOOL Save( BOOL bNamed /* = FALSE */ )
  326. {
  327.     if ( !db.IsPresent() )
  328.     {
  329.         cout << "But you don't have a database to save.\n";
  330.         return FALSE;
  331.     }
  332.     TRY
  333.     {
  334.         if ( bNamed )
  335.             db.DoSave();
  336.         else
  337.         {
  338.             CString strFileName;
  339.             cout << "write to file: ";
  340.             cin >> strFileName.GetBuffer( INPUTSIZE );
  341.             strFileName.ReleaseBuffer();
  342.             db.DoSave( strFileName );
  343.         }
  344.     }
  345.     CATCH( CFileException, e )
  346.     {
  347.         cout << "File Save Error ->" << e->m_lOsError << " while saving "
  348.                 << db.GetName() << '\n';
  349.         return FALSE;
  350.     }
  351.     AND_CATCH( CArchiveException, e )
  352.     {
  353.         cout << "Archive Write while saving " << db.GetName() << '\n';
  354.         return FALSE;
  355.     }
  356.     END_CATCH
  357.     return TRUE;
  358. }
  359.  
  360.  
  361. /////////////////////////////////////////////////////////////////////////////
  362. //  main
  363. //  Loops until the global bLeave is set to TRUE.  It processes commands
  364. //  by iterating through the list until either the text matches or the
  365. //  the end of the command list is hit.  If a match is found the the
  366. //  command function is called otherwise an error is displayed and
  367. //  OnHelp is called.
  368. //
  369. void main()
  370. {
  371.     commandmap* finder;
  372.     CString strVerb;
  373.  
  374.     do
  375.     {
  376.         cout << db.GetName() << " - command: ";
  377.         cin >> strVerb.GetBuffer( INPUTSIZE );
  378.         strVerb.ReleaseBuffer();
  379.  
  380.         finder = commands;
  381.         while (finder->verb != NULL && finder->verb != strVerb )
  382.             finder++;
  383.  
  384.         if ( finder->verb == NULL )
  385.             cout << "command \"" << strVerb << "\" is not known.\n";
  386.  
  387.     } while ( (*finder).cmd() );
  388.  
  389.     db.Terminate();
  390.  
  391.     return;
  392. }
  393.