home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 26
/
CD_ASCQ_26_1295.iso
/
vrac
/
tvme30.zip
/
TVEDIT1.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-02
|
42KB
|
1,205 lines
// File : TVEDIT1.CPP
// Author : Eric Woodruff, CIS ID: 72134,1150
// Updated : Wed 08/02/95 17:54:19
// Note : Copyright 1994-95, Eric Woodruff, All rights reserved
// Compiler: Borland C++ 3.1 to 4.xx
//
// This program demonstrates the TVMEditor classes.
// Included is my standard front end. It will also serve as a fairly good
// tutorial on selecting color palettes from the command line as well as
// saving and restoring colors to a configuration file. This same front
// end and all references to TVCOLR.H, TVCOLR.DOC, and COLUPDT.DOC can be
// found in TVCOLR.ZIP also in BCPPDOS library 11 on CompuServe. It is *not*
// required that you have it for TVMEditor use though. It simply describes
// a method of extending the Turbo Vision color palettes.
//
// You may use any of the following command line parameters:
//
// /MC | /MB | /MM | /MA - Select color, black & white, monochrome,
// or alternate color palette. If not
// specified, it defaults to the palette
// best suited for the monitor in use.
//
// /Cdr:\path\filename.ext - Specify different default config filename.
//
// /Rdr:\path\filename.ext - Specify different resource filename.
//
// /VA | /VE | /VX | /VM | - Specify the default virtual memory
// /VS | /VD preference for the editors (Auto detect,
// EMS first, XMS first, EMS only, XMS only,
// or disk only).
//
// dr:\path\filename.ext - Load file into an editor from command line.
//
// This program uses a resource file for some of the objects like the menu
// bar, status line, color dialog box, etc. If you use this code elsewhere
// without a resource file, you can generally replace the rsc->get() calls
// with calls to the functions from BLDRSC.CPP that create the objects. Just
// include those functions in here or in a separate module and remove all
// references to the resource file.
//
// #define SHAREWARE - Done in Options | Compiler | Code Generation | Defines
// for the shareware release.
// Uncomment the following line to allow searching the the end of the
// executable for the resource file.
//
// NOTE: The resource file cannot be appended to the executable if the
// application is compiled to run under protected mode. It won't let
// you access it (sort of like the problem when including debug info).
//#define FINAL
#include <conio.h>
#include <ctype.h>
#include <dir.h>
#include <dos.h>
#include <float.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern unsigned _stklen = 10240U; // Increase stack size to 10K.
#define Uses_MsgBox
#define Uses_TApplication
#define Uses_TColorDialog
#define Uses_TChDirDialog
#define Uses_TDeskTop
#define Uses_TDialog
#define Uses_TEvent
#define Uses_TFileDialog
#define Uses_TKeys
#define Uses_TMenuBar
#define Uses_TMenuItem
#define Uses_TPalette
#define Uses_TResourceFile
#define Uses_TScreen
#define Uses_TScrollBar
#define Uses_TStatusDef
#define Uses_TStatusItem
#define Uses_TStatusLine
#define Uses_TStreamableClass
#define Uses_TSubMenu
#define Uses_TWindow
#define Uses_TVCOLR // Use this if you modified the TV.H file.
#define Uses_fpstream
#include <tv.h>
#if !defined(cpDefSize)
// Use this if you chose not to modify the Turbo Vision files.
#include <tvcolr.h>
#endif
// ****************************************************************************
// Headers not in the standard front end file.
#if !defined(SHAREWARE)
#define Uses_TVirtualMemory // Only available in registered versions.
#endif
#define Uses_TVMEditWindow
#include <tvmedit.h>
#if defined(CSH_LIBRARY)
#define Uses_TCSHEditor
#define Uses_TCSHEditWindow // Uses Color Syntax Highlighting
#include <cshedit.h>
#endif
#ifdef INCLUDE_HEAPVIEW
#include <heapview.h>
#endif
#include <tmsgview.h>
#define Uses_TVMEditorApp
#include "tvedit.h" // Demo program header file.
// ****************************************************************************
#include "link.h" // Resource file link definitions.
//extern int _Cdecl _argc; // Global pointers to the command line args.
//extern char **_Cdecl _argv; // This way the app's constructor can access
// them. Declarations are in DOS.H too.
char demo_cfg[MAXPATH], // Configuration filename.
demo_rsc[MAXPATH]; // Resource filename.
#if defined(CSH_LIBRARY)
char demo_csh[MAXPATH]; // Default location of the CSH data file.
#endif
// Resource file pointers.
fpstream *s;
TResourceFile *rsc = NULL; // NULL to start with.
// The value of this variable determines what is printed when the program
// exits back to DOS.
short ExitValue = EXIT_NOERR;
// Monitor type palette index as set from the command line (/MC | /MB | /MM |
// /MA). Default it is -1 to let the application use the default palette
// selected by TProgram::initScreen().
short CmdLinePalette = -1;
// Global pointer to the user screen buffer for the User Screen event.
char *ScrBuf = NULL;
// ****************************************************************************
// Global variables not in the standard front end file.
// Global clipboard pointer for the editor.
TVMEditWindow *clipWindow;
// Indent for new editor windows.
short winIndent = 0;
// Global data structures for the demo.
#if !defined(__DPMI16__) && !defined(__DPMI32__)
StartUp StartUpOpts = { soIndicAtTop | soUseCSH, 0, 20};
#else
StartUp StartUpOpts = { soIndicAtTop | soUseCSH, 20, 16384 };
#endif
// Memo demo data.
DemoData Demo = { 22, "Test - NULL terminated", 31, "Initial Data\r\nSecond Memo Field" };
//*****************************************************************************
// Standard functions. Modify as needed.
void exitfunc(void)
{
#if _TV_VERSION != 0x0103
// Prevent the screen from being cleared on exit.
TScreen::clearOnSuspend = False;
#endif
switch(ExitValue)
{
case EXIT_NOERR:
cout << endl << "Thank you for using this demo program." << endl;
break;
case EXIT_RSCERR:
cout << "Could not locate or open resource file: " <<
demo_rsc << endl;
break;
case EXIT_SWERR:
cout << "Bad parameter: " << _argv[_argc] << endl << endl;
// Fall through and display command line syntax.
case EXIT_SYNTAX:
cout << "Command line syntax:" << endl << _argv[0] << endl <<
" [/MC | /MB | /MM | /MA] [/Rrsc_file.ext] [/Ccfg_file.ext]" <<
endl <<
" [/VE | /VX | /VM | /VS | /VD] [dr:\\path\\filespec(s)...]" <<
endl;
break;
}
}
#if _TV_VERSION == 0x0103
// Tell the exit code to call the display function just prior to quiting.
#pragma exit exitfunc 31
#endif
//
// This will kick everything off. Note that no argc, or argv parameters are
// used. The global _argc and _argv variables are used instead so that we
// don't have to pass them to the constructor. You don't need to do things
// this way, it's just one alternative.
//
void main(void)
{
short index = 1;
#if _TV_VERSION != 0x0103
// Prevent the screen from being cleared on exit until we've had a
// chance to check things out.
TScreen::clearOnSuspend = False;
// Register the exit function so that the exit messages are still
// displayed.
atexit(exitfunc);
#endif
// To begin with, assume that the resource file is appended to the
// executable. If it isn't, we'll try a different approach.
// To append the resource file to the executable you would issue the
// command:
// COPY /B filename1.EXE+filename.RSC filename2.EXE
//
// Make sure the destination .EXE name is not the same as the source
// .EXE name or you will overwrite the source .EXE file.
// Also note that the source .EXE can't have debug info at the end of it.
//
strcpy(demo_rsc, _argv[0]);
// Until the final production version, don't bother trying to access the
// executable. Debugging from within the IDE will cause a general access
// failure on the drive when it tries to open it. TResourceFile won't
// read past the debug info at the end of the executable anyway so use a
// separate resource file until debugging is all done.
#ifndef FINAL
strcpy(strrchr(demo_rsc, '.') + 1, "RSC");
#endif
// Modify executable name to get location and name of the default
// configuration file. We'll assume the config file (if any) is in the
// same directory as the executable and has the same name with a .CFG
// extension. It can be changed with a /C command line switch to
// specify a different path to it or a different name.
strcpy(demo_cfg, _argv[0]);
strcpy(strrchr(demo_cfg, '.') + 1, "CFG");
// Look for command line switches affecting configuration and resource
// files. A check for a user requested palette is also included here.
// That way everything will come up in the proper colors when
// setScreenMode() is called in the application's constructor or in
// the loadConfig() function.
//
// I've found it best to scan for and process these items here because
// I do have some cases where the command line arguments are processed
// in the application's constructor to insert some default objects into
// the desktop such as file or directory viewers, editor windows, etc
// specified with other command line switches. If there is an error
// doing one of them, you need the screen active so that you can see
// the error message box. Also, you don't have to do anything special
// in the application's constructor to switch palettes if one of these
// is found.
//
while(index != _argc)
{
// Allow -opt or /opt.
if(_argv[index][0] == '/' || _argv[index][0] == '-')
switch(toupper(_argv[index][1]))
{
case 'M': // Change the default palette.
switch(toupper(_argv[index][2]))
{
case 'C':
CmdLinePalette = apColor;
break;
case 'B':
CmdLinePalette = apBlackWhite;
break;
case 'M':
CmdLinePalette = apMonochrome;
break;
case 'A':
CmdLinePalette = apAltColor;
break;
default:
ExitValue = EXIT_SWERR; // Signal bad switch value.
_argc = index;
exit(EXIT_SWERR);
}
break;
case 'C': // Use a different configuration filename.
strcpy(demo_cfg, &_argv[index][2]);
break;
case 'R': // Use a different resource filename.
strcpy(demo_rsc, &_argv[index][2]);
break;
#if !defined(SHAREWARE) && !defined(__DPMI16__) && !defined(__DPMI32__)
case 'V': // Change the default virtual memory type.
switch(toupper(_argv[index][2]))
{
case 'A':
TVirtualMemory::MemoryCheck = TVMAutoDetect;
break;
case 'E':
TVirtualMemory::MemoryCheck = TVMEMSFirst;
break;
case 'X':
TVirtualMemory::MemoryCheck = TVMXMSFirst;
break;
case 'M':
TVirtualMemory::MemoryCheck = TVMEMSOnly;
break;
case 'S':
TVirtualMemory::MemoryCheck = TVMXMSOnly;
break;
case 'D':
TVirtualMemory::MemoryCheck = TVMDiskOnly;
break;
default:
ExitValue = EXIT_SWERR; // Signal bad switch value.
_argc = index;
exit(EXIT_SWERR);
}
StartUpOpts.VirtualMemory = TVirtualMemory::MemoryCheck;
break;
#endif
case '?':
ExitValue = EXIT_SYNTAX; // Display command syntax.
exit(EXIT_SYNTAX);
// case 'X': // Ignore other valid switches that
// case 'Y': // will be processed in the application's
// case 'Z': // constructor.
// break;
default:
ExitValue = EXIT_SWERR; // Signal bad switch value.
_argc = index;
exit(EXIT_SWERR);
}
index++;
}
// Now try to open the resource file and use it.
s = new fpstream(demo_rsc, ios::in | ios::nocreate | ios::binary);
if(s->good())
{
rsc = (TResourceFile *)new TResourceFile(s);
if(!rsc->count())
{
TObject::destroy(rsc); // No resource file in the EXE or
rsc = NULL; // user supplied filename.
}
}
else
delete s;
if(!rsc)
{
// As long as a /R switch wasn't specified, modify the executable name
// to get the location and name of the default resource file.
// We'll assume the resource file is in the same directory as the
// executable and has the same name with a .RSC extension. It can be
// changed with a /R command line switch to specify a different path
// to it or a different name. If that is the case, it wasn't
// accessible.
if(!strnicmp(_argv[0], demo_rsc, strlen(_argv[0]) - 3))
{
strcpy(strrchr(demo_rsc, '.') + 1, "RSC");
s = new fpstream(demo_rsc, ios::in | ios::nocreate | ios::binary);
if(!s->good())
ExitValue = EXIT_RSCERR; // Still not accessible.
else
{
rsc = (TResourceFile *)new TResourceFile(s);
if(!rsc->count())
{
TObject::destroy(rsc); // Not a valid resource file.
ExitValue = EXIT_RSCERR;
}
}
}
else
ExitValue = EXIT_RSCERR; // User specified file isn't accessible.
if(ExitValue)
exit(EXIT_RSCERR);
}
#if _TV_VERSION != 0x0103
// Now it's okay to clear the screen upon exit.
TScreen::clearOnSuspend = True;
#endif
#if defined(CSH_LIBRARY)
// Set the location of the default CSH data set file.
strcpy(demo_csh, _argv[0]);
strcpy(strrchr(demo_csh, '\\') + 1, "CSHDEFLT.DTA");
TCSHEditor::CSHDataSetName = demo_csh;
#endif
// Application Instance. Change class name of application as needed.
TVMEditorApp Demo;
Demo.run();
// Shutdown the app and close the resource file.
Demo.shutDown();
TObject::destroy(rsc);
if(ScrBuf)
delete [] ScrBuf; // Delete User Screen buffer if used.
#if _TV_VERSION != 0x0103
// Be neat and get rid of the desktop display so that the exit message
// can be seen clearly.
Demo.suspend();
#endif
exit(EXIT_NOERR);
}
// ****************************************************************************
// Standard front end functions follow, modify as needed.
//
// Constructor for the application.
//
TVMEditorApp::TVMEditorApp(void) :
TProgInit( &TVMEditorApp::initStatusLine, &TVMEditorApp::initMenuBar,
&TVMEditorApp::initDeskTop )
{
TRect r;
TEvent event;
short index = 1,
Ignored = 0; // Count of ignored command line parameters.
#if _TV_VERSION == 0x0103
// This line insures snow checking is off to speed up the display.
// It can be removed if you've modified TSCREEN.CPP or are using TV 2.0.
TScreen::checkSnow = False;
#endif
#ifdef INCLUDE_HEAPVIEW
// Create the heap view (optional).
r = getExtent();
r.a.x = r.b.x - 22;
r.b.y = r.a.y + 1;
heap = new THeapView( r );
insert(heap);
#endif
// **********************************************************************
// Application-specific setup code.
#if !defined(SHAREWARE)
#if !defined(__DPMI16__) && !defined(__DPMI32__)
// Set memory option based on library default.
StartUpOpts.VirtualMemory = TVirtualMemory::MemoryCheck;
#else
StartUpOpts.MaxAllocatable =
short(TVirtualMemory::getMaxAllocation() / 1024L);
#endif
#endif
// These commands need to be disabled manually when the application
// is initialized because there aren't any editors around yet to use
// them or turn them off automatically.
TCommandSet ts;
ts.enableCmd(cmSave);
ts.enableCmd(cmSaveAs);
ts.enableCmd(cmSaveAll);
ts.enableCmd(cmPrintFile);
ts.enableCmd(cmUndo);
ts.enableCmd(cmRedo);
ts.enableCmd(cmCut);
ts.enableCmd(cmCopy);
ts.enableCmd(cmPaste);
ts.enableCmd(cmClear);
ts.enableCmd(cmFind);
ts.enableCmd(cmReplace);
ts.enableCmd(cmSearchAgain);
ts.enableCmd(cmGotoLine);
ts.enableCmd(cmLocalEditorOpt);
ts.enableCmd(cmPrevMsg);
ts.enableCmd(cmNextMsg);
disableCommands(ts);
kbFlags = EOS;
// Install the new editorDialog() handler.
TVMEditor::editorDialog = doEditDialog;
// Install the Signs of Life handler
TVMEditor::signsOfLife = doSignsOfLife;
// Create a clipboard. Keep the conventional memory buffer small so
// as not to waste memory on it.
clipWindow = (TVMEditWindow *)validView(
new TVMEditWindow(deskTop->getExtent(), NULL, wnNoNumber, True, 4) );
if(clipWindow)
{
// Make sure other editors know where it is.
TVMEditor::clipboard = clipWindow->editor;
// Just a preference, no need for undo/redo on the clipboard.
TVMEditor::clipboard->setOption(efCanUndo, False);
// The clipboard window is hidden by default.
clipWindow->hide();
deskTop->insert(clipWindow);
}
#if defined(AUTOEOL)
// Test efAutoEOLMark. Uses a visible EOL marker (a left chevron).
TVMEditor::EOLMarker = '\xAE';
TVMEditor::GlobalOpts.Operation |= (efWordWrap | efAutoWrap);
TVMEditor::GlobalOpts.EnterMatch |= efAutoEOLMark;
#endif
#if defined(__FLAT__)
// In case something went wrong (or if you don't construct a clipboard!),
// call AllocateDescriptor() to establish TVMEditor::lowMemDesc. It is
// used in idle() to access the BIOS keyboard flags.
if(!TVMEditor::clipboard)
AllocateDescriptor();
#endif
// **********************************************************************
// All the default objects and views have been constructed, now we
// can do some stuff with the desktop.
// If there is a configuration file, read in the data now.
// Then, here or in loadConfig, turn on the screen and redraw it.
// If it is done earlier than this, the proper colors won't be used
// for the initial screen when an alternate palette is specified.
if(!access(demo_cfg, 0))
loadConfig(False);
else
{
setScreenMode(TScreen::screenMode);
#if _TV_VERSION == 0x0103 // Fixed in TV 2.0
if(TMouse::present()) // Adjust mouse limits if present.
TMouse::setRange(TScreen::screenWidth - 1,
TScreen::screenHeight - 1);
#endif
}
// Attempt to restore the desktop if one exists.
#if defined(__DPMI16__)
if(!access("TVEDIT16.TVD", 0))
restoreDeskTop();
#else
#if defined(__DPMI32__)
if(!access("TVEDIT32.TVD", 0))
restoreDeskTop();
#else
if(!access("TVEDIT.TVD", 0))
restoreDeskTop();
#endif
#endif
// **********************************************************************
// Process any other command line arguments now.
// Don't forget to ignore any of the one's parsed in main().
while(index != _argc)
{
if(_argv[index][0] == '/' || _argv[index][0] == '-')
{
switch(toupper(_argv[index][1]))
{
// case 'X':
// case 'Y':
// case 'Z':
// do something
// break;
case 'C': // Ignore config file selection
case 'R': // Ignore resource file selection
case 'M': // Ignore palette selection
case 'V': // Ignore virtual memory selection
Ignored++; // They're already taken care of.
break;
default:
Ignored++;
messageBox(mfError | mfOKButton,
"Invalid command line switch: %s", _argv[index]);
break;
}
}
else // If not a switch, default to doing something else with it.
{
// // Ignored by default.
// Ignored++;
// messageBox(mfError | mfOKButton,
// "Invalid command line parameter: %s", _argv[index]);
// For the editor demo, assume it is a valid filename or wildcard.
openEditor(_argv[index], True);
}
// Processing to be done after each switch command (if any).
// Insert other default views, etc.
index++;
}
// Display the About Box if no command line parameters are passed
// or only /Mx, /C, or /R parameters were used.
if(_argc < 2 || (_argc - Ignored) < 2)
{
event.what = evCommand;
event.message.command = cmAbout;
putEvent(event);
}
}
// This is where the palettes for the application are defined.
TPalette &TVMEditorApp::getPalette() const
{
// The Color and Alternate Color attribute maps are swapped in these
// definitions so that my color preferences are used by default for
// color monitors.
static TPalette color( cpExtAltColor, sizeof( cpExtAltColor)-1 );
static TPalette blackwhite( cpExtBlackWhite, sizeof( cpExtBlackWhite)-1 );
static TPalette monochrome( cpExtMonochrome, sizeof( cpExtMonochrome)-1 );
static TPalette altcolor( cpExtColor, sizeof( cpExtColor)-1 );
static TPalette *palettes[] =
{
&color,
&blackwhite,
&monochrome,
&altcolor // Additional palettes must come after standard ones
// in this array.
};
return *(palettes[appPalette]);
}
//
// Application idle function. Modify or remark out as required.
//
void TVMEditorApp::idle(void)
{
uchar newFlags;
TProgram::idle();
#ifdef INCLUDE_HEAPVIEW
heap->update();
#endif
// While idling, keep the editor windows informed of changes to the
// CAPS, NumLock, and ScrollLock states. Those keys don't generate
// an event.
#if !defined(__DPMI16__) && !defined(__DPMI32__)
newFlags = (*((uchar _FAR *)MK_FP(0x40, 0x17)) &
(kbCapsState | kbNumState | kbScrollState));
#else
#if defined(__DPMI16__)
newFlags = (*((uchar _FAR *)MK_FP(__Seg0040, 0x17)) &
(kbCapsState | kbNumState | kbScrollState));
#else
// Access BIOS keyboard flags. Use __emit__() to avoid the
// inline assembler problems.
__emit__(0x1E); // push ds
_ESI = 1047L;
_DS = TVMEditor::lowMemDesc;
__emit__(0x8A); // mov bl, ds:[esi]
__emit__(0x1E);
__emit__(0x1F); // pop ds
newFlags = (_BL & 0x70);
#endif
#endif
if(kbFlags != newFlags)
{
kbFlags = newFlags;
message(deskTop, evBroadcast, cmkbFlagChg, NULL);
}
// Turn off Tile and Cascade if other window commands are disabled.
if(!commandEnabled(cmPrev))
{
disableCommand(cmCloseAll);
disableCommand(cmTile);
disableCommand(cmCascade);
}
else
{
enableCommand(cmCloseAll);
enableCommand(cmTile);
enableCommand(cmCascade);
}
// Select the menu bar if the desktop is empty.
if(!deskTop->current && !menuBar->getState(sfSelected))
{
TEvent event;
event.what = evCommand;
event.message.command = cmMenu;
putEvent(event);
}
}
// Test the Get Selected Text feature.
void TVMEditorApp::testGetText(void)
{
TVMEditWindow *edWin = (TVMEditWindow *)message(TProgram::deskTop,
evBroadcast, cmEditorPresent, NULL);
if(!edWin)
return;
#if !defined(SHAREWARE) && defined(TVME_DIAG)
// This a diagnostic check to see how many characters are in the editor
// buffer. It is mainly for debugging the TextSize code, but also returns
// the LRU counter to see what kind of load the swap mechanism is under.
char temp[256];
short x;
long y;
TVirtualMemory* buf = edWin->editor->Buffer;
edWin->editor->textLimits(x, y);
// V(irtual buffer) + L(ine count) should always equal E(ditor)
// when efUseLFOnly is disabled. When efUseLFOnly is enabled,
// V and E should always be equal.
sprintf(temp, "Diagnostic - Size Info:\n V=%7ld L=%7ld\n"
"V+L=%7ld E=%7ld\nLRU=%d", buf->getTextSize(), y,
buf->getTextSize() + y, edWin->editor->getTextSize(),
buf->getLRUCnt());
messageBox(temp, mfInformation | mfOKButton);
#endif
ushort textSize = edWin->editor->getSelectedTextSize('\r');
messageBox(mfInformation | mfOKButton, "Selected Text Size = %u",
textSize);
if(textSize)
{
// Use malloc so as not to abort on allocation failure.
char *text = (char *)malloc(textSize);
if(!text)
{
outOfMemory();
return;
}
FILE *fp = fopen("GETTEXT.XXX", "wb");
if(fp)
{
Boolean NotDone;
ushort copyCount;
// Copy text to file until there is no more.
do
{
copyCount = edWin->editor->getSelectedText(text,
textSize, '\r', &NotDone);
fwrite(text, copyCount, 1, fp);
} while(NotDone);
fclose(fp);
}
free(text);
}
edWin->editor->setSelect(0,1L,maxLineLength,50,True);
}
//
// Event handler to distribute the work.
//
void TVMEditorApp::handleEvent(TEvent &event)
{
TColorDialog *c;
if(event.what == evCommand && event.message.command == cmQuit &&
(StartUpOpts.EdOpts & soSaveDeskTop))
saveDeskTop();
TApplication::handleEvent(event);
if(event.what == evCommand)
{
switch(event.message.command)
{
// Standard front end evCommand events.
case cmAbout: // About Dialog Box
executeDialog((TDialog *)rsc->get("AboutBox"), NULL);
break;
case cmRepaint:
setScreenMode(TScreen::screenMode);
break;
case cmSaveAll:
// Change it from a command to a broadcast event.
message(deskTop, evBroadcast, cmSaveAll, NULL);
break;
case cmDosShell:
suspend(); // Suspend Turbo Vision and shell to DOS.
cout << endl << "Type EXIT to return..." << endl;
system(getenv("COMSPEC"));
_fpreset(); // Reset math co-processor.
if(!ScrBuf)
ScrBuf = new char[4100]; // At least 4000 bytes.
gettext(1, 1, 80, 25, ScrBuf); // Get screen image.
resume(); // Restart Turbo Vision.
redraw();
// Tell all open editor windows to resynchronize their
// buffers with the copy of the file on disk if necessary.
message(deskTop, evBroadcast, cmReSynch, NULL);
break;
case cmTile: // Tile current windows
deskTop->tile(deskTop->getExtent());
// Tell all editors to Reformat on Resize if they need to.
message(deskTop, evBroadcast, cmResizeReformat, NULL);
break;
case cmCascade: // Cascade current windows
deskTop->cascade(deskTop->getExtent());
// Tell all editors to Reformat on Resize if they need to.
message(deskTop, evBroadcast, cmResizeReformat, NULL);
break;
case cmCloseAll: // Close all views that have ofTileable set.
TView *vw;
while((vw = deskTop->firstThat(isTileable, 0)) != NULL)
message(vw, evCommand, cmClose, NULL);
break;
case cmScreenSize: // Change screen size.
// If already in 43/50 line mode, return to the startup mode.
if(TScreen::screenMode == (TDisplay::smCO80 | TDisplay::smFont8x8))
setScreenMode(TScreen::startupMode);
else
setScreenMode(TDisplay::smCO80 | TDisplay::smFont8x8);
#if _TV_VERSION == 0x0103
// Adjust mouse limits if present. (Fixed in TV 2.0)
if(TMouse::present())
TMouse::setRange(TScreen::screenWidth - 1,
TScreen::screenHeight - 1);
#endif
break;
case cmUserScreen:
suspend(); // Suspend Turbo Vision and display user
if(ScrBuf) // screen if there is one.
puttext(1, 1, 80, 25, ScrBuf);
getch(); // Wait for keypress and restart Turbo Vision.
resume();
redraw();
break;
case cmColors:
c = (TColorDialog *)rsc->get("ColorDlg");
if(validView(c))
{
#if _TV_VERSION == 0x0103
//* TV 1.03 NOTE: I have found that this is the *proper* way to set up *all*
//* TColorDialog boxes. If you follow the TVDEMO example, you pass
//* TColorDialog a NULL pointer in its constructor (the palette pointer is
//* also NULL after you restore it from a resource file!).
//* You then call its setData() member to initialize the color set. The
//* problem is that TColorDialog::setData() does a memcpy() using that NULL
//* pointer. If you trace into the assembler code at that point, you'll see
//* that it takes the address stored in interrupt zero (the Divide by Zero
//* handler) and copies the palette to that address. Most of the time you
//* don't know anything is wrong, but I have found cases where it crashes
//* immediately or at some point shortly after that. Even if it doesn't
//* crash, you are still asking for trouble. The method below is the only
//* way to get a TColorDialog box to work safely and properly when created
//* at runtime or stored in a resource file.
TPalette x = getPalette(); // Create temporary
c->pal = &x; // palette and assign it.
// TV 2.0 NOTE: In TV 2.0, this has been fixed. The above two lines
// should not be used or a crash will result.
#endif
c->setData(&getPalette()); // Call setData() with
// the initial colors.
// Execute the color dialog box.
if(deskTop->execView(c) != cmCancel)
{
// Do a straight assignment to get the modified colors.
getPalette() = *(c->pal);
// Repaint the entire desktop by calling
// setScreenMode(). Calling deskTop->setState()
// to set sfVisible off and then on as in TVDEMO
// doesn't always redraw the entire screen if
// there is a window or some other view on the
// desktop that has the focus.
setScreenMode(TScreen::screenMode);
}
destroy(c);
}
break;
case cmChangePalettes:
CmdLinePalette = appPalette + 1;
if(CmdLinePalette == apTotalPalettes)
CmdLinePalette = apColor;
setScreenMode(TScreen::screenMode);
break;
case cmLoadCfg:
if(executeDialog(new TFileDialog(demo_cfg, "Load Configuration",
"~N~ame", fdOpenButton, 100), demo_cfg) != cmCancel)
loadConfig(True);
break;
case cmSaveCfg:
if(executeDialog(new TFileDialog(demo_cfg, "Save Configuration",
"~N~ame", fdOKButton, 100), demo_cfg) != cmCancel)
saveConfig();
break;
// Non-standard evCommand events.
case cmNew:
openEditor(NULL, True);
break;
case cmOpen:
char fileName[MAXPATH];
strcpy(fileName, "*.");
strcat(fileName, TVMEditor::GlobalOpts.DefaultExt);
openEditor(fileName, True);
break;
case cmChDir:
executeDialog(new TChDirDialog( cdNormal, 0 ), 0);
break;
case cmShowClip:
if(clipWindow)
{
clipWindow->select();
clipWindow->show();
}
break;
case cmStartUpOpt:
executeDialog((TDialog *)rsc->get("StartUpDlg"), &StartUpOpts);
#if !defined(SHAREWARE)
#if !defined(__DPMI16__) && !defined(__DPMI32__)
TVirtualMemory::MemoryCheck = StartUpOpts.VirtualMemory;
#else
TVirtualMemory::setMaxAllocation(
long(StartUpOpts.MaxAllocatable) * 1024L);
#endif
#endif
#if defined(CSH_LIBRARY)
// Let the editors know whether to enable or disable
// syntax highlighting.
message(deskTop, evBroadcast, cmCSHOnOff,
(void *)(StartUpOpts.EdOpts & soUseCSH));
#endif
break;
case cmDefaultEditorOpt: // Set the default editor options.
executeDialog((TDialog *)rsc->get("DefEdOptDlg"), &TVMEditor::GlobalOpts);
break;
case cmReplaceKeyMaps:
ReplaceKeyMaps();
break;
case cmMemoDemo:
MemoDemo();
break;
case cmKeyHelp:
executeDialog((TDialog *)rsc->get("KeyHelp"), NULL);
break;
case cmMsgViewer:
// Don't insert more than one viewer.
if(!commandEnabled(cmPrevMsg))
DemoMsgViewer();
break;
case cmPrevMsg:
case cmNextMsg:
// The application must convert these to broadcast events
// so that the message viewer will see them even when
// it isn't the focused view.
message(deskTop, evBroadcast, event.message.command, NULL);
break;
case cmGetSelText:
testGetText();
break;
#if defined(CSH_LIBRARY)
case cmCSHColors:
setCSHColors();
break;
#endif
default:
return;
}
clearEvent (event);
}
}
// ****************************************************************************
//
// The isTileable() function checks for a visible, tileable view on the
// desktop.
//
Boolean isTileable(TView *p, void *)
{
// Must ignore such objects as the clipboard when they are hidden!
if(!(p->options & ofTileable) || !(p->state & sfVisible))
return False;
return True;
}
// ****************************************************************************
// **** In TV 2.0, TProgram::executeDialog() replaces this.
// ****
#if _TV_VERSION == 0x0103
// This function executes any dialog passed to it and destroys it when done.
ushort executeDialog(TDialog *d, void *data)
{
TView *p = TProgram::application->validView(d);
if(!p)
return cmCancel;
if(data)
p->setData(data);
ushort result = TProgram::deskTop->execView(p);
if(result != cmCancel && data)
p->getData(data);
TObject::destroy(p);
return result;
}
#endif
// ****************************************************************************
// ****************************************************************************
// End of standard front end functions.
// ****************************************************************************
// Other functions not in the standard front end file.
#if defined(CSH_LIBRARY)
TCSHEditWindow *TVMEditorApp::openEditor(const char *fName, Boolean visible)
#else
TVMEditWindow *TVMEditorApp::openEditor(const char *fName, Boolean visible)
#endif
{
char fileName[MAXPATH] = "";
ffblk finfo;
// Make a copy of the filename.
if(fName)
strcpy(fileName, fName);
// When not opening an untitled file, check for a directory name or
// wildcards.
if(fileName[0])
{
finfo.ff_attrib = 0;
findfirst(fileName, &finfo, FA_NORMAL | FA_HIDDEN | FA_SYSTEM |
FA_RDONLY | FA_ARCH | FA_DIREC);
// If there are no wildcard characters in the filename, see if the
// entry is a directory or drive reference only. If so, append a
// default "\*.*" to it.
if((!strchr(fileName, '*') && !strchr(fileName, '?') &&
(finfo.ff_attrib & FA_DIREC)) ||
(fileName[1] == ':' && !fileName[2]) ||
fileName[strlen(fileName) - 1] == '\\')
{
// Strip any existing trailing backslash?
if(fileName[strlen(fileName) - 1] == '\\')
fileName[strlen(fileName) - 1] = EOS;
strcat(fileName, "\\*.*");
}
// Wildcard? If so, prompt for a real name.
if(strchr(fileName, '*') || strchr(fileName, '?'))
if(executeDialog(new TFileDialog(fileName, "Open file",
"~N~ame", fdOpenButton, 100), fileName) == cmCancel)
return NULL;
}
// Got a filename or null (untitled file), so open it.
TRect r = deskTop->getExtent();
// Indent each window's upper border so that the titles of all loaded
// files stay visible. This is only done when there are other windows
// open. If no other windows are open, the new one is always full size.
if(message(deskTop, evBroadcast, cmEditorPresent, NULL))
{
r.a.y += winIndent;
if(++winIndent > 11)
winIndent = 0;
}
else // Take the opportunity to reset the indent
winIndent = 1; // for the next window opened.
#if defined(CSH_LIBRARY)
TCSHEditWindow *p = (TCSHEditWindow *)validView(new TCSHEditWindow(r,
fileName, wnNoNumber, Boolean((StartUpOpts.EdOpts & soIndicAtTop) != 0),
StartUpOpts.bufSizeInK));
if(p)
p->editor->setOption(efUseCSH,
Boolean((StartUpOpts.EdOpts & soUseCSH) != 0));
#else
TVMEditWindow *p = (TVMEditWindow *)validView(new TVMEditWindow(r,
fileName, wnNoNumber, Boolean((StartUpOpts.EdOpts & soIndicAtTop) != 0),
StartUpOpts.bufSizeInK));
#endif
if(p)
{
// To conserve some memory, TVMEditWindow turns off buffering.
// If screen flicker is a problem on your system when using the
// edit window, uncoment this line:
// p->options |= ofBuffered;
if(!visible)
p->hide();
deskTop->insert(p);
}
return p;
}
// ****************************************************************************
// End of standard front end file.
// ****************************************************************************