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

  1. // File    : TVEDIT2.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. // More functions for the TVMEditor demo program.
  8. //
  9.  
  10. #include <ctype.h>
  11. #include <dir.h>
  12. #include <io.h>
  13. #include <stdarg.h>
  14. #include <string.h>
  15.  
  16. #define Uses_MsgBox
  17. #define Uses_TApplication
  18. #define Uses_TColorDialog
  19. #define Uses_TColorGroup
  20. #define Uses_TColorItem
  21. #define Uses_TDeskTop
  22. #define Uses_TFileDialog
  23. #define Uses_TKeys
  24. #define Uses_TMenuBar
  25. #define Uses_TProgram
  26. #define Uses_TResourceFile
  27. #define Uses_TScreen
  28. #define Uses_TStatusLine
  29. #define Uses_TVCOLR             // Use this if you modified the TV.H file.
  30. #define Uses_fpstream
  31. #include <tv.h>
  32.  
  33. #if !defined(cpDefSize)
  34. // Use this if you chose not to modify the Turbo Vision files.
  35. #include <tvcolr.h>
  36. #endif
  37.  
  38. #if !defined(SHAREWARE)
  39. #define Uses_TVirtualMemory
  40. #endif
  41. #define Uses_TVMEditWindow
  42. #define Uses_TVMMemo
  43. #include <tvmedit.h>
  44.  
  45. #if defined(CSH_LIBRARY)
  46. #define Uses_TCSHEditor
  47. #include <cshedit.h>        // For the Color Syntax Highlighter.
  48. #endif
  49.  
  50. #define Uses_TMsgViewWindow
  51. #include <tmsgview.h>
  52.  
  53. #define Uses_TVMEditorApp
  54. #include "tvedit.h"
  55.  
  56. extern TPoint shadowSize;   // Altered when screen size changes.
  57.  
  58. extern TResourceFile *rsc;
  59. extern StartUp StartUpOpts;
  60. extern DemoData Demo;
  61.  
  62. extern char demo_cfg[MAXPATH];
  63. extern short CmdLinePalette;
  64.  
  65. // ****************************************************************************
  66. // More standard front end functions.  Modify as needed.
  67.  
  68. //
  69. // Desktop initialization.
  70. //
  71. TDeskTop *TVMEditorApp::initDeskTop(TRect r)
  72. {
  73.     // Prevent drawing the desktop until the colors are set correctly.
  74.     TProgram::application->setState(sfExposed, False);
  75.  
  76.     r.a.y++;
  77.     r.b.y--;
  78.     return new TDeskTop(r);
  79. }
  80.  
  81. //
  82. // Screen initialization.  This is overridden so that a command line
  83. // specified color palette can be used.  If not, the default initScreen()
  84. // will reset the palette based on monitor type every time it is called.
  85. //
  86. void TVMEditorApp::initScreen()
  87. {
  88.     TProgram::initScreen();
  89.  
  90.     // Force palette to equal the user-specified palette.
  91.     if(CmdLinePalette > -1 && TApplication::appPalette != CmdLinePalette)
  92.     {
  93.         TApplication::appPalette = CmdLinePalette;
  94.  
  95.         // If monochrome, turn off shadows and turn on markers.
  96.         if(CmdLinePalette == apMonochrome)
  97.         {
  98.             shadowSize.x = 0;
  99.             shadowSize.y = 0;
  100.             showMarkers = True;
  101.         }
  102.     }
  103. }
  104.  
  105. //
  106. // Menubar initialization.
  107. //
  108. TMenuBar *TVMEditorApp::initMenuBar(TRect)
  109. {
  110.     TMenuBar *menuBar = (TMenuBar *)rsc->get("MenuBar");
  111.  
  112.     // Set menubar width in case the application starts up in anything other
  113.     // than a screen mode of 80x25 lines.
  114.     menuBar->size.x = TScreen::screenWidth;
  115.  
  116.     return menuBar;
  117. }
  118.  
  119. //
  120. // Create statusline.
  121. //
  122. TStatusLine *TVMEditorApp::initStatusLine( TRect )
  123. {
  124.     TStatusLine *statLine = (TStatusLine *)rsc->get("StatusLine");
  125.  
  126.     // Set status line width and position in case the application starts up
  127.     // in anything other than a screen mode of 80x25 lines.
  128.     statLine->origin.y = TScreen::screenHeight - 1;
  129.     statLine->size.x = TScreen::screenWidth;
  130.  
  131.     return statLine;
  132. }
  133.  
  134. // Standard Out Of Memory error dialog.
  135. void TVMEditorApp::outOfMemory(void)
  136. {
  137.     messageBox("Not enough memory for this operation.", mfError | mfCancelButton);
  138. }
  139.  
  140. //
  141. // Standard load config file.  Modify as needed.
  142. //
  143. void TVMEditorApp::loadConfig(Boolean UseFileSetting)
  144. {
  145.     fpstream *f = new fpstream(demo_cfg, ios::in | ios::nocreate | ios::binary);
  146.  
  147.     if(!f->good())
  148.     {
  149.         //  Turn on the screen?
  150.         if(!(state & sfExposed))
  151.         {
  152.             setScreenMode(TScreen::screenMode);
  153.  
  154. #if _TV_VERSION == 0x0103       // Fixed in TV 2.0.
  155.             if(TMouse::present())       // Adjust mouse limits if present.
  156.                 TMouse::setRange(TScreen::screenWidth - 1,
  157.                     TScreen::screenHeight - 1);
  158. #endif
  159.         }
  160.  
  161.         messageBox(mfError | mfCancelButton,
  162.             "Could not open configuration file: %s", demo_cfg);
  163.  
  164.         delete f;
  165.         return;
  166.     }
  167.  
  168.     ipstream &strm = *f;
  169.  
  170.     // Read palettes from the configuration file.
  171.     short curr_palette = appPalette;
  172.     for(short i = 0; i < apTotalPalettes; i++)
  173.     {
  174.         appPalette = i;
  175.         TPalette *palette = &getPalette();
  176.         strm.readBytes(palette->data, palette->data[0] + 1);
  177.     }
  178.     appPalette = curr_palette;
  179.  
  180.     // Get the video mode
  181.     ushort scrMode;
  182.     strm.readBytes(&scrMode, sizeof(scrMode));
  183.  
  184.     // Get the palette that was in use.
  185.     short usePalette;
  186.     strm.readBytes(&usePalette, sizeof(usePalette));
  187.  
  188.     // If not overridden from the command line, set the palette.
  189.     if(CmdLinePalette == -1 || (CmdLinePalette != -1 && UseFileSetting))
  190.         CmdLinePalette = usePalette;
  191.  
  192.     setScreenMode(scrMode);
  193.  
  194. #if _TV_VERSION == 0x0103   // Fixed in TV 2.0.
  195.     if(TMouse::present())       // Adjust mouse limits if present.
  196.         TMouse::setRange(TScreen::screenWidth - 1, TScreen::screenHeight - 1);
  197. #endif
  198.  
  199.     // ************************************************************************
  200.     // Add code here to load non-standard application-specific config data.
  201.     strm.readBytes(&StartUpOpts, sizeof(StartUp));
  202.     strm.readBytes(&TVMEditor::GlobalOpts, sizeof(GlobalEditorOptions));
  203.  
  204.     // Set memory preference based on user selection.
  205. #if !defined(SHAREWARE)
  206.     #if !defined(__DPMI16__) && !defined(__DPMI32__)
  207.         TVirtualMemory::MemoryCheck = StartUpOpts.VirtualMemory;
  208.     #else
  209.         TVirtualMemory::setMaxAllocation(
  210.             long(StartUpOpts.MaxAllocatable) * 1024L);
  211.     #endif
  212. #endif
  213.  
  214.     delete f;
  215. }
  216.  
  217. //
  218. // Standard save config file.  Modify as needed.
  219. //
  220. void TVMEditorApp::saveConfig(void)
  221. {
  222.     fpstream *f = new fpstream(demo_cfg, ios::trunc | ios::binary);
  223.  
  224.     if(!f->good())
  225.     {
  226.         messageBox(mfError | mfCancelButton,
  227.             "Could not open configuration file: %s", demo_cfg);
  228.  
  229.         delete f;
  230.         return;
  231.     }
  232.  
  233.     opstream &strm = *f;
  234.  
  235.     // Store the palettes
  236.     short curr_palette = appPalette;
  237.     for(short i = 0; i < apTotalPalettes; i++)
  238.     {
  239.         appPalette = i;
  240.         TPalette *palette = &getPalette();
  241.         strm.writeBytes(palette->data, palette->data[0] + 1);
  242.     }
  243.     appPalette = curr_palette;
  244.  
  245.     // Store current video mode
  246.     strm.writeBytes(&TScreen::screenMode, sizeof(TScreen::screenMode));
  247.  
  248.     // Store current palette in use.
  249.     strm.writeBytes(&appPalette, sizeof(appPalette));
  250.  
  251.     // ************************************************************************
  252.     // Add code here to save non-standard application-specific config data.
  253.     strm.writeBytes(&StartUpOpts, sizeof(StartUp));
  254.     strm.writeBytes(&TVMEditor::GlobalOpts, sizeof(GlobalEditorOptions));
  255.  
  256.     delete f;
  257. }
  258.  
  259. // ****************************************************************************
  260. // More functions not in the standard front end.
  261.  
  262. void TVMEditorApp::saveDeskTop(void)
  263. {
  264.     // We'll assume that only editor windows are on the desktop for the demo.
  265.     TVMEditWindow *win;
  266.  
  267. #if defined(__DPMI16__)
  268.     fpstream *f = new fpstream("TVEDIT16.TVD", ios::out | ios::trunc | ios::binary);
  269. #else
  270.     #if defined(__DPMI32__)
  271.         fpstream *f = new fpstream("TVEDIT32.TVD", ios::out | ios::trunc | ios::binary);
  272.     #else
  273.         fpstream *f = new fpstream("TVEDIT.TVD", ios::out | ios::trunc | ios::binary);
  274.     #endif
  275. #endif
  276.  
  277.     if(f->good())
  278.     {
  279.         while((win = (TVMEditWindow *)deskTop->firstThat(isTileable, 0)) != NULL)
  280.         {
  281.             *f << win;
  282.             message(win, evCommand, cmClose, NULL);
  283.         }
  284.         *f << NULL;
  285.  
  286.         if(!f->good())
  287.             messageBox("Error saving desktop!", mfError | mfCancelButton);
  288.     }
  289.     else
  290.         messageBox("Error creating desktop file!", mfError | mfCancelButton);
  291.  
  292.     delete f;
  293. }
  294.  
  295. void TVMEditorApp::restoreDeskTop(void)
  296. {
  297.     TView *p;
  298.  
  299. #if defined(__DPMI16__)
  300.     fpstream *f = new fpstream("TVEDIT16.TVD", ios::in | ios::nocreate | ios::binary);
  301. #else
  302.     #if defined(__DPMI32__)
  303.         fpstream *f = new fpstream("TVEDIT32.TVD", ios::in | ios::nocreate | ios::binary);
  304.     #else
  305.         fpstream *f = new fpstream("TVEDIT.TVD", ios::in | ios::nocreate | ios::binary);
  306.     #endif
  307. #endif
  308.  
  309.     if(f->good())
  310.     {
  311.         do
  312.         {
  313.             *f >> p;
  314.             deskTop->insertBefore(validView(p), deskTop->last);
  315.  
  316.         } while(p != 0);
  317.  
  318.         if(!f->good())
  319.             messageBox("Error restoring desktop!", mfError | mfCancelButton);
  320.     }
  321.     else
  322.         messageBox("Error opening desktop file!", mfError | mfCancelButton);
  323.  
  324.     delete f;
  325. }
  326.  
  327. // ****************************************************************************
  328. void TVMEditorApp::ReplaceKeyMaps(void)
  329. {
  330.     static Boolean isSwitched = False;
  331.  
  332.     // Demo of replaceable key maps.  Toggle between full set and this
  333.     // replacement set of movement keys only.
  334.     static const ushort NewSingleKeys[] =
  335.     {
  336.         kbCtrlX,     0xFF05,         // Additional set of two-key commands.
  337.         kbLeft,      cmCharLeft,     // Movement only.
  338.         kbRight,     cmCharRight,
  339.         kbCtrlLeft,  cmWordLeft,
  340.         kbCtrlRight, cmWordRight,
  341.         kbHome,      cmLineStart,
  342.         kbEnd,       cmLineEnd,
  343.         kbUp,        cmLineUp,
  344.         kbDown,      cmLineDown,
  345.         kbCtrlW,     cmShiftUp,
  346.         kbCtrlZ,     cmShiftDown,
  347.         kbPgUp,      cmPageUp,
  348.         kbPgDn,      cmPageDown,
  349.         kbCtrlHome,  cmWindowTop,
  350.         kbCtrlEnd,   cmWindowBotm,
  351.         kbCtrlPgUp,  cmTextStart,
  352.         kbCtrlPgDn,  cmTextEnd,
  353.         0
  354.     };
  355.  
  356.     // Demo: Ctrl X, 0xFF05
  357.     static const ushort MyCtrlXKeys[] =
  358.     {
  359.         'G', cmGotoLine,        // Just for demonstration purposes.
  360.         'V', cmPrevPos,
  361.         'L', cmLastChg,
  362.         0
  363.     };
  364.  
  365.     if(isSwitched)
  366.     {
  367.         // Switch back to the full set of editing keys.
  368.         TVMEditor::changeKeyMap(0, NULL);
  369.         TVMEditor::changeKeyMap(5, NULL);
  370.         isSwitched = False;
  371.  
  372.         messageBox("Now using the default editor key assignments.",
  373.             mfInformation | mfOKButton);
  374.     }
  375.     else
  376.     {
  377.         // Replace the default single key command map and add a new map
  378.         // for the Ctrl+X key map.
  379.         TVMEditor::changeKeyMap(0, &NewSingleKeys[0]);
  380.         TVMEditor::changeKeyMap(5, &MyCtrlXKeys[0]);
  381.         isSwitched = True;
  382.  
  383.         messageBox("Only movement keys and text insertion will be recognized now.  "
  384.             "Select option again to restore defaults.",
  385.             mfInformation | mfOKButton);
  386.     }
  387. }
  388.  
  389. void TVMEditorApp::MemoDemo(void)
  390. {
  391.     // Structure for the dialog box.
  392.     struct
  393.     {
  394.         TVMMemoData Memo1;
  395.         TVMMemoData Memo2;
  396.     } DialogData;
  397.  
  398.     DialogData.Memo1.length = 255;                  // Maximum size.
  399.     DialogData.Memo1.buffer = &Demo.ShortText[0];   // Point to the text.
  400.     DialogData.Memo1.copyCount = Demo.Size1;        // Current size.
  401.  
  402.     DialogData.Memo2.length = 1024;
  403.     DialogData.Memo2.buffer = &Demo.LongText[0];
  404.     DialogData.Memo2.copyCount = Demo.Size2;
  405.  
  406.     // Use a different editorDialog() handler to take care of TVMMemo
  407.     // interaction with the user.
  408.     TVMEditor::editorDialog = doMemoEditDialog;
  409.  
  410.     // Execute the dialog box.  The executeDialog() function takes care of
  411.     // setting and getting the data using the temporary structure.
  412.     if(executeDialog((TDialog *)rsc->get("MemoDemo"), &DialogData) == cmOK)
  413.     {
  414.         // If OK was pressed, update the demo structure memo lengths.
  415.         // The memo text will have been updated already because the
  416.         // addresses were passed to the dialog in the DialogData structure.
  417.         Demo.Size1 = DialogData.Memo1.copyCount;
  418.         Demo.Size2 = DialogData.Memo2.copyCount;
  419.     }
  420.  
  421.     // Now switch back to the original editorDialog() handler.
  422.     TVMEditor::editorDialog = doEditDialog;
  423. }
  424.  
  425. void TVMEditorApp::DemoMsgViewer(void)
  426. {
  427.     TRect r = deskTop->getExtent();       // Create new one.
  428.     r.a.y = r.b.y - 7;
  429.  
  430.     TMsgViewWindow *msg = new TMsgViewWindow(r, "Demo Message Viewer");
  431.  
  432.     if(!validView(msg))
  433.         return;
  434.  
  435.     msg->insertMsg(0, "Use Alt+F7/Alt+F8 to jump backward/forward when not in this window");
  436.     msg->insertMsg(10, "Jump to line 10");
  437.     msg->insertMsg(20, "Jump to line 20");
  438.     msg->insertMsg(30, "Jump to line 30");
  439.     msg->insertMsg(100, "Jump to line 100");
  440.     msg->insertMsg(110, "Jump to line 110");
  441.     msg->insertMsg(120, "Jump to line 120");
  442.  
  443.     deskTop->insert(msg);
  444. }
  445.  
  446. // ****************************************************************************
  447. // This is for the Color Syntax Highlighter.  It allows you to alter the
  448. // colors for the topmost view that is using CSH (if there is one).
  449.  
  450. #if defined(CSH_LIBRARY)
  451. void TVMEditorApp::setCSHColors(void)
  452. {
  453.     char colors[csMaxGroups];
  454.     char *colorPalette[] = { "Color", "Black & White", "Monochrome",
  455.         "Alt. Color" };
  456.  
  457.     // There's nobody to work with.
  458.     if(!message(deskTop, evBroadcast, cmCSHGetColors, colors))
  459.         return;
  460.  
  461.     TColorGroup &group1 =
  462.         *new TColorGroup(colorPalette[appPalette]) +
  463.             *new TColorItem("Group A",        1)+
  464.             *new TColorItem("Group B",        2)+
  465.             *new TColorItem("Group C",        3)+
  466.             *new TColorItem("Group D",        4)+
  467.             *new TColorItem("Group E",        5)+
  468.             *new TColorItem("Group F",        6)+
  469.             *new TColorItem("Group G",        7)+
  470.             *new TColorItem("Group H",        8)+
  471.             *new TColorItem("Group I",        9)+
  472.             *new TColorItem("Group J",       10)+
  473.             *new TColorItem("Group K",       11)+
  474.             *new TColorItem("Group L",       12)+
  475.             *new TColorItem("Group M",       13)+
  476.             *new TColorItem("Group N",       14)+
  477.             *new TColorItem("Group O",       15)+
  478.             *new TColorItem("Group P",       16);
  479.  
  480.     TPalette *pal = new TPalette(colors, csMaxGroups);
  481.  
  482.     TColorDialog *c = new TColorDialog(pal, &group1);
  483.  
  484.     if(validView(c))
  485.     {
  486.         // Execute the color dialog box.
  487.         if(deskTop->execView(c) != cmCancel)
  488.         {
  489.             *pal = *(c->pal);
  490.  
  491.             memcpy(colors, &pal->data[1], csMaxGroups);
  492.             message(deskTop, evBroadcast, cmCSHSetColors, colors);
  493.  
  494.             // Repaint the entire desktop by calling
  495.             // setScreenMode().  Calling deskTop->setState()
  496.             // to set sfVisible off and then on as in TVDEMO
  497.             // doesn't always redraw the entire screen if
  498.             // there is a window or some other view on the
  499.             // desktop that has the focus.
  500.             setScreenMode(TScreen::screenMode);
  501.  
  502.             // If allowed, save the colors to the defaults file for
  503.             // permanent use.
  504.             if(messageBox("Save color set to defaults file?",
  505.               mfConfirmation | mfYesNoCancel) == cmYes)
  506.                 message(deskTop, evBroadcast, cmCSHSaveColors, NULL);
  507.         }
  508.         destroy(c);
  509.     }
  510.     delete pal;
  511. }
  512.  
  513. #endif
  514. // ****************************************************************************
  515.  
  516. // If you replace the default editor dialog function, be sure to check for
  517. // all possible cases that your application will need!
  518. //
  519. // This one is the general editor dialog handler for the TVMEditWindows.
  520. //
  521. ushort doEditDialog(int dialog, ...)
  522. {
  523.     va_list arg;
  524.     char  *fname, *ln;
  525.     short  size;
  526.     ushort result = cmCancel;       // Default to cancel in case undefined.
  527.  
  528.     va_start(arg, dialog);
  529.  
  530.     switch(dialog)
  531.     {
  532.         case edOutOfMemory:
  533.             messageBox("Not enough memory to complete operation",
  534.                 mfError | mfCancelButton );
  535.             break;
  536.  
  537.         case edReadError:       // Passes a char * to the name of the file.
  538.             messageBox(mfError | mfCancelButton,
  539.                 "Error reading file %s", (char *)va_arg(arg, char *));
  540.             break;
  541.  
  542.         case edWriteError:      // Passes a char * to the name of the file.
  543.             messageBox(mfError | mfCancelButton,
  544.                 "Error writing to %s", (char *)va_arg(arg, char *));
  545.             break;
  546.  
  547.         case edCreateError:     // Passes a char * to the name of the file.
  548.             messageBox(mfError | mfCancelButton,
  549.                 "Error creating file %s", (char *)va_arg(arg, char *));
  550.             break;
  551.  
  552.         case edSwapBadSeek:
  553.             messageBox("ERROR: Bad seek on swap file!", mfError | mfCancelButton);
  554.             break;
  555.  
  556.         case edSwapFileFail:
  557.             messageBox("ERROR: Could not read/write swap file!", mfError | mfCancelButton);
  558.             break;
  559.  
  560.         case edEMSXMSFailure:   // Passes a short value for the error code.
  561.             messageBox(mfError | mfCancelButton,
  562.                 "ERROR: EMS/XMS handler error code #%#x received",
  563.                 (short)va_arg(arg, short));
  564.             break;
  565.  
  566.         // Used by the diagnostic checks within the editor and virtual
  567.         // memory manager.  Also used by TVMMemo::valid() if the
  568.         // memo text is too long.  Passes a char * to the message string.
  569.         case edGeneralMsg:
  570.             messageBox(va_arg(arg, char *), mfInformation | mfCancelButton);
  571.             break;
  572.  
  573.         case edLinesSplit:
  574.             messageBox("Long lines were split when loaded", mfInformation | mfOKButton);
  575.             break;
  576.  
  577.         case edLineTooLong:
  578.             messageBox("Line would be too long", mfInformation | mfCancelButton);
  579.             break;
  580.  
  581.         case edGotoLine:
  582.             // The input is *text* so that + or - can be used!
  583.             // Absence of the + or - means a literal line number.
  584.             // Passes a char * to the buffer and a short for the
  585.             // maximum size of the string.
  586.             ln = (char *)va_arg(arg, char *);
  587.             size = (short)va_arg(arg, short);
  588.             result = inputBox("Goto/Jump", "Line number or +nnn/-nnn:",
  589.                 ln, size);
  590.             break;
  591.  
  592.         case edChgLocalOpts:    // Passes addr of LocalEditorOptions structure
  593. #if _TV_VERSION == 0x0103
  594.             result = executeDialog((TDialog *)rsc->get("LclEdOptDlg"), va_arg(arg, char *));
  595. #else
  596.             result = TProgram::application->executeDialog((TDialog *)rsc->get("LclEdOptDlg"), va_arg(arg, char *));
  597. #endif
  598.             break;
  599.  
  600.         case edFind:            // Passes addr of TVMFindDialogRec structure
  601. #if _TV_VERSION == 0x0103
  602.             result = executeDialog((TDialog *)rsc->get("FindDialog"), va_arg(arg, char *));
  603. #else
  604.             result = TProgram::application->executeDialog((TDialog *)rsc->get("FindDialog"), va_arg(arg, char *));
  605. #endif
  606.             break;
  607.  
  608.         case edReplace:         // Passes addr of TVMReplaceDialogRec structure
  609.             // NOTE:  If the Replace Dialog returns cmYes, *ALL* occurances
  610.             //        will be replaced, not just the first one.  This was
  611.             //        easier than using a new command and deriving a dialog
  612.             //        box class that could return a non-standard value.  The
  613.             //        TVMEditor classes will look specifically for cmYes to
  614.             //        enable the Change All option for search and replace
  615.             //        operations.  If cmOK is returned, only the first
  616.             //        occurance will be replaced.
  617. #if _TV_VERSION == 0x0103
  618.             result = executeDialog((TDialog *)rsc->get("ReplaceDialog"), va_arg(arg, char *));
  619. #else
  620.             result = TProgram::application->executeDialog((TDialog *)rsc->get("ReplaceDialog"), va_arg(arg, char *));
  621. #endif
  622.             break;
  623.  
  624.         case edReplacePrompt:
  625.         {
  626.             // Avoid placing the dialog on the same line as the cursor.
  627.             TRect r(0, 1, 40, 8);
  628.             r.move((TProgram::deskTop->size.x - r.b.x) / 2, 0);
  629.             TPoint t = TProgram::deskTop->makeGlobal(r.b);
  630.             t.y++;
  631.  
  632.             // Passes a pointer to the *screen* cursor position.  This is a
  633.             // normal TPoint not a TVMPoint!
  634.             TPoint *pt = (TPoint *)va_arg(arg, char *);
  635.  
  636.             if(pt->y <= t.y)
  637.                 r.move(0, TProgram::deskTop->size.y - r.b.y - 2);
  638.  
  639.             result = messageBoxRect(r, "Replace this occurance?",
  640.                 mfInformation | mfYesNoCancel);
  641.             break;
  642.         }
  643.  
  644.         case edSearchFailed:
  645.             messageBox("Search string not found.", mfInformation | mfOKButton);
  646.             break;
  647.  
  648.         case edReadBlock:       // Passes char * to a filename buffer
  649. #if _TV_VERSION == 0x0103
  650.             result = executeDialog(new TFileDialog("*.*", "Read text from",
  651.                 "~N~ame", fdOpenButton, 101), va_arg(arg, char *));
  652. #else
  653.             result = TProgram::application->executeDialog(new TFileDialog("*.*", "Read text from",
  654.                 "~N~ame", fdOpenButton, 101), va_arg(arg, char *));
  655. #endif
  656.             break;
  657.  
  658.         case edSaveBlock:       // Passes char * to a filename buffer
  659.             fname = (char *)va_arg(arg, char *);
  660.  
  661. #if _TV_VERSION == 0x0103
  662.             result = executeDialog(new TFileDialog("*.*", "Save block to",
  663.                 "~N~ame", fdOKButton, 101), fname);
  664. #else
  665.             result = TProgram::application->executeDialog(new TFileDialog("*.*", "Save block to",
  666.                 "~N~ame", fdOKButton, 101), fname);
  667. #endif
  668.             if(result != cmCancel && !access(fname, 0))
  669.                 result = messageBox(mfConfirmation | mfYesNoCancel,
  670.                     "%s already exists.  OVERWRITE?", fname);
  671.             break;
  672.  
  673.         case edSaveAs:          // Passes char * to a filename buffer
  674.             fname = (char *)va_arg(arg, char *);
  675.  
  676. #if _TV_VERSION == 0x0103
  677.             result = executeDialog(new TFileDialog("*.*", "Save file as",
  678.                 "~N~ame", fdOKButton, 101), fname);
  679. #else
  680.             result = TProgram::application->executeDialog(new TFileDialog("*.*", "Save file as",
  681.                 "~N~ame", fdOKButton, 101), fname);
  682. #endif
  683.             if(result != cmCancel && !access(fname, 0))
  684.                 result = messageBox(mfConfirmation | mfYesNoCancel,
  685.                     "%s already exists.  OVERWRITE?", fname);
  686.             break;
  687.  
  688.         case edSaveUntitled:
  689.             result = messageBox("Save untitled file?",
  690.                 mfConfirmation | mfYesNoCancel);
  691.             break;
  692.  
  693.         case edSaveModify:      // Passes char * to the name of the file.
  694.             result = messageBox(mfConfirmation | mfYesNoCancel,
  695.                 "%s has been modified.  Save?", (char *)va_arg(arg, char *));
  696.             break;
  697.  
  698.         case edReSynch:         // Passes char * to the name of the file.
  699.             result = messageBox(mfInformation | mfYesButton | mfNoButton,
  700.                 "The copy of %s on disk is different from the one in memory."
  701.                 "  Reload from disk?", (char *)va_arg(arg, char *));
  702.             break;
  703.     }
  704.     va_end(arg);
  705.  
  706.     return result;
  707. }
  708.  
  709. //
  710. // This one is the general editor dialog handler for the TVMMemos.
  711. // It will ignore edSaveAs, edSaveUntitled, and edSaveModify requests
  712. // which only pertain to TVMFileEditors.  The other I/O type events
  713. // may still be used when using the write block/read block features.
  714. // It can be made to ignore other events as you need by removing the
  715. // necessary case statements.
  716. //
  717. ushort doMemoEditDialog(int dialog, ...)
  718. {
  719.     va_list arg;
  720.     char  *fname, *ln;
  721.     short  size;
  722.     ushort result = cmCancel;       // Default to cancel in case undefined.
  723.  
  724.     va_start(arg, dialog);
  725.  
  726.     switch(dialog)
  727.     {
  728.         case edOutOfMemory:
  729.             messageBox("Not enough memory to complete operation",
  730.                 mfError | mfCancelButton );
  731.             break;
  732.  
  733.         case edReadError:       // Passes a char * to the name of the file.
  734.             messageBox(mfError | mfCancelButton,
  735.                 "Error reading file %s", (char *)va_arg(arg, char *));
  736.             break;
  737.  
  738.         case edWriteError:      // Passes a char * to the name of the file.
  739.             messageBox(mfError | mfCancelButton,
  740.                 "Error writing file %s", (char *)va_arg(arg, char *));
  741.             break;
  742.  
  743.         case edCreateError:     // Passes a char * to the name of the file.
  744.             messageBox(mfError | mfCancelButton,
  745.                 "Error creating file %s", (char *)va_arg(arg, char *));
  746.             break;
  747.  
  748.         case edSwapBadSeek:
  749.             messageBox("ERROR: Bad seek on swap file!", mfError | mfCancelButton);
  750.             break;
  751.  
  752.         case edSwapFileFail:
  753.             messageBox("ERROR: Could not read/write swap file!", mfError | mfCancelButton);
  754.             break;
  755.  
  756.         case edEMSXMSFailure:   // Passes a short value for the error code.
  757.             messageBox(mfError | mfCancelButton,
  758.                 "ERROR: EMS/XMS handler error code #%#x received",
  759.                 (short)va_arg(arg, short));
  760.             break;
  761.  
  762.         // Used by the diagnostic checks within the editor and virtual
  763.         // memory manager.  Also used by TVMMemo::valid() if the
  764.         // memo text is too long.  Passes a char * to the message string.
  765.         case edGeneralMsg:
  766.             messageBox(va_arg(arg, char *), mfInformation | mfCancelButton);
  767.             break;
  768.  
  769.         case edLinesSplit:
  770.             messageBox("Long lines were split when loaded", mfInformation | mfOKButton);
  771.             break;
  772.  
  773.         case edLineTooLong:
  774.             messageBox("Line would be too long", mfInformation | mfCancelButton);
  775.             break;
  776.  
  777.         case edGotoLine:
  778.             // The input is *text* so that + or - can be used!
  779.             // Absence of the + or - means a literal line number.
  780.             // Passes a char * to the buffer and a short for the
  781.             // maximum size of the string.
  782.             ln = (char *)va_arg(arg, char *);
  783.             size = (short)va_arg(arg, short);
  784.             result = inputBox("Goto/Jump", "Line number or +nnn/-nnn:",
  785.                 ln, size);
  786.             break;
  787.  
  788.         case edChgLocalOpts:    // Passes addr of LocalEditorOptions structure
  789. #if _TV_VERSION == 0x0103
  790.             result = executeDialog((TDialog *)rsc->get("LclEdOptDlg"), va_arg(arg, char *));
  791. #else
  792.             result = TProgram::application->executeDialog((TDialog *)rsc->get("LclEdOptDlg"), va_arg(arg, char *));
  793. #endif
  794.             break;
  795.  
  796.         case edFind:            // Passes addr of TVMFindDialogRec structure
  797. #if _TV_VERSION == 0x0103
  798.             result = executeDialog((TDialog *)rsc->get("FindDialog"), va_arg(arg, char *));
  799. #else
  800.             result = TProgram::application->executeDialog((TDialog *)rsc->get("FindDialog"), va_arg(arg, char *));
  801. #endif
  802.             break;
  803.  
  804.         case edReplace:         // Passes addr of TVMReplaceDialogRec structure
  805. #if _TV_VERSION == 0x0103
  806.             result = executeDialog((TDialog *)rsc->get("ReplaceDialog"), va_arg(arg, char *));
  807. #else
  808.             result = TProgram::application->executeDialog((TDialog *)rsc->get("ReplaceDialog"), va_arg(arg, char *));
  809. #endif
  810.             break;
  811.  
  812.         case edReplacePrompt:
  813.         {
  814.             // Avoid placing the dialog on the same line as the cursor.
  815.             TRect r(0, 1, 40, 8);
  816.             r.move((TProgram::deskTop->size.x - r.b.x) / 2, 0);
  817.             TPoint t = TProgram::deskTop->makeGlobal(r.b);
  818.             t.y++;
  819.  
  820.             // Passes a pointer to the *screen* cursor position.  This is a
  821.             // normal TPoint not a TVMPoint!
  822.             TPoint *pt = (TPoint *)va_arg(arg, char *);
  823.  
  824.             if(pt->y <= t.y)
  825.                 r.move(0, TProgram::deskTop->size.y - r.b.y - 2);
  826.  
  827.             result = messageBoxRect(r, "Replace this occurance?",
  828.                 mfYesNoCancel | mfInformation);
  829.             break;
  830.         }
  831.  
  832.         case edSearchFailed:
  833.             messageBox("Search string not found.", mfInformation | mfOKButton);
  834.             break;
  835.  
  836.         case edReadBlock:       // Passes char * to a filename buffer
  837. #if _TV_VERSION == 0x0103
  838.             result = executeDialog(new TFileDialog("*.*", "Read text from",
  839.                 "~N~ame", fdOpenButton, 101), va_arg(arg, char *));
  840. #else
  841.             result = TProgram::application->executeDialog(new TFileDialog("*.*", "Read text from",
  842.                 "~N~ame", fdOpenButton, 101), va_arg(arg, char *));
  843. #endif
  844.             break;
  845.  
  846.         case edSaveBlock:       // Passes char * to a filename buffer
  847.             fname = (char *)va_arg(arg, char *);
  848.  
  849. #if _TV_VERSION == 0x0103
  850.             result = executeDialog(new TFileDialog("*.*", "Save block to",
  851.                 "~N~ame", fdOKButton, 101), fname);
  852. #else
  853.             result = TProgram::application->executeDialog(new TFileDialog("*.*", "Save block to",
  854.                 "~N~ame", fdOKButton, 101), fname);
  855. #endif
  856.             if(result != cmCancel && !access(fname, 0))
  857.                 result = messageBox(mfConfirmation | mfYesNoCancel,
  858.                     "%s already exists.  OVERWRITE?", fname);
  859.             break;
  860.     }
  861.     va_end(arg);
  862.  
  863.     return result;
  864. }
  865.