home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 26 / CD_ASCQ_26_1295.iso / vrac / tvme30.zip / TVEDIT1.CPP < prev    next >
C/C++ Source or Header  |  1995-08-02  |  42KB  |  1,205 lines

  1. // File    : TVEDIT1.CPP
  2. // Author  : Eric Woodruff,  CIS ID: 72134,1150
  3. // Updated : Wed 08/02/95 17:54:19
  4. // Note    : Copyright 1994-95, Eric Woodruff, All rights reserved
  5. // Compiler: Borland C++ 3.1 to 4.xx
  6. //
  7. // This program demonstrates the TVMEditor classes.
  8. // Included is my standard front end.  It will also serve as a fairly good
  9. // tutorial on selecting color palettes from the command line as well as
  10. // saving and restoring colors to a configuration file.  This same front
  11. // end and all references to TVCOLR.H, TVCOLR.DOC, and COLUPDT.DOC can be
  12. // found in TVCOLR.ZIP also in BCPPDOS library 11 on CompuServe.  It is *not*
  13. // required that you have it for TVMEditor use though.  It simply describes
  14. // a method of extending the Turbo Vision color palettes.
  15. //
  16. // You may use any of the following command line parameters:
  17. //
  18. //     /MC | /MB | /MM | /MA    -  Select color, black & white, monochrome,
  19. //                                 or alternate color palette.  If not
  20. //                                 specified, it defaults to the palette
  21. //                                 best suited for the monitor in use.
  22. //
  23. //     /Cdr:\path\filename.ext  -  Specify different default config filename.
  24. //
  25. //     /Rdr:\path\filename.ext  -  Specify different resource filename.
  26. //
  27. //     /VA | /VE | /VX | /VM |  -  Specify the default virtual memory
  28. //     /VS | /VD                   preference for the editors (Auto detect,
  29. //                                 EMS first, XMS first, EMS only, XMS only,
  30. //                                 or disk only).
  31. //
  32. //     dr:\path\filename.ext    -  Load file into an editor from command line.
  33. //
  34. // This program uses a resource file for some of the objects like the menu
  35. // bar, status line, color dialog box, etc.  If you use this code elsewhere
  36. // without a resource file, you can generally replace the rsc->get() calls
  37. // with calls to the functions from BLDRSC.CPP that create the objects.  Just
  38. // include those functions in here or in a separate module and remove all
  39. // references to the resource file.
  40. //
  41.  
  42. // #define SHAREWARE - Done in Options | Compiler | Code Generation | Defines
  43. //                     for the shareware release.
  44.  
  45. // Uncomment the following line to allow searching the the end of the
  46. // executable for the resource file.
  47. //
  48. // NOTE: The resource file cannot be appended to the executable if the
  49. //       application is compiled to run under protected mode.  It won't let
  50. //       you access it (sort of like the problem when including debug info).
  51. //#define FINAL
  52.  
  53. #include <conio.h>
  54. #include <ctype.h>
  55. #include <dir.h>
  56. #include <dos.h>
  57. #include <float.h>
  58. #include <io.h>
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62.  
  63. extern unsigned _stklen = 10240U;       // Increase stack size to 10K.
  64.  
  65. #define Uses_MsgBox
  66. #define Uses_TApplication
  67. #define Uses_TColorDialog
  68. #define Uses_TChDirDialog
  69. #define Uses_TDeskTop
  70. #define Uses_TDialog
  71. #define Uses_TEvent
  72. #define Uses_TFileDialog
  73. #define Uses_TKeys
  74. #define Uses_TMenuBar
  75. #define Uses_TMenuItem
  76. #define Uses_TPalette
  77. #define Uses_TResourceFile
  78. #define Uses_TScreen
  79. #define Uses_TScrollBar
  80. #define Uses_TStatusDef
  81. #define Uses_TStatusItem
  82. #define Uses_TStatusLine
  83. #define Uses_TStreamableClass
  84. #define Uses_TSubMenu
  85. #define Uses_TWindow
  86. #define Uses_TVCOLR             // Use this if you modified the TV.H file.
  87. #define Uses_fpstream
  88. #include <tv.h>
  89.  
  90. #if !defined(cpDefSize)
  91. // Use this if you chose not to modify the Turbo Vision files.
  92. #include <tvcolr.h>
  93. #endif
  94.  
  95. // ****************************************************************************
  96. // Headers not in the standard front end file.
  97.  
  98. #if !defined(SHAREWARE)
  99. #define Uses_TVirtualMemory     // Only available in registered versions.
  100. #endif
  101. #define Uses_TVMEditWindow
  102. #include <tvmedit.h>
  103.  
  104. #if defined(CSH_LIBRARY)
  105. #define Uses_TCSHEditor
  106. #define Uses_TCSHEditWindow     // Uses Color Syntax Highlighting
  107. #include <cshedit.h>
  108. #endif
  109.  
  110. #ifdef INCLUDE_HEAPVIEW
  111. #include <heapview.h>
  112. #endif
  113.  
  114. #include <tmsgview.h>
  115.  
  116. #define Uses_TVMEditorApp
  117. #include "tvedit.h"             // Demo program header file.
  118.  
  119. // ****************************************************************************
  120.  
  121. #include "link.h"              // Resource file link definitions.
  122.  
  123. //extern int    _Cdecl _argc;  // Global pointers to the command line args.
  124. //extern char **_Cdecl _argv;  // This way the app's constructor can access
  125.                                // them.  Declarations are in DOS.H too.
  126.  
  127. char demo_cfg[MAXPATH],     // Configuration filename.
  128.      demo_rsc[MAXPATH];     // Resource filename.
  129.  
  130. #if defined(CSH_LIBRARY)
  131. char demo_csh[MAXPATH];     // Default location of the CSH data file.
  132. #endif
  133.  
  134. // Resource file pointers.
  135. fpstream *s;
  136. TResourceFile *rsc = NULL;  // NULL to start with.
  137.  
  138. // The value of this variable determines what is printed when the program
  139. // exits back to DOS.
  140. short ExitValue = EXIT_NOERR;
  141.  
  142. // Monitor type palette index as set from the command line (/MC | /MB | /MM |
  143. // /MA).  Default it is -1 to let the application use the default palette
  144. // selected by TProgram::initScreen().
  145. short CmdLinePalette = -1;
  146.  
  147. // Global pointer to the user screen buffer for the User Screen event.
  148. char *ScrBuf = NULL;
  149.  
  150. // ****************************************************************************
  151. // Global variables not in the standard front end file.
  152.  
  153. // Global clipboard pointer for the editor.
  154. TVMEditWindow *clipWindow;
  155.  
  156. // Indent for new editor windows.
  157. short winIndent = 0;
  158.  
  159. // Global data structures for the demo.
  160. #if !defined(__DPMI16__) && !defined(__DPMI32__)
  161.     StartUp StartUpOpts = { soIndicAtTop | soUseCSH, 0, 20};
  162. #else
  163.     StartUp StartUpOpts = { soIndicAtTop | soUseCSH, 20, 16384 };
  164. #endif
  165.  
  166. // Memo demo data.
  167. DemoData Demo = { 22, "Test - NULL terminated", 31, "Initial Data\r\nSecond Memo Field" };
  168.  
  169. //*****************************************************************************
  170. // Standard functions.  Modify as needed.
  171.  
  172. void exitfunc(void)
  173. {
  174. #if _TV_VERSION != 0x0103
  175.     // Prevent the screen from being cleared on exit.
  176.     TScreen::clearOnSuspend = False;
  177. #endif
  178.  
  179.     switch(ExitValue)
  180.     {
  181.         case EXIT_NOERR:
  182.             cout << endl << "Thank you for using this demo program." << endl;
  183.             break;
  184.  
  185.         case EXIT_RSCERR:
  186.             cout << "Could not locate or open resource file: " <<
  187.                 demo_rsc << endl;
  188.             break;
  189.  
  190.         case EXIT_SWERR:
  191.             cout << "Bad parameter: " << _argv[_argc] << endl << endl;
  192.             // Fall through and display command line syntax.
  193.  
  194.         case EXIT_SYNTAX:
  195.             cout << "Command line syntax:" << endl << _argv[0] << endl <<
  196.                 " [/MC | /MB | /MM | /MA] [/Rrsc_file.ext] [/Ccfg_file.ext]" <<
  197.                 endl <<
  198.                 " [/VE | /VX | /VM | /VS | /VD] [dr:\\path\\filespec(s)...]" <<
  199.                 endl;
  200.             break;
  201.     }
  202. }
  203.  
  204. #if _TV_VERSION == 0x0103
  205. // Tell the exit code to call the display function just prior to quiting.
  206. #pragma exit exitfunc 31
  207. #endif
  208.  
  209. //
  210. // This will kick everything off.  Note that no argc, or argv parameters are
  211. // used.  The global _argc and _argv variables are used instead so that we
  212. // don't have to pass them to the constructor.  You don't need to do things
  213. // this way, it's just one alternative.
  214. //
  215. void main(void)
  216. {
  217.     short index = 1;
  218.  
  219. #if _TV_VERSION != 0x0103
  220.     // Prevent the screen from being cleared on exit until we've had a
  221.     // chance to check things out.
  222.     TScreen::clearOnSuspend = False;
  223.  
  224.     // Register the exit function so that the exit messages are still
  225.     // displayed.
  226.     atexit(exitfunc);
  227. #endif
  228.  
  229.     // To begin with, assume that the resource file is appended to the
  230.     // executable.  If it isn't, we'll try a different approach.
  231.     // To append the resource file to the executable you would issue the
  232.     // command:
  233.     //          COPY /B filename1.EXE+filename.RSC filename2.EXE
  234.     //
  235.     // Make sure the destination .EXE name is not the same as the source
  236.     // .EXE name or you will overwrite the source .EXE file.
  237.     // Also note that the source .EXE can't have debug info at the end of it.
  238.     //
  239.     strcpy(demo_rsc, _argv[0]);
  240.  
  241. // Until the final production version, don't bother trying to access the
  242. // executable.  Debugging from within the IDE will cause a general access
  243. // failure on the drive when it tries to open it.  TResourceFile won't
  244. // read past the debug info at the end of the executable anyway so use a
  245. // separate resource file until debugging is all done.
  246. #ifndef FINAL
  247.     strcpy(strrchr(demo_rsc, '.') + 1, "RSC");
  248. #endif
  249.  
  250.     // Modify executable name to get location and name of the default
  251.     // configuration file.  We'll assume the config file (if any) is in the
  252.     // same directory as the executable and has the same name with a .CFG
  253.     // extension.  It can be changed with a /C command line switch to
  254.     // specify a different path to it or a different name.
  255.  
  256.     strcpy(demo_cfg, _argv[0]);
  257.     strcpy(strrchr(demo_cfg, '.') + 1, "CFG");
  258.  
  259.     // Look for command line switches affecting configuration and resource
  260.     // files.  A check for a user requested palette is also included here.
  261.     // That way everything will come up in the proper colors when
  262.     // setScreenMode() is called in the application's constructor or in
  263.     // the loadConfig() function.
  264.     //
  265.     // I've found it best to scan for and process these items here because
  266.     // I do have some cases where the command line arguments are processed
  267.     // in the application's constructor to insert some default objects into
  268.     // the desktop such as file or directory viewers, editor windows, etc
  269.     // specified with other command line switches.  If there is an error
  270.     // doing one of them, you need the screen active so that you can see
  271.     // the error message box.  Also, you don't have to do anything special
  272.     // in the application's constructor to switch palettes if one of these
  273.     // is found.
  274.     //
  275.     while(index != _argc)
  276.     {
  277.         // Allow -opt or /opt.
  278.         if(_argv[index][0] == '/' || _argv[index][0] == '-')
  279.             switch(toupper(_argv[index][1]))
  280.             {
  281.                 case 'M':       // Change the default palette.
  282.                     switch(toupper(_argv[index][2]))
  283.                     {
  284.                         case 'C':
  285.                             CmdLinePalette = apColor;
  286.                             break;
  287.  
  288.                         case 'B':
  289.                             CmdLinePalette = apBlackWhite;
  290.                             break;
  291.  
  292.                         case 'M':
  293.                             CmdLinePalette = apMonochrome;
  294.                             break;
  295.  
  296.                         case 'A':
  297.                             CmdLinePalette = apAltColor;
  298.                             break;
  299.  
  300.                         default:
  301.                             ExitValue = EXIT_SWERR;  // Signal bad switch value.
  302.                             _argc = index;
  303.                             exit(EXIT_SWERR);
  304.                     }
  305.                     break;
  306.  
  307.                 case 'C':           // Use a different configuration filename.
  308.                     strcpy(demo_cfg, &_argv[index][2]);
  309.                     break;
  310.  
  311.                 case 'R':           // Use a different resource filename.
  312.                     strcpy(demo_rsc, &_argv[index][2]);
  313.                     break;
  314.  
  315. #if !defined(SHAREWARE) && !defined(__DPMI16__) && !defined(__DPMI32__)
  316.  
  317.                 case 'V':       // Change the default virtual memory type.
  318.                     switch(toupper(_argv[index][2]))
  319.                     {
  320.                         case 'A':
  321.                             TVirtualMemory::MemoryCheck = TVMAutoDetect;
  322.                             break;
  323.  
  324.                         case 'E':
  325.                             TVirtualMemory::MemoryCheck = TVMEMSFirst;
  326.                             break;
  327.  
  328.                         case 'X':
  329.                             TVirtualMemory::MemoryCheck = TVMXMSFirst;
  330.                             break;
  331.  
  332.                         case 'M':
  333.                             TVirtualMemory::MemoryCheck = TVMEMSOnly;
  334.                             break;
  335.  
  336.                         case 'S':
  337.                             TVirtualMemory::MemoryCheck = TVMXMSOnly;
  338.                             break;
  339.  
  340.                         case 'D':
  341.                             TVirtualMemory::MemoryCheck = TVMDiskOnly;
  342.                             break;
  343.  
  344.                         default:
  345.                             ExitValue = EXIT_SWERR;  // Signal bad switch value.
  346.                             _argc = index;
  347.                             exit(EXIT_SWERR);
  348.                     }
  349.                     StartUpOpts.VirtualMemory = TVirtualMemory::MemoryCheck;
  350.                     break;
  351. #endif
  352.                 case '?':
  353.                     ExitValue = EXIT_SYNTAX;    // Display command syntax.
  354.                     exit(EXIT_SYNTAX);
  355.  
  356. //                case 'X':         // Ignore other valid switches that
  357. //                case 'Y':         // will be processed in the application's
  358. //                case 'Z':         // constructor.
  359. //                    break;
  360.  
  361.                 default:
  362.                     ExitValue = EXIT_SWERR;  // Signal bad switch value.
  363.                     _argc = index;
  364.                     exit(EXIT_SWERR);
  365.             }
  366.  
  367.         index++;
  368.     }
  369.  
  370.     // Now try to open the resource file and use it.
  371.     s = new fpstream(demo_rsc, ios::in | ios::nocreate | ios::binary);
  372.     if(s->good())
  373.     {
  374.         rsc = (TResourceFile *)new TResourceFile(s);
  375.  
  376.         if(!rsc->count())
  377.         {
  378.             TObject::destroy(rsc);      // No resource file in the EXE or
  379.             rsc = NULL;                 // user supplied filename.
  380.         }
  381.     }
  382.     else
  383.         delete s;
  384.  
  385.     if(!rsc)
  386.     {
  387.         // As long as a /R switch wasn't specified, modify the executable name
  388.         // to get the location and name of the default resource file.
  389.         // We'll assume the resource file is in the same directory as the
  390.         // executable and has the same name with a .RSC extension.  It can be
  391.         // changed with a /R command line switch to specify a different path
  392.         // to it or a different name.  If that is the case, it wasn't
  393.         // accessible.
  394.         if(!strnicmp(_argv[0], demo_rsc, strlen(_argv[0]) - 3))
  395.         {
  396.             strcpy(strrchr(demo_rsc, '.') + 1, "RSC");
  397.             s = new fpstream(demo_rsc, ios::in | ios::nocreate | ios::binary);
  398.  
  399.             if(!s->good())
  400.                 ExitValue = EXIT_RSCERR;      // Still not accessible.
  401.             else
  402.             {
  403.                 rsc = (TResourceFile *)new TResourceFile(s);
  404.                 if(!rsc->count())
  405.                 {
  406.                     TObject::destroy(rsc);      // Not a valid resource file.
  407.                     ExitValue = EXIT_RSCERR;
  408.                 }
  409.             }
  410.         }
  411.         else
  412.             ExitValue = EXIT_RSCERR;   // User specified file isn't accessible.
  413.  
  414.         if(ExitValue)
  415.             exit(EXIT_RSCERR);
  416.     }
  417.  
  418. #if _TV_VERSION != 0x0103
  419.     // Now it's okay to clear the screen upon exit.
  420.     TScreen::clearOnSuspend = True;
  421. #endif
  422.  
  423. #if defined(CSH_LIBRARY)
  424.     // Set the location of the default CSH data set file.
  425.     strcpy(demo_csh, _argv[0]);
  426.     strcpy(strrchr(demo_csh, '\\') + 1, "CSHDEFLT.DTA");
  427.  
  428.     TCSHEditor::CSHDataSetName = demo_csh;
  429. #endif
  430.  
  431.     // Application Instance.  Change class name of application as needed.
  432.     TVMEditorApp Demo;
  433.     Demo.run();
  434.  
  435.     // Shutdown the app and close the resource file.
  436.     Demo.shutDown();
  437.     TObject::destroy(rsc);
  438.  
  439.     if(ScrBuf)
  440.         delete [] ScrBuf;     // Delete User Screen buffer if used.
  441.  
  442. #if _TV_VERSION != 0x0103
  443.     // Be neat and get rid of the desktop display so that the exit message
  444.     // can be seen clearly.
  445.     Demo.suspend();
  446. #endif
  447.  
  448.     exit(EXIT_NOERR);
  449. }
  450.  
  451. // ****************************************************************************
  452. // Standard front end functions follow, modify as needed.
  453.  
  454. //
  455. // Constructor for the application.
  456. //
  457. TVMEditorApp::TVMEditorApp(void) :
  458.   TProgInit( &TVMEditorApp::initStatusLine, &TVMEditorApp::initMenuBar,
  459.     &TVMEditorApp::initDeskTop )
  460. {
  461.     TRect  r;
  462.     TEvent event;
  463.     short  index = 1,
  464.            Ignored = 0;        // Count of ignored command line parameters.
  465.  
  466. #if _TV_VERSION == 0x0103
  467.     // This line insures snow checking is off to speed up the display.
  468.     // It can be removed if you've modified TSCREEN.CPP or are using TV 2.0.
  469.     TScreen::checkSnow = False;
  470. #endif
  471.  
  472. #ifdef INCLUDE_HEAPVIEW
  473.     // Create the heap view (optional).
  474.     r = getExtent();
  475.     r.a.x = r.b.x - 22;
  476.     r.b.y = r.a.y + 1;
  477.     heap = new THeapView( r );
  478.     insert(heap);
  479. #endif
  480.     // **********************************************************************
  481.     // Application-specific setup code.
  482.  
  483. #if !defined(SHAREWARE)
  484.     #if !defined(__DPMI16__) && !defined(__DPMI32__)
  485.         // Set memory option based on library default.
  486.         StartUpOpts.VirtualMemory = TVirtualMemory::MemoryCheck;
  487.     #else
  488.         StartUpOpts.MaxAllocatable =
  489.             short(TVirtualMemory::getMaxAllocation() / 1024L);
  490.     #endif
  491. #endif
  492.  
  493.     // These commands need to be disabled manually when the application
  494.     // is initialized because there aren't any editors around yet to use
  495.     // them or turn them off automatically.
  496.     TCommandSet ts;
  497.     ts.enableCmd(cmSave);
  498.     ts.enableCmd(cmSaveAs);
  499.     ts.enableCmd(cmSaveAll);
  500.     ts.enableCmd(cmPrintFile);
  501.     ts.enableCmd(cmUndo);
  502.     ts.enableCmd(cmRedo);
  503.     ts.enableCmd(cmCut);
  504.     ts.enableCmd(cmCopy);
  505.     ts.enableCmd(cmPaste);
  506.     ts.enableCmd(cmClear);
  507.     ts.enableCmd(cmFind);
  508.     ts.enableCmd(cmReplace);
  509.     ts.enableCmd(cmSearchAgain);
  510.     ts.enableCmd(cmGotoLine);
  511.     ts.enableCmd(cmLocalEditorOpt);
  512.     ts.enableCmd(cmPrevMsg);
  513.     ts.enableCmd(cmNextMsg);
  514.     disableCommands(ts);
  515.  
  516.     kbFlags = EOS;
  517.  
  518.     // Install the new editorDialog() handler.
  519.     TVMEditor::editorDialog = doEditDialog;
  520.  
  521.     // Install the Signs of Life handler
  522.     TVMEditor::signsOfLife = doSignsOfLife;
  523.  
  524.     // Create a clipboard.  Keep the conventional memory buffer small so
  525.     // as not to waste memory on it.
  526.     clipWindow = (TVMEditWindow *)validView(
  527.         new TVMEditWindow(deskTop->getExtent(), NULL, wnNoNumber, True, 4) );
  528.  
  529.     if(clipWindow)
  530.     {
  531.         // Make sure other editors know where it is.
  532.         TVMEditor::clipboard = clipWindow->editor;
  533.  
  534.         // Just a preference, no need for undo/redo on the clipboard.
  535.         TVMEditor::clipboard->setOption(efCanUndo, False);
  536.  
  537.         // The clipboard window is hidden by default.
  538.         clipWindow->hide();
  539.         deskTop->insert(clipWindow);
  540.     }
  541.  
  542. #if defined(AUTOEOL)
  543.     // Test efAutoEOLMark.  Uses a visible EOL marker (a left chevron).
  544.     TVMEditor::EOLMarker = '\xAE';
  545.     TVMEditor::GlobalOpts.Operation |= (efWordWrap | efAutoWrap);
  546.     TVMEditor::GlobalOpts.EnterMatch |= efAutoEOLMark;
  547. #endif
  548.  
  549. #if defined(__FLAT__)
  550.     // In case something went wrong (or if you don't construct a clipboard!),
  551.     // call AllocateDescriptor() to establish TVMEditor::lowMemDesc.  It is
  552.     // used in idle() to access the BIOS keyboard flags.
  553.     if(!TVMEditor::clipboard)
  554.         AllocateDescriptor();
  555. #endif
  556.  
  557.     // **********************************************************************
  558.     // All the default objects and views have been constructed, now we
  559.     // can do some stuff with the desktop.
  560.  
  561.     // If there is a configuration file, read in the data now.
  562.     // Then, here or in loadConfig, turn on the screen and redraw it.
  563.     // If it is done earlier than this, the proper colors won't be used
  564.     // for the initial screen when an alternate palette is specified.
  565.     if(!access(demo_cfg, 0))
  566.         loadConfig(False);
  567.     else
  568.     {
  569.         setScreenMode(TScreen::screenMode);
  570.  
  571. #if _TV_VERSION == 0x0103       // Fixed in TV 2.0
  572.         if(TMouse::present())       // Adjust mouse limits if present.
  573.             TMouse::setRange(TScreen::screenWidth - 1,
  574.                 TScreen::screenHeight - 1);
  575. #endif
  576.     }
  577.  
  578.     // Attempt to restore the desktop if one exists.
  579. #if defined(__DPMI16__)
  580.     if(!access("TVEDIT16.TVD", 0))
  581.         restoreDeskTop();
  582. #else
  583.     #if defined(__DPMI32__)
  584.         if(!access("TVEDIT32.TVD", 0))
  585.             restoreDeskTop();
  586.     #else
  587.         if(!access("TVEDIT.TVD", 0))
  588.             restoreDeskTop();
  589.     #endif
  590. #endif
  591.  
  592.     // **********************************************************************
  593.  
  594.     // Process any other command line arguments now.
  595.     // Don't forget to ignore any of the one's parsed in main().
  596.     while(index != _argc)
  597.     {
  598.         if(_argv[index][0] == '/' || _argv[index][0] == '-')
  599.         {
  600.             switch(toupper(_argv[index][1]))
  601.             {
  602. //                case 'X':
  603. //                case 'Y':
  604. //                case 'Z':
  605. //                    do something
  606. //                    break;
  607.  
  608.                 case 'C':                  // Ignore config file selection
  609.                 case 'R':                  // Ignore resource file selection
  610.                 case 'M':                  // Ignore palette selection
  611.                 case 'V':                  // Ignore virtual memory selection
  612.                     Ignored++;             // They're already taken care of.
  613.                     break;
  614.  
  615.                 default:
  616.                     Ignored++;
  617.                     messageBox(mfError | mfOKButton,
  618.                         "Invalid command line switch: %s", _argv[index]);
  619.                     break;
  620.             }
  621.         }
  622.         else  // If not a switch, default to doing something else with it.
  623.         {
  624. //            // Ignored by default.
  625. //            Ignored++;
  626. //            messageBox(mfError | mfOKButton,
  627. //                "Invalid command line parameter: %s", _argv[index]);
  628.  
  629.             // For the editor demo, assume it is a valid filename or wildcard.
  630.             openEditor(_argv[index], True);
  631.         }
  632.  
  633. //      Processing to be done after each switch command (if any).
  634. //      Insert other default views, etc.
  635.  
  636.         index++;
  637.     }
  638.  
  639.     // Display the About Box if no command line parameters are passed
  640.     // or only /Mx, /C, or /R parameters were used.
  641.     if(_argc < 2 || (_argc - Ignored) < 2)
  642.     {
  643.         event.what = evCommand;
  644.         event.message.command = cmAbout;
  645.         putEvent(event);
  646.     }
  647. }
  648.  
  649. // This is where the palettes for the application are defined.
  650. TPalette &TVMEditorApp::getPalette() const
  651. {
  652.     // The Color and Alternate Color attribute maps are swapped in these
  653.     // definitions so that my color preferences are used by default for
  654.     // color monitors.
  655.  
  656.     static TPalette color( cpExtAltColor, sizeof( cpExtAltColor)-1 );
  657.     static TPalette blackwhite( cpExtBlackWhite, sizeof( cpExtBlackWhite)-1 );
  658.     static TPalette monochrome( cpExtMonochrome, sizeof( cpExtMonochrome)-1 );
  659.     static TPalette altcolor( cpExtColor, sizeof( cpExtColor)-1 );
  660.  
  661.     static TPalette *palettes[] =
  662.     {
  663.         &color,
  664.         &blackwhite,
  665.         &monochrome,
  666.         &altcolor        // Additional palettes must come after standard ones
  667.                          // in this array.
  668.     };
  669.     return *(palettes[appPalette]);
  670. }
  671.  
  672. //
  673. // Application idle function.  Modify or remark out as required.
  674. //
  675. void TVMEditorApp::idle(void)
  676. {
  677.     uchar newFlags;
  678.  
  679.     TProgram::idle();
  680.  
  681. #ifdef INCLUDE_HEAPVIEW
  682.     heap->update();
  683. #endif
  684.  
  685.     // While idling, keep the editor windows informed of changes to the
  686.     // CAPS, NumLock, and ScrollLock states.  Those keys don't generate
  687.     // an event.
  688. #if !defined(__DPMI16__) && !defined(__DPMI32__)
  689.     newFlags = (*((uchar _FAR *)MK_FP(0x40, 0x17)) &
  690.       (kbCapsState | kbNumState | kbScrollState));
  691. #else
  692.     #if defined(__DPMI16__)
  693.         newFlags = (*((uchar _FAR *)MK_FP(__Seg0040, 0x17)) &
  694.           (kbCapsState | kbNumState | kbScrollState));
  695.     #else
  696.         // Access BIOS keyboard flags.  Use __emit__() to avoid the
  697.         // inline assembler problems.
  698.         __emit__(0x1E);         // push    ds
  699.  
  700.         _ESI = 1047L;
  701.         _DS = TVMEditor::lowMemDesc;
  702.  
  703.         __emit__(0x8A);         // mov     bl, ds:[esi]
  704.         __emit__(0x1E);
  705.         __emit__(0x1F);         // pop     ds
  706.  
  707.         newFlags = (_BL & 0x70);
  708.     #endif
  709. #endif
  710.  
  711.     if(kbFlags != newFlags)
  712.     {
  713.         kbFlags = newFlags;
  714.         message(deskTop, evBroadcast, cmkbFlagChg, NULL);
  715.     }
  716.  
  717.     // Turn off Tile and Cascade if other window commands are disabled.
  718.     if(!commandEnabled(cmPrev))
  719.     {
  720.         disableCommand(cmCloseAll);
  721.         disableCommand(cmTile);
  722.         disableCommand(cmCascade);
  723.     }
  724.     else
  725.     {
  726.         enableCommand(cmCloseAll);
  727.         enableCommand(cmTile);
  728.         enableCommand(cmCascade);
  729.     }
  730.  
  731.     // Select the menu bar if the desktop is empty.
  732.     if(!deskTop->current && !menuBar->getState(sfSelected))
  733.     {
  734.         TEvent event;
  735.         event.what = evCommand;
  736.         event.message.command = cmMenu;
  737.         putEvent(event);
  738.     }
  739. }
  740.  
  741. // Test the Get Selected Text feature.
  742. void TVMEditorApp::testGetText(void)
  743. {
  744.     TVMEditWindow *edWin = (TVMEditWindow *)message(TProgram::deskTop,
  745.         evBroadcast, cmEditorPresent, NULL);
  746.  
  747.     if(!edWin)
  748.         return;
  749.  
  750. #if !defined(SHAREWARE) && defined(TVME_DIAG)
  751.     // This a diagnostic check to see how many characters are in the editor
  752.     // buffer.  It is mainly for debugging the TextSize code, but also returns
  753.     // the LRU counter to see what kind of load the swap mechanism is under.
  754.  
  755.     char temp[256];
  756.     short x;
  757.     long  y;
  758.  
  759.     TVirtualMemory* buf = edWin->editor->Buffer;
  760.  
  761.     edWin->editor->textLimits(x, y);
  762.  
  763.     // V(irtual buffer) + L(ine count) should always equal E(ditor)
  764.     // when efUseLFOnly is disabled.  When efUseLFOnly is enabled,
  765.     // V and E should always be equal.
  766.     sprintf(temp, "Diagnostic - Size Info:\n  V=%7ld  L=%7ld\n"
  767.         "V+L=%7ld  E=%7ld\nLRU=%d", buf->getTextSize(), y,
  768.         buf->getTextSize() + y, edWin->editor->getTextSize(),
  769.         buf->getLRUCnt());
  770.     messageBox(temp, mfInformation | mfOKButton);
  771. #endif
  772.  
  773.     ushort textSize = edWin->editor->getSelectedTextSize('\r');
  774.     messageBox(mfInformation | mfOKButton, "Selected Text Size = %u",
  775.         textSize);
  776.  
  777.     if(textSize)
  778.     {
  779.         // Use malloc so as not to abort on allocation failure.
  780.         char *text = (char *)malloc(textSize);
  781.  
  782.         if(!text)
  783.         {
  784.             outOfMemory();
  785.             return;
  786.         }
  787.  
  788.         FILE *fp = fopen("GETTEXT.XXX", "wb");
  789.         if(fp)
  790.         {
  791.             Boolean NotDone;
  792.             ushort copyCount;
  793.  
  794.             // Copy text to file until there is no more.
  795.             do
  796.             {
  797.                 copyCount = edWin->editor->getSelectedText(text,
  798.                     textSize, '\r', &NotDone);
  799.  
  800.                 fwrite(text, copyCount, 1, fp);
  801.  
  802.             } while(NotDone);
  803.  
  804.             fclose(fp);
  805.         }
  806.         free(text);
  807.     }
  808.     edWin->editor->setSelect(0,1L,maxLineLength,50,True);
  809. }
  810.  
  811. //
  812. //  Event handler to distribute the work.
  813. //
  814. void TVMEditorApp::handleEvent(TEvent &event)
  815. {
  816.     TColorDialog *c;
  817.  
  818.     if(event.what == evCommand && event.message.command == cmQuit &&
  819.       (StartUpOpts.EdOpts & soSaveDeskTop))
  820.         saveDeskTop();
  821.  
  822.     TApplication::handleEvent(event);
  823.  
  824.     if(event.what == evCommand)
  825.     {
  826.         switch(event.message.command)
  827.         {
  828.     // Standard front end evCommand events.
  829.  
  830.             case cmAbout:               //  About Dialog Box
  831.                 executeDialog((TDialog *)rsc->get("AboutBox"), NULL);
  832.                 break;
  833.  
  834.             case cmRepaint:
  835.                 setScreenMode(TScreen::screenMode);
  836.                 break;
  837.  
  838.             case cmSaveAll:
  839.                 // Change it from a command to a broadcast event.
  840.                 message(deskTop, evBroadcast, cmSaveAll, NULL);
  841.                 break;
  842.  
  843.             case cmDosShell:
  844.                 suspend();          // Suspend Turbo Vision and shell to DOS.
  845.                 cout << endl << "Type EXIT to return..." << endl;
  846.                 system(getenv("COMSPEC"));
  847.                 _fpreset();         // Reset math co-processor.
  848.  
  849.                 if(!ScrBuf)
  850.                     ScrBuf = new char[4100];    // At least 4000 bytes.
  851.  
  852.                 gettext(1, 1, 80, 25, ScrBuf);  // Get screen image.
  853.  
  854.                 resume();       // Restart Turbo Vision.
  855.                 redraw();
  856.  
  857.                 // Tell all open editor windows to resynchronize their
  858.                 // buffers with the copy of the file on disk if necessary.
  859.                 message(deskTop, evBroadcast, cmReSynch, NULL);
  860.                 break;
  861.  
  862.             case cmTile:                //  Tile current windows
  863.                 deskTop->tile(deskTop->getExtent());
  864.  
  865.                 // Tell all editors to Reformat on Resize if they need to.
  866.                 message(deskTop, evBroadcast, cmResizeReformat, NULL);
  867.                 break;
  868.  
  869.             case cmCascade:             //  Cascade current windows
  870.                 deskTop->cascade(deskTop->getExtent());
  871.  
  872.                 // Tell all editors to Reformat on Resize if they need to.
  873.                 message(deskTop, evBroadcast, cmResizeReformat, NULL);
  874.                 break;
  875.  
  876.             case cmCloseAll:    // Close all views that have ofTileable set.
  877.                 TView *vw;
  878.                 while((vw = deskTop->firstThat(isTileable, 0)) != NULL)
  879.                     message(vw, evCommand, cmClose, NULL);
  880.                 break;
  881.  
  882.             case cmScreenSize:          // Change screen size.
  883.                 // If already in 43/50 line mode, return to the startup mode.
  884.                 if(TScreen::screenMode == (TDisplay::smCO80 | TDisplay::smFont8x8))
  885.                     setScreenMode(TScreen::startupMode);
  886.                 else
  887.                     setScreenMode(TDisplay::smCO80 | TDisplay::smFont8x8);
  888.  
  889. #if _TV_VERSION == 0x0103
  890.                 // Adjust mouse limits if present.  (Fixed in TV 2.0)
  891.                 if(TMouse::present())
  892.                     TMouse::setRange(TScreen::screenWidth - 1,
  893.                         TScreen::screenHeight - 1);
  894. #endif
  895.                 break;
  896.  
  897.             case cmUserScreen:
  898.                 suspend();      // Suspend Turbo Vision and display user
  899.                 if(ScrBuf)      // screen if there is one.
  900.                     puttext(1, 1, 80, 25, ScrBuf);
  901.  
  902.                 getch();        // Wait for keypress and restart Turbo Vision.
  903.                 resume();
  904.                 redraw();
  905.                 break;
  906.  
  907.             case cmColors:
  908.                 c = (TColorDialog *)rsc->get("ColorDlg");
  909.  
  910.                 if(validView(c))
  911.                 {
  912.  
  913. #if _TV_VERSION == 0x0103
  914.  
  915. //* TV 1.03 NOTE: I have found that this is the *proper* way to set up *all*
  916. //* TColorDialog boxes.  If you follow the TVDEMO example, you pass
  917. //* TColorDialog a NULL pointer in its constructor (the palette pointer is
  918. //* also NULL after you restore it from a resource file!).
  919. //* You then call its setData() member to initialize the color set.  The
  920. //* problem is that TColorDialog::setData() does a memcpy() using that NULL
  921. //* pointer.  If you trace into the assembler code at that point, you'll see
  922. //* that it takes the address stored in interrupt zero (the Divide by Zero
  923. //* handler) and copies the palette to that address.  Most of the time you
  924. //* don't know anything is wrong, but I have found cases where it crashes
  925. //* immediately or at some point shortly after that.  Even if it doesn't
  926. //* crash, you are still asking for trouble.  The method below is the only
  927. //* way to get a TColorDialog box to work safely and properly when created
  928. //* at runtime or stored in a resource file.
  929.  
  930.                     TPalette x = getPalette();      // Create temporary
  931.                     c->pal = &x;                    // palette and assign it.
  932.  
  933. // TV 2.0 NOTE: In TV 2.0, this has been fixed.  The above two lines
  934. //              should not be used or a crash will result.
  935. #endif
  936.  
  937.                     c->setData(&getPalette());      // Call setData() with
  938.                                                     // the initial colors.
  939.                     // Execute the color dialog box.
  940.                     if(deskTop->execView(c) != cmCancel)
  941.                     {
  942.                         // Do a straight assignment to get the modified colors.
  943.                         getPalette() = *(c->pal);
  944.  
  945.                         // Repaint the entire desktop by calling
  946.                         // setScreenMode().  Calling deskTop->setState()
  947.                         // to set sfVisible off and then on as in TVDEMO
  948.                         // doesn't always redraw the entire screen if
  949.                         // there is a window or some other view on the
  950.                         // desktop that has the focus.
  951.                         setScreenMode(TScreen::screenMode);
  952.                     }
  953.                     destroy(c);
  954.                 }
  955.                 break;
  956.  
  957.             case cmChangePalettes:
  958.                 CmdLinePalette = appPalette + 1;
  959.  
  960.                 if(CmdLinePalette == apTotalPalettes)
  961.                     CmdLinePalette = apColor;
  962.  
  963.                 setScreenMode(TScreen::screenMode);
  964.                 break;
  965.  
  966.             case cmLoadCfg:
  967.                 if(executeDialog(new TFileDialog(demo_cfg, "Load Configuration",
  968.                   "~N~ame", fdOpenButton, 100), demo_cfg) != cmCancel)
  969.                     loadConfig(True);
  970.                 break;
  971.  
  972.             case cmSaveCfg:
  973.                 if(executeDialog(new TFileDialog(demo_cfg, "Save Configuration",
  974.                   "~N~ame", fdOKButton, 100), demo_cfg) != cmCancel)
  975.                     saveConfig();
  976.                 break;
  977.  
  978.     // Non-standard evCommand events.
  979.  
  980.             case cmNew:
  981.                 openEditor(NULL, True);
  982.                 break;
  983.  
  984.             case cmOpen:
  985.                 char fileName[MAXPATH];
  986.                 strcpy(fileName, "*.");
  987.                 strcat(fileName, TVMEditor::GlobalOpts.DefaultExt);
  988.  
  989.                 openEditor(fileName, True);
  990.                 break;
  991.  
  992.             case cmChDir:
  993.                 executeDialog(new TChDirDialog( cdNormal, 0 ), 0);
  994.                 break;
  995.  
  996.             case cmShowClip:
  997.                 if(clipWindow)
  998.                 {
  999.                     clipWindow->select();
  1000.                     clipWindow->show();
  1001.                 }
  1002.                 break;
  1003.  
  1004.             case cmStartUpOpt:
  1005.                 executeDialog((TDialog *)rsc->get("StartUpDlg"), &StartUpOpts);
  1006. #if !defined(SHAREWARE)
  1007.     #if !defined(__DPMI16__) && !defined(__DPMI32__)
  1008.                 TVirtualMemory::MemoryCheck = StartUpOpts.VirtualMemory;
  1009.     #else
  1010.                 TVirtualMemory::setMaxAllocation(
  1011.                     long(StartUpOpts.MaxAllocatable) * 1024L);
  1012.     #endif
  1013. #endif
  1014. #if defined(CSH_LIBRARY)
  1015.                 // Let the editors know whether to enable or disable
  1016.                 // syntax highlighting.
  1017.                 message(deskTop, evBroadcast, cmCSHOnOff,
  1018.                     (void *)(StartUpOpts.EdOpts & soUseCSH));
  1019. #endif
  1020.                 break;
  1021.  
  1022.             case cmDefaultEditorOpt:    // Set the default editor options.
  1023.                 executeDialog((TDialog *)rsc->get("DefEdOptDlg"), &TVMEditor::GlobalOpts);
  1024.                 break;
  1025.  
  1026.             case cmReplaceKeyMaps:
  1027.                 ReplaceKeyMaps();
  1028.                 break;
  1029.  
  1030.             case cmMemoDemo:
  1031.                 MemoDemo();
  1032.                 break;
  1033.  
  1034.             case cmKeyHelp:
  1035.                 executeDialog((TDialog *)rsc->get("KeyHelp"), NULL);
  1036.                 break;
  1037.  
  1038.             case cmMsgViewer:
  1039.                 // Don't insert more than one viewer.
  1040.                 if(!commandEnabled(cmPrevMsg))
  1041.                     DemoMsgViewer();
  1042.                 break;
  1043.  
  1044.             case cmPrevMsg:
  1045.             case cmNextMsg:
  1046.                 // The application must convert these to broadcast events
  1047.                 // so that the message viewer will see them even when
  1048.                 // it isn't the focused view.
  1049.                 message(deskTop, evBroadcast, event.message.command, NULL);
  1050.                 break;
  1051.  
  1052.             case cmGetSelText:
  1053.                 testGetText();
  1054.                 break;
  1055.  
  1056. #if defined(CSH_LIBRARY)
  1057.             case cmCSHColors:
  1058.                 setCSHColors();
  1059.                 break;
  1060. #endif
  1061.             default:
  1062.                 return;
  1063.         }
  1064.         clearEvent (event);
  1065.     }
  1066. }
  1067.  
  1068. // ****************************************************************************
  1069. //
  1070. // The isTileable() function checks for a visible, tileable view on the
  1071. // desktop.
  1072. //
  1073. Boolean isTileable(TView *p, void *)
  1074. {
  1075.     // Must ignore such objects as the clipboard when they are hidden!
  1076.     if(!(p->options & ofTileable) || !(p->state & sfVisible))
  1077.         return False;
  1078.  
  1079.     return True;
  1080. }
  1081.  
  1082. // ****************************************************************************
  1083. // **** In TV 2.0, TProgram::executeDialog() replaces this.
  1084. // ****
  1085. #if _TV_VERSION == 0x0103
  1086.  
  1087. // This function executes any dialog passed to it and destroys it when done.
  1088. ushort executeDialog(TDialog *d, void *data)
  1089. {
  1090.     TView *p = TProgram::application->validView(d);
  1091.     if(!p)
  1092.         return cmCancel;
  1093.  
  1094.     if(data)
  1095.         p->setData(data);
  1096.  
  1097.     ushort result = TProgram::deskTop->execView(p);
  1098.  
  1099.     if(result != cmCancel && data)
  1100.         p->getData(data);
  1101.  
  1102.     TObject::destroy(p);
  1103.     return result;
  1104. }
  1105.  
  1106. #endif
  1107. // ****************************************************************************
  1108.  
  1109. // ****************************************************************************
  1110. // End of standard front end functions.
  1111. // ****************************************************************************
  1112. // Other functions not in the standard front end file.
  1113.  
  1114. #if defined(CSH_LIBRARY)
  1115. TCSHEditWindow *TVMEditorApp::openEditor(const char *fName, Boolean visible)
  1116. #else
  1117. TVMEditWindow *TVMEditorApp::openEditor(const char *fName, Boolean visible)
  1118. #endif
  1119. {
  1120.     char fileName[MAXPATH] = "";
  1121.  
  1122.     ffblk finfo;
  1123.  
  1124.     // Make a copy of the filename.
  1125.     if(fName)
  1126.         strcpy(fileName, fName);
  1127.  
  1128.     // When not opening an untitled file, check for a directory name or
  1129.     // wildcards.
  1130.     if(fileName[0])
  1131.     {
  1132.         finfo.ff_attrib = 0;
  1133.         findfirst(fileName, &finfo, FA_NORMAL | FA_HIDDEN | FA_SYSTEM |
  1134.             FA_RDONLY | FA_ARCH | FA_DIREC);
  1135.  
  1136.         // If there are no wildcard characters in the filename, see if the
  1137.         // entry is a directory or drive reference only.  If so, append a
  1138.         // default "\*.*" to it.
  1139.         if((!strchr(fileName, '*') && !strchr(fileName, '?') &&
  1140.           (finfo.ff_attrib & FA_DIREC)) ||
  1141.           (fileName[1] == ':' && !fileName[2]) ||
  1142.            fileName[strlen(fileName) - 1] == '\\')
  1143.         {
  1144.             // Strip any existing trailing backslash?
  1145.             if(fileName[strlen(fileName) - 1] == '\\')
  1146.                 fileName[strlen(fileName) - 1] = EOS;
  1147.  
  1148.             strcat(fileName, "\\*.*");
  1149.         }
  1150.  
  1151.         // Wildcard?  If so, prompt for a real name.
  1152.         if(strchr(fileName, '*') || strchr(fileName, '?'))
  1153.             if(executeDialog(new TFileDialog(fileName, "Open file",
  1154.               "~N~ame", fdOpenButton, 100), fileName) == cmCancel)
  1155.                 return NULL;
  1156.     }
  1157.  
  1158.     // Got a filename or null (untitled file), so open it.
  1159.     TRect r = deskTop->getExtent();
  1160.  
  1161.     // Indent each window's upper border so that the titles of all loaded
  1162.     // files stay visible.  This is only done when there are other windows
  1163.     // open.  If no other windows are open, the new one is always full size.
  1164.     if(message(deskTop, evBroadcast, cmEditorPresent, NULL))
  1165.     {
  1166.         r.a.y += winIndent;
  1167.         if(++winIndent > 11)
  1168.             winIndent = 0;
  1169.     }
  1170.     else                  // Take the opportunity to reset the indent
  1171.         winIndent = 1;    // for the next window opened.
  1172.  
  1173. #if defined(CSH_LIBRARY)
  1174.     TCSHEditWindow *p = (TCSHEditWindow *)validView(new TCSHEditWindow(r,
  1175.       fileName, wnNoNumber, Boolean((StartUpOpts.EdOpts & soIndicAtTop) != 0),
  1176.       StartUpOpts.bufSizeInK));
  1177.  
  1178.     if(p)
  1179.         p->editor->setOption(efUseCSH,
  1180.           Boolean((StartUpOpts.EdOpts & soUseCSH) != 0));
  1181. #else
  1182.     TVMEditWindow *p = (TVMEditWindow *)validView(new TVMEditWindow(r,
  1183.       fileName, wnNoNumber, Boolean((StartUpOpts.EdOpts & soIndicAtTop) != 0),
  1184.       StartUpOpts.bufSizeInK));
  1185. #endif
  1186.  
  1187.     if(p)
  1188.     {
  1189.         // To conserve some memory, TVMEditWindow turns off buffering.
  1190.         // If screen flicker is a problem on your system when using the
  1191.         // edit window, uncoment this line:
  1192.         // p->options |= ofBuffered;
  1193.  
  1194.         if(!visible)
  1195.             p->hide();
  1196.  
  1197.         deskTop->insert(p);
  1198.     }
  1199.     return p;
  1200. }
  1201.  
  1202. // ****************************************************************************
  1203. // End of standard front end file.
  1204. // ****************************************************************************
  1205.