home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_GEN / TVCOLR.ZIP / DEMO.CPP < prev    next >
C/C++ Source or Header  |  1994-02-08  |  36KB  |  1,071 lines

  1. // File    : DEMO.CPP
  2. // Author  : Eric Woodruff,  CIS ID: 72134,1150
  3. // Updated : Tue 02/08/94 10:27:28
  4. // Note    : Hereby declared public domain
  5. // Compiler: Borland C++ 3.1/4.0
  6. //
  7. // This program demonstrates the changes described in the TVCOLR.DOC and
  8. // COLUPDT.DOC files.
  9. //
  10. // Note:  Compiling this program before making the described changes
  11. // will generate an executable equivalent to DEMOUMOD.EXE.  Compiling this
  12. // program after making the changes will generate an executable equivalent
  13. // to DEMOMOD.EXE.
  14. //
  15. // Included is my standard front end.  It will also serve as a fairly good
  16. // tutorial on selecting color palettes from the command line as well as
  17. // saving and restoring colors to a configuration file.
  18. //
  19. // You may use any of the following command line parameters:
  20. //
  21. //     /MC | /MB | /MM | /MA    -  Select color, black & white, monochrome,
  22. //                                 or alternate color palette.  If not
  23. //                                 specified, it defaults to the palette
  24. //                                 best suited for the monitor in use.
  25. //
  26. //     /Cdr:\path\filename.ext  -  Specify different default config filename.
  27. //
  28. //     /Rdr:\path\filename.ext  -  Specify different resource filename.
  29. //
  30. // This program uses a resource file for some of the objects like the menu
  31. // bar, status line, color dialog box, etc.  If you use this code elsewhere
  32. // without a resource file, you can generally replace the rsc->get() calls
  33. // with calls to the functions from BLDRSC.CPP that create the objects.  Just
  34. // include those functions in here or in a separate module and remove all
  35. // references to the resource file.
  36. //
  37.  
  38. #define FINAL            // Uncomment this line to allow searching the
  39.                          // the end of the executable for the resource file.
  40.  
  41. #include <conio.h>
  42. #include <ctype.h>
  43. #include <dir.h>
  44. #include <dos.h>
  45. #include <float.h>
  46. #include <io.h>
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include <string.h>
  50.  
  51. //extern unsigned _stklen = 10240U;
  52.  
  53. #define Uses_MsgBox
  54. #define Uses_TApplication
  55. #define Uses_TColorDialog
  56. #define Uses_TDeskTop
  57. #define Uses_TDialog
  58. #define Uses_TEvent
  59. #define Uses_TFileDialog
  60. #define Uses_TMenuBar
  61. #define Uses_TMenuItem
  62. #define Uses_TPalette
  63. #define Uses_TResourceFile
  64. #define Uses_TScreen
  65. #define Uses_TScrollBar
  66. #define Uses_TStaticText
  67. #define Uses_TStatusDef
  68. #define Uses_TStatusItem
  69. #define Uses_TStatusLine
  70. #define Uses_TSubMenu
  71. #define Uses_TWindow
  72. //#define Uses_TVCOLR         // Use this if you modified the TV.H file.
  73. #define Uses_fpstream
  74. #include <tv.h>
  75.  
  76. #if !defined(cpDefSize)
  77. // Use this if you chose not to modify the Turbo Vision files.
  78. #include "tvcolr.h"
  79. #endif
  80.  
  81. //#include <heapview.h>
  82.  
  83. // ****************************************************************************
  84. // Headers not in the standard front end file.
  85.  
  86. #include <tcoltxt.h>           // TColorText header file.
  87.  
  88. #define Uses_DemoApp
  89. #include "demo.h"              // Demo program header file.
  90.  
  91. // ****************************************************************************
  92.  
  93. #include "link.h"           // Resource file link definitions.
  94.  
  95. //extern int    _Cdecl _argc;  // Global pointers to the command line args.
  96. //extern char **_Cdecl _argv;  // This way the app's constructor can access
  97.                                // them.  Declarations are in DOS.H too.
  98.  
  99. extern TPoint shadowSize;   // Altered when screen size changes.
  100.  
  101. char demo_cfg[MAXPATH],     // Configuration filename.
  102.      demo_rsc[MAXPATH];     // Resource filename.
  103.  
  104. // Resource file pointers.
  105. fpstream *s;
  106. TResourceFile *rsc = NULL;  // NULL to start with.
  107.  
  108. // The value of this variable determines what is printed when the program
  109. // exits back to DOS.
  110. short ExitValue = EXIT_NOERR;
  111.  
  112. // Monitor type palette index as set from the command line (/MC | /MB | /MM |
  113. // /MA).  By default it is -1 to let the application use the default palette
  114. // selected by TProgram::initScreen().
  115. short CmdLinePalette = -1;
  116.  
  117. // Global pointer to the user screen buffer for the User Screen event.
  118. char *ScrBuf = NULL;
  119.  
  120. // ****************************************************************************
  121. // Global variables not in the standard front end file.
  122.  
  123. //  NONE
  124.  
  125. //*****************************************************************************
  126. // Standard functions.  Modify as needed.
  127.  
  128. void exitfunc(void)
  129. {
  130.     switch(ExitValue)
  131.     {
  132.         case EXIT_NOERR:
  133.             cout << endl << "Thank you for using this demo program." << endl;
  134.             break;
  135.  
  136.         case EXIT_RSCERR:
  137.             cout << "Could not locate or open resource file: " <<
  138.                 demo_rsc << endl;
  139.             break;
  140.  
  141.         case EXIT_SWERR:
  142.             cout << "Bad parameter: " << _argv[_argc] << endl << endl;
  143.             // Fall through and display command line syntax.
  144.  
  145.         case EXIT_SYNTAX:
  146.             cout << "Command line syntax:" << endl << _argv[0] <<
  147.                 " [/MC | /MB | /MC /MA] [/Rrsc_file.ext] [/Ccfg_file.ext]" <<
  148.                 endl;
  149.             break;
  150.     }
  151. }
  152.  
  153. // Tell the exit code to call the display function just prior to quiting.
  154. #pragma exit exitfunc 31
  155.  
  156. //
  157. // This will kick everything off.  Note that no argc, or argv parameters are
  158. // used.  The global _argc and _argv variables are used instead so that we
  159. // don't have to pass them to the constructor.  You don't need to do things
  160. // this way, it's just one alternative.
  161. //
  162. void main(void)
  163. {
  164.     short index = 1;
  165.  
  166.     // To begin with, assume that the resource file is appended to the
  167.     // executable.  If it isn't, we'll try a different approach.
  168.     // To append the resource file to the executable you would issue the
  169.     // command:
  170.     //          COPY /B filename1.EXE+filename.RSC filename2.EXE
  171.     //
  172.     // Make sure the destination .EXE name is not the same as the source
  173.     // .EXE name or you will overwrite the source .EXE file.
  174.     // Also note that the source .EXE can't have debug info at the end of it.
  175.     //
  176.     strcpy(demo_rsc, _argv[0]);
  177.  
  178. // Until the final production version, don't bother trying to access the
  179. // executable.  Debugging from within the IDE will cause a general access
  180. // failure on the drive when it tries to open it.  TResourceFile won't
  181. // read past the debug info at the end of the executable anyway so use a
  182. // separate resource file until debugging is all done.
  183. #ifndef FINAL
  184.     strcpy(strchr(demo_rsc, '.') + 1, "RSC");
  185. #endif
  186.  
  187.     // Modify executable name to get location and name of the default
  188.     // configuration file.  We'll assume the config file (if any) is in the
  189.     // same directory as the executable and has the same name with a .CFG
  190.     // extension.  It can be changed with a /C command line switch to
  191.     // specify a different path to it or a different name.
  192.  
  193.     strcpy(demo_cfg, _argv[0]);
  194.     strcpy(strchr(demo_cfg, '.') + 1, "CFG");
  195.  
  196.     // Look for command line switches affecting configuration and resource
  197.     // files.  A check for a user requested palette is also included here.
  198.     // That way everything will come up in the proper colors when
  199.     // setScreenMode() is called in the application's constructor or in
  200.     // the loadConfig() function.
  201.     //
  202.     // I've found it best to scan for and process these items here because
  203.     // I do have some cases where the command line arguments are processed
  204.     // in the application's constructor to insert some default objects into
  205.     // the desktop such as file or directory viewers, editor windows, etc
  206.     // specified with other command line switches.  If there is an error
  207.     // doing one of them, you need the screen active so that you can see
  208.     // the error message box.  Also, you don't have to do anything special
  209.     // in the application's constructor to switch palettes if one of these
  210.     // is found.
  211.     //
  212.     while(index != _argc)
  213.     {
  214.         // Allow -opt or /opt.
  215.         if(_argv[index][0] == '/' || _argv[index][0] == '-')
  216.             switch(toupper(_argv[index][1]))
  217.             {
  218.                 case 'M':       // Change the default palette.
  219.                     switch(toupper(_argv[index][2]))
  220.                     {
  221.                         case 'C':
  222.                             CmdLinePalette = apColor;
  223.                             break;
  224.  
  225.                         case 'B':
  226.                             CmdLinePalette = apBlackWhite;
  227.                             break;
  228.  
  229.                         case 'M':
  230.                             CmdLinePalette = apMonochrome;
  231.                             break;
  232.  
  233.                         case 'A':
  234.                             CmdLinePalette = apAltColor;
  235.                             break;
  236.  
  237.                         default:
  238.                             ExitValue = EXIT_SWERR;  // Signal bad switch value.
  239.                             _argc = index;
  240.                             exit(EXIT_SWERR);
  241.                             break;
  242.                     }
  243.                     break;
  244.  
  245.                 case 'C':           // Use a different configuration filename.
  246.                     strcpy(demo_cfg, &_argv[index][2]);
  247.                     break;
  248.  
  249.                 case 'R':           // Use a different resource filename.
  250.                     strcpy(demo_rsc, &_argv[index][2]);
  251.                     break;
  252.  
  253.                 case '?':
  254.                     ExitValue = EXIT_SYNTAX;    // Display command syntax.
  255.                     exit(EXIT_SYNTAX);
  256.                     break;
  257.  
  258. //                case 'X':         // Ignore other valid switches that
  259. //                case 'Y':         // will be processed in the application's
  260. //                case 'Z':         // constructor.
  261. //                    break;
  262.  
  263.                 default:
  264.                     ExitValue = EXIT_SWERR;  // Signal bad switch value.
  265.                     _argc = index;
  266.                     exit(EXIT_SWERR);
  267.                     break;
  268.             }
  269.  
  270.         index++;
  271.     }
  272.  
  273.     // Now try to open the resource file and use it.
  274.     s = new fpstream(demo_rsc, ios::in | ios::nocreate | ios::binary);
  275.     if(s->good())
  276.     {
  277.         rsc = (TResourceFile *)new TResourceFile(s);
  278.  
  279.         if(!rsc->count())
  280.         {
  281.             TObject::destroy(rsc);      // No resource file in the EXE or
  282.             rsc = NULL;                 // user supplied filename.
  283.         }
  284.     }
  285.     else
  286.         delete s;
  287.  
  288.     if(!rsc)
  289.     {
  290.         // As long as a /R switch wasn't specified, modify the executable name
  291.         // to get the location and name of the default resource file.
  292.         // We'll assume the resource file is in the same directory as the
  293.         // executable and has the same name with a .RSC extension.  It can be
  294.         // changed with a /R command line switch to specify a different path
  295.         // to it or a different name.  If that is the case, it wasn't
  296.         // accessible.
  297.         if(!strnicmp(_argv[0], demo_rsc, strlen(_argv[0]) - 3))
  298.         {
  299.             strcpy(strchr(demo_rsc, '.') + 1, "RSC");
  300.             s = new fpstream(demo_rsc, ios::in | ios::nocreate | ios::binary);
  301.  
  302.             if(!s->good())
  303.                 ExitValue = EXIT_RSCERR;      // Still not accessible.
  304.             else
  305.             {
  306.                 rsc = (TResourceFile *)new TResourceFile(s);
  307.                 if(!rsc->count())
  308.                 {
  309.                     TObject::destroy(rsc);      // Not a valid resource file.
  310.                     ExitValue = EXIT_RSCERR;
  311.                 }
  312.             }
  313.         }
  314.         else
  315.             ExitValue = EXIT_RSCERR;   // User specified file isn't accessible.
  316.  
  317.         if(ExitValue)
  318.             exit(EXIT_RSCERR);
  319.     }
  320.  
  321.     // Application Instance.  Change class name of application as needed.
  322.     TDemoApp Demo;
  323.     Demo.run();
  324.  
  325.     // Shutdown the app and close the resource file.
  326.     Demo.shutDown();
  327.     TObject::destroy(rsc);
  328.  
  329.     if(ScrBuf)
  330.         delete [] ScrBuf;     // Delete User Screen buffer if used.
  331.  
  332.     exit(EXIT_NOERR);
  333. }
  334.  
  335. // ****************************************************************************
  336. // Standard front end functions follow, modify as needed.
  337.  
  338. //
  339. // Constructor for the application.
  340. //
  341. TDemoApp::TDemoApp(void) :
  342.   TProgInit( &TDemoApp::initStatusLine, &TDemoApp::initMenuBar,
  343.     &TDemoApp::initDeskTop )
  344. {
  345.     TRect  r;
  346.     TEvent event;
  347.     short  index = 1,
  348.            Ignored = 0;        // Count of ignored command line parameters.
  349.  
  350.  
  351.     TScreen::checkSnow = False;        // Insure snow checking is off.
  352.  
  353. //    // Create the heap view (optional).
  354. //    r = getExtent();
  355. //    r.a.x = r.b.x - 21;
  356. //    r.b.y = r.a.y + 1;
  357. //    heap = new THeapView( r );
  358. //    insert(heap);
  359.  
  360.     // **********************************************************************
  361.     // Application-specific setup code.
  362.  
  363.     // NONE
  364.  
  365.     // **********************************************************************
  366.     // All the default objects and views have been constructed, now we
  367.     // can do some stuff with the desktop.
  368.  
  369.     // If there is a configuration file, read in the data now.
  370.     // Then, here or in loadConfig, turn on the screen and redraw it.
  371.     // If it is done earlier than this, the proper colors won't be used
  372.     // for the initial screen when an alternate palette is specified.
  373.     if(!access(demo_cfg, 0))
  374.         loadConfig(False);
  375.     else
  376.     {
  377.         setScreenMode(TScreen::screenMode);
  378.  
  379.         if(TMouse::present())       // Adjust mouse limits if present.
  380.             TMouse::setRange(TScreen::screenWidth - 1,
  381.                 TScreen::screenHeight - 1);
  382.     }
  383.  
  384.     // **********************************************************************
  385.  
  386.     // Process any other command line arguments now.
  387.     // Don't forget to ignore any of the one's parsed in main().
  388.     while(index != _argc)
  389.     {
  390.         if(_argv[index][0] == '/' || _argv[index][0] == '-')
  391.         {
  392.             switch(toupper(_argv[index][1]))
  393.             {
  394. //                case 'X':
  395. //                case 'Y':
  396. //                case 'Z':
  397. //                    do something
  398. //                    break;
  399.  
  400.                 case 'C':                  // Ignore config file selection
  401.                 case 'R':                  // Ignore resource file selection.
  402.                 case 'M':                  // Ignore palette selection.
  403.                     Ignored++;             // They're already taken care of.
  404.                     break;
  405.  
  406.                 default:
  407.                     Ignored++;
  408.                     messageBox(mfError | mfOKButton,
  409.                         "Invalid command line switch: %s", _argv[index]);
  410.                     break;
  411.             }
  412.         }
  413.         else  // If not a switch, default to doing something else with it.
  414.         {
  415.             // Ignored by default.
  416.             Ignored++;
  417.             messageBox(mfError | mfOKButton,
  418.                 "Invalid command line parameter: %s", _argv[index]);
  419.         }
  420.  
  421. //      Processing to be done after each switch command (if any).
  422. //      Insert default views, etc.
  423.  
  424.         index++;
  425.     }
  426.  
  427.     // Display the About Box if no command line parameters are passed
  428.     // or only /Mx, /C, or /R parameters were used.
  429.     if(_argc < 2 || (_argc - Ignored) < 2)
  430.     {
  431.         event.what = evCommand;
  432.         event.message.command = cmAbout;
  433.         putEvent(event);
  434.     }
  435. }
  436.  
  437. // This is where the palettes for the application are defined.
  438. TPalette &TDemoApp::getPalette() const
  439. {
  440.     // The Color and Alternate Color attribute maps are swapped in these
  441.     // definitions so that my color preferences are used by default for
  442.     // color monitors.
  443.  
  444.     static TPalette color( cpExtAltColor, sizeof( cpExtAltColor)-1 );
  445.     static TPalette blackwhite( cpExtBlackWhite, sizeof( cpExtBlackWhite)-1 );
  446.     static TPalette monochrome( cpExtMonochrome, sizeof( cpExtMonochrome)-1 );
  447.     static TPalette altcolor( cpExtColor, sizeof( cpExtColor)-1 );
  448.  
  449.     static TPalette *palettes[] =
  450.     {
  451.         &color,
  452.         &blackwhite,
  453.         &monochrome,
  454.         &altcolor        // Additional palettes must come after standard ones
  455.                          // in this array.
  456.     };
  457.     return *(palettes[appPalette]);
  458. }
  459.  
  460. //
  461. // Desktop initialization.
  462. //
  463. TDeskTop *TDemoApp::initDeskTop(TRect r)
  464. {
  465.     // Prevent drawing the desktop until the colors are set correctly.
  466.     TProgram::application->setState(sfExposed, False);
  467.  
  468.     r.a.y++;
  469.     r.b.y--;
  470.     return new TDeskTop(r);
  471. }
  472.  
  473. //
  474. // Screen initialization.  This is overridden so that a command line
  475. // specified color palette can be used.  If not, the default initScreen()
  476. // will reset the palette based on monitor type every time it is called.
  477. //
  478. void TDemoApp::initScreen()
  479. {
  480.     TProgram::initScreen();
  481.  
  482.     // Force palette to equal the user-specified palette.
  483.     if(CmdLinePalette > -1 && TApplication::appPalette != CmdLinePalette)
  484.     {
  485.         TApplication::appPalette = CmdLinePalette;
  486.  
  487.         // If monochrome, turn off shadows and turn on markers.
  488.         if(CmdLinePalette == apMonochrome)
  489.         {
  490.             shadowSize.x = 0;
  491.             shadowSize.y = 0;
  492.             showMarkers = True;
  493.         }
  494.     }
  495. }
  496.  
  497. //
  498. // Menubar initialization.
  499. //
  500. TMenuBar *TDemoApp::initMenuBar(TRect)
  501. {
  502.     return (TMenuBar *)rsc->get("MenuBar");
  503. }
  504.  
  505. //
  506. // Create statusline.
  507. //
  508. TStatusLine *TDemoApp::initStatusLine( TRect )
  509. {
  510.     TStatusLine *statLine = (TStatusLine *)rsc->get("StatusLine");
  511.  
  512.     // If the application starts up in anything other than a screen mode
  513.     // of 25 lines, the status bar will end up in the wrong place.
  514.     if(statLine->origin.y != TScreen::screenHeight - 1)
  515.         statLine->origin.y = TScreen::screenHeight - 1;
  516.  
  517.     return statLine;
  518. }
  519.  
  520. //
  521. // Application idle function.  Modify or remark out as required.
  522. //
  523. void TDemoApp::idle(void)
  524. {
  525.       TProgram::idle();
  526. //    heap->update();
  527. //
  528.     // Turn off Tile and Cascade if other window commands are disabled.
  529.     if(!commandEnabled(cmPrev))
  530.     {
  531.         disableCommand(cmCloseTileable);
  532.         disableCommand(cmTile);
  533.         disableCommand(cmCascade);
  534.     }
  535.     else
  536.     {
  537.         enableCommand(cmCloseTileable);
  538.         enableCommand(cmTile);
  539.         enableCommand(cmCascade);
  540.     }
  541.  
  542.     // Select the menu bar if the desktop is empty.
  543.     if(!deskTop->current && !menuBar->getState(sfSelected))
  544.     {
  545.         TEvent event;
  546.         event.what = evCommand;
  547.         event.message.command = cmMenu;
  548.         putEvent(event);
  549.     }
  550. }
  551.  
  552. //
  553. //  Event handler to distribute the work.
  554. //
  555. void TDemoApp::handleEvent(TEvent &event)
  556. {
  557.     FILE    *palfp;
  558.     TView   *vw;
  559.     TWindow *win;
  560.     TDialog *dlg;
  561.     TDemoHelpWindow *hlp;
  562.     TColorDialog *c;
  563.  
  564.     short    newMode;
  565.  
  566.     TApplication::handleEvent(event);
  567.  
  568.     if(event.what == evCommand)
  569.     {
  570.         switch(event.message.command)
  571.         {
  572.     // Standard front end evCommand events.
  573.  
  574.             case cmAbout:               //  About Dialog Box
  575.                 execDialog((TDialog *)rsc->get("AboutBox"), NULL);
  576.                 break;
  577.  
  578.             case cmRepaint:
  579.                 setScreenMode(TScreen::screenMode);
  580.                 break;
  581.  
  582. //            case cmSaveAll:
  583. //                // Change it from a command to a broadcast event.
  584. //                message(deskTop, evBroadcast, cmSaveAll, NULL);
  585. //                break;
  586. //
  587.             case cmDOSshell:
  588.                 suspend();          // Suspend Turbo Vision and shell to DOS.
  589.                 cout << "Type EXIT to return...";
  590.                 system("");
  591.                 _fpreset();         // Reset math co-processor.
  592.  
  593.                 if(!ScrBuf)
  594.                     ScrBuf = new char[4100];    // At least 4000 bytes.
  595.  
  596.                 gettext(1, 1, 80, 25, ScrBuf);  // Get screen image.
  597.  
  598.                 resume();       // Restart Turbo Vision.
  599.                 redraw();
  600.                 break;
  601.  
  602.             case cmTile:                //  Tile current windows
  603.                 deskTop->tile(deskTop->getExtent());
  604.                 break;
  605.  
  606.             case cmCascade:             //  Cascade current windows
  607.                 deskTop->cascade(deskTop->getExtent());
  608.                 break;
  609.  
  610.             case cmCloseTileable:  // Close all views that have ofTileable set.
  611.                 while((vw = deskTop->firstThat(isTileable, 0)) != NULL)
  612.                     message(vw, evCommand, cmClose, NULL);
  613.                 break;
  614.  
  615.             case cmScreenSize:          // Change screen size.
  616.                 newMode = TScreen::screenMode ^ TDisplay::smFont8x8;
  617.  
  618.                 if(newMode & TDisplay::smFont8x8)
  619.                     shadowSize.x = 1;
  620.                 else
  621.                     shadowSize.x = 2;
  622.  
  623.                 setScreenMode(newMode);
  624.  
  625.                 // Adjust mouse limits if present.
  626.                 if(TMouse::present())
  627.                     TMouse::setRange(TScreen::screenWidth - 1,
  628.                         TScreen::screenHeight - 1);
  629.                 break;
  630.  
  631.             case cmUserScreen:
  632.                 suspend();      // Suspend Turbo Vision and display user
  633.                 if(ScrBuf)      // screen if there is one.
  634.                     puttext(1, 1, 80, 25, ScrBuf);
  635.  
  636.                 getch();        // Wait for keypress and restart Turbo Vision.
  637.                 resume();
  638.                 redraw();
  639.                 break;
  640.  
  641.             case cmColors:
  642. //                c = (TColorDialog *)Colors();
  643.                 c = (TColorDialog *)rsc->get("ColorDlg");
  644.  
  645.                 if(validView(c))
  646.                 {
  647.  
  648. //*     NOTE: I have found that this is the *proper* way to set up *all*
  649. //* TColorDialog boxes.  If you follow the TVDEMO example, you pass
  650. //* TColorDialog a NULL pointer in its constructor (the palette pointer is
  651. //* also NULL after you restore it from a resource file!).
  652. //* You then call its setData() member to initialize the color set.  The
  653. //* problem is that TColorDialog::setData() does a memcpy() using that NULL
  654. //* pointer.  If you trace into the assembler code at that point, you'll see
  655. //* that it takes the address stored in interrupt zero (the Divide by Zero
  656. //* handler) and copies the palette to that address.  Most of the time you
  657. //* don't know anything is wrong, but I have found cases where it crashes
  658. //* immediately or at some point shortly after that.  Even if it doesn't
  659. //* crash, you are still asking for trouble.  The method below is the only
  660. //* way to get a TColorDialog box to work safely and properly when created
  661. //* at runtime or stored in a resource file.
  662.  
  663.                     TPalette x = getPalette();      // Create temporary
  664.                     c->pal = &x;                    // palette and assign it.
  665.                     c->setData(&getPalette());      // Call setData() with
  666.                                                     // the initial colors.
  667.                     // Execute the color dialog box.
  668.                     if(deskTop->execView(c) != cmCancel)
  669.                     {
  670.                         // Do a straight assignment to get the modified colors.
  671.                         getPalette() = *(c->pal);
  672.  
  673.                         // Repaint the entire desktop by calling
  674.                         // setScreenMode().  Calling deskTop->setState()
  675.                         // to set sfVisible off and then on as in TVDEMO
  676.                         // doesn't always redraw the entire screen if
  677.                         // there is a window or some other view on the
  678.                         // desktop that has the focus.
  679.                         setScreenMode(TScreen::screenMode);
  680.                     }
  681.                     destroy(c);
  682.                 }
  683.                 break;
  684.  
  685.             case cmChangePalettes:
  686.                 CmdLinePalette = appPalette + 1;
  687.  
  688.                 if(CmdLinePalette == apTotalPalettes)
  689.                     CmdLinePalette = apColor;
  690.  
  691.                 setScreenMode(TScreen::screenMode);
  692.                 break;
  693.  
  694.             case cmLoadCfg:
  695.                 if(execDialog(new TFileDialog(demo_cfg, "Load Configuration",
  696.                   "~N~ame", fdOpenButton, 100), demo_cfg) != cmCancel)
  697.                     loadConfig(True);
  698.                 break;
  699.  
  700.             case cmSaveCfg:
  701.                 if(execDialog(new TFileDialog(demo_cfg, "Save Configuration",
  702.                   "~N~ame", fdOKButton, 100), demo_cfg) != cmCancel)
  703.                     saveConfig();
  704.                 break;
  705.  
  706.     // Non-standard evCommand events.
  707.             case cmMakeStrings:
  708.                 // This creates a text file containing #defines for
  709.                 // all palettes as currently configured.  Use it for
  710.                 // creating your own custom palette replacement for
  711.                 // cpAltColor, cpColor, cpBlackWhite, cpMonochrome,
  712.                 // the help palettes, or your custom object palettes.
  713.                 palfp = fopen("PALETTE.DEF", "wt");
  714.                 if(palfp)
  715.                 {
  716.                     short save_palette = appPalette;
  717.                     fputs("// For each palette:\n// Lines 1-5 = Standard "
  718.                           "palette\n// Line 6 = Help palette\n"
  719.                           "// Line 7-??? = All other color palettes\n", palfp);
  720.  
  721.                     for(short i = 0; i < apTotalPalettes; i++)
  722.                     {
  723.                         appPalette = i;     // Get palette information.
  724.                         TPalette *cpal = &getPalette();
  725.                         char *palptr = cpal->data;
  726.  
  727.                         switch(i)
  728.                         {
  729.                             case 0:
  730.                                 fputs("\n#define AllColor \\\n", palfp);
  731.                                 break;
  732.  
  733.                             case 1:
  734.                                 fputs("\n#define AllBlackWhite \\\n", palfp);
  735.                                 break;
  736.  
  737.                             case 2:
  738.                                 fputs("\n#define AllMonochrome \\\n", palfp);
  739.                                 break;
  740.  
  741.                             default:
  742.                                 fprintf(palfp, "\n#define AllOther_%d\\\n", i);
  743.                                 break;
  744.                         }
  745.  
  746.                         short len = *palptr++, index = 0;
  747.                         while(index != len)
  748.                         {
  749.                             fputs("    \"", palfp);
  750.                             for(short byte = 0; byte < 14 && index != len;
  751.                               byte++, index++)
  752.                             {
  753.                                 fprintf(palfp, "\\x%02X", (short)*palptr++);
  754.  
  755.                                 // Separate standard palette, help palette,
  756.                                 // and user's object palettes.
  757.                                 if(index == sizeof(cpColor) - 2 ||
  758.                                    index == sizeof(cpColor) +
  759.                                             sizeof(cHelpColor) - 3)
  760.                                 {
  761.                                     index++;
  762.                                     break;
  763.                                 }
  764.                             }
  765.  
  766.                             if(index != len)
  767.                                 fputs("\" \\\n", palfp);
  768.                         }
  769.                         fprintf(palfp,"\"\n");
  770.                     }
  771.                     fclose(palfp);
  772.  
  773.                     appPalette = save_palette;
  774.                 }
  775.                 break;
  776.  
  777.             case cmBlueWindow:
  778.                 win = createDemoWindow("Blue Window");
  779.                 if(validView(win))
  780.                     deskTop->insert(win);
  781.                 break;
  782.  
  783.             case cmGrayWindow:
  784.                 win = createDemoWindow("Gray Window");
  785.                 win->palette = wpGrayWindow;
  786.                 if(validView(win))
  787.                     deskTop->insert(win);
  788.                 break;
  789.  
  790.             case cmCyanWindow:
  791.                 win = createDemoWindow("Cyan Window");
  792.                 win->palette = wpCyanWindow;
  793.                 if(validView(win))
  794.                     deskTop->insert(win);
  795.                 break;
  796.  
  797.             case cmDialogBox:
  798.                 dlg = new TDialog(TRect(15,10,55,23), "Dialog Box");
  799.                 dlg->insert(new TColorText(TRect(5,2,28,3), "Normal TColorText", eTxtNormal));
  800.                 dlg->insert(new TColorText(TRect(5,4,28,5), "Information TColorText", eTxtInfo));
  801.                 dlg->insert(new TColorText(TRect(5,6,28,7), "Notification TColorText", eTxtNotify));
  802.                 dlg->insert(new TColorText(TRect(5,8,28,9), "Warning TColorText", eTxtWarn));
  803.                 dlg->insert(new TColorText(TRect(5,10,28,11), "Error TColorText", eTxtError));
  804.                 if(validView(dlg))
  805.                     deskTop->insert(dlg);   // Insert as modeless.
  806.                 break;
  807.  
  808.             case cmHelpWindow:
  809.                 hlp = createDemoHelpWindow();
  810.                 if(validView(hlp))
  811.                     deskTop->insert(hlp);
  812.                 break;
  813.  
  814.             default:
  815.                 return;
  816.         }
  817.         clearEvent (event);
  818.     }
  819. }
  820.  
  821. // Standard Out Of Memory error dialog.
  822. void TDemoApp::outOfMemory(void)
  823. {
  824.     messageBox("Not enough memory for this operation.", mfError | mfCancelButton);
  825. }
  826.  
  827. //
  828. // Standard load config file.  Modify as needed.
  829. //
  830. void TDemoApp::loadConfig(Boolean UseFileSetting)
  831. {
  832.     fpstream *f = new fpstream(demo_cfg, ios::in | ios::nocreate | ios::binary);
  833.  
  834.     if(!f->good())
  835.     {
  836.         //  Turn on the screen?
  837.         if(!(state & sfExposed))
  838.         {
  839.             setScreenMode(TScreen::screenMode);
  840.  
  841.             if(TMouse::present())       // Adjust mouse limits if present.
  842.                 TMouse::setRange(TScreen::screenWidth - 1,
  843.                     TScreen::screenHeight - 1);
  844.         }
  845.  
  846.         messageBox(mfError | mfOKButton,
  847.             "Could not open configuration file: %s", demo_cfg);
  848.  
  849.         delete f;
  850.         return;
  851.     }
  852.  
  853.     ipstream &strm = *f;
  854.  
  855.     // Read palettes from the configuration file.
  856.     short curr_palette = appPalette;
  857.     for(short i = 0; i < apTotalPalettes; i++)
  858.     {
  859.         appPalette = i;
  860.         TPalette *palette = &getPalette();
  861.         strm.readBytes(palette->data, palette->data[0] + 1);
  862.     }
  863.     appPalette = curr_palette;
  864.  
  865.     // Get the video mode
  866.     ushort scrMode;
  867.     strm.readBytes(&scrMode, sizeof(scrMode));
  868.  
  869.     // Get the palette that was in use.
  870.     short usePalette;
  871.     strm.readBytes(&usePalette, sizeof(usePalette));
  872.  
  873.     // If not overridden from the command line, set the palette.
  874.     if(CmdLinePalette == -1 || (CmdLinePalette != -1 && UseFileSetting))
  875.         CmdLinePalette = usePalette;
  876.  
  877.     if(scrMode & TDisplay::smFont8x8)
  878.         shadowSize.x = 1;
  879.     else
  880.         shadowSize.x = 2;
  881.  
  882.     setScreenMode(scrMode);
  883.  
  884.     if(TMouse::present())       // Adjust mouse limits if present.
  885.         TMouse::setRange(TScreen::screenWidth - 1, TScreen::screenHeight - 1);
  886.  
  887.     // ************************************************************************
  888.     // Add code here to load non-standard application-specific config data.
  889.  
  890.     delete f;
  891. }
  892.  
  893. //
  894. // Standard save config file.  Modify as needed.
  895. //
  896. void TDemoApp::saveConfig(void)
  897. {
  898.     fpstream *f = new fpstream(demo_cfg, ios::trunc | ios::binary);
  899.  
  900.     if(!f->good())
  901.     {
  902.         messageBox(mfError | mfOKButton,
  903.             "Could not open configuration file: %s", demo_cfg);
  904.  
  905.         delete f;
  906.         return;
  907.     }
  908.  
  909.     opstream &strm = *f;
  910.  
  911.     // Store the palettes
  912.     short curr_palette = appPalette;
  913.     for(short i = 0; i < apTotalPalettes; i++)
  914.     {
  915.         appPalette = i;
  916.         TPalette *palette = &getPalette();
  917.         strm.writeBytes(palette->data, palette->data[0] + 1);
  918.     }
  919.     appPalette = curr_palette;
  920.  
  921.     // Store current video mode
  922.     strm.writeBytes(&TScreen::screenMode, sizeof(TScreen::screenMode));
  923.  
  924.     // Store current palette in use.
  925.     strm.writeBytes(&appPalette, sizeof(appPalette));
  926.  
  927.     // ************************************************************************
  928.     // Add code here to save non-standard application-specific config data.
  929.  
  930.     delete f;
  931. }
  932.  
  933. // ****************************************************************************
  934. //
  935. // The isTileable() function checks for a tileable view on the desktop.
  936. //
  937. Boolean isTileable(TView *p, void *)
  938. {
  939.     // Must ignore objects such as the clipboard when they are hidden!
  940.     if(!(p->options & ofTileable) || !(p->state & sfVisible))
  941.         return False;
  942.  
  943.     return True;
  944. }
  945.  
  946. // This function executes any dialog passed to it and destroys it when done.
  947. ushort execDialog(TDialog *d, void *data)
  948. {
  949.     TView *p = TProgram::application->validView(d);
  950.     if(!p)
  951.         return cmCancel;
  952.  
  953.     if(data)
  954.         p->setData(data);
  955.  
  956.     ushort result = TProgram::deskTop->execView(p);
  957.  
  958.     if(result != cmCancel && data)
  959.         p->getData(data);
  960.  
  961.     TObject::destroy(p);
  962.     return result;
  963. }
  964.  
  965. // ****************************************************************************
  966. // End of standard front end functions.
  967. // ****************************************************************************
  968. // Other functions not in the standard front end file.
  969.  
  970. // ****************************************************************************
  971. // Create a demo window to view the colors.
  972. TWindow *TDemoApp::createDemoWindow(char *aTitle)
  973. {
  974.     randomize();
  975.  
  976.     // Randomly select an initial size and position.
  977.     TRect r(0, 0, 34, 6);
  978.     r.move(rand() % 30, rand() % 10);
  979.  
  980.     TWindow *win = new TWindow(r, aTitle, 0);
  981.  
  982.     if(!win)
  983.         return NULL;
  984.  
  985.     win->options |= ofTileable;     // Allow it to cascade/tile.
  986.  
  987.     win->standardScrollBar(sbVertical);
  988.     r = win->getClipRect();
  989.     r.grow(-1,-1);
  990.  
  991.     TInterior *i = new TInterior(r);
  992.     i->growMode = gfGrowHiX | gfGrowHiY;
  993.  
  994.     win->insert(i);
  995.  
  996.     return win;
  997. }
  998.  
  999. // Create a demo help window to view the colors.
  1000. TDemoHelpWindow *TDemoApp::createDemoHelpWindow(void)
  1001. {
  1002.     randomize();
  1003.  
  1004.     // Randomly select an initial size and position.
  1005.     TRect r(0, 0, 34, 7);
  1006.     r.move(rand() % 30, rand() % 10);
  1007.  
  1008.     TDemoHelpWindow *hlp = new TDemoHelpWindow(r);
  1009.  
  1010.     if(!hlp)
  1011.         return NULL;
  1012.  
  1013.     hlp->standardScrollBar(sbVertical);
  1014.  
  1015.     r = hlp->getClipRect();
  1016.     r.grow(-1,-1);
  1017.     THelpInterior *hi = new THelpInterior(r);
  1018.     hi->growMode = gfGrowHiX | gfGrowHiY;
  1019.  
  1020.     hlp->insert(hi);
  1021.  
  1022.     return hlp;
  1023. }
  1024.  
  1025. void TInterior::draw(void)
  1026. {
  1027.     // A simple demo to display all window colors colors.
  1028.     TView::draw();
  1029.  
  1030.     TDrawBuffer b;
  1031.     ushort color = getColor(0x0706);
  1032.  
  1033.     b.moveChar(0, ' ', color, size.x);
  1034.     b.moveCStr( 0, "Normal Text    ~Selected Text~", color );
  1035.     writeLine( 2, 1, 28, 1, b);
  1036. }
  1037.  
  1038. TPalette &TDemoHelpWindow::getPalette() const
  1039. {
  1040.     static TPalette palette(cHelpWindow, sizeof( cHelpWindow)-1);
  1041.     return palette;
  1042. }
  1043.  
  1044. void THelpInterior::draw(void)
  1045. {
  1046.     // A simple demo to insure the help colors are in the right place.
  1047.     TView::draw();
  1048.  
  1049.     TDrawBuffer b;
  1050.     ushort color = getColor(0x0201);
  1051.  
  1052.     b.moveChar(0, ' ', color, size.x);
  1053.     b.moveCStr( 0, "Normal Text    ~Keyword~", color );
  1054.     writeLine( 2, 1, 22, 1, b);
  1055.  
  1056.     color = getColor(0x03);
  1057.     b.moveChar(0, ' ', color, 16);
  1058.     b.moveCStr( 0, "Selected keyword", color );
  1059.     writeLine( 2, 3, 16, 1, b);
  1060. }
  1061.  
  1062. TPalette &THelpInterior::getPalette() const
  1063. {
  1064.     static TPalette palette(cHelpViewer, sizeof( cHelpViewer)-1);
  1065.     return palette;
  1066. }
  1067.  
  1068. // ****************************************************************************
  1069. // End of standard front end file.
  1070. // ****************************************************************************
  1071.