dos_compilers/Borland Turbo Pascal v6/TVDEMOS/TVDEMO.PAS
2024-07-02 07:11:05 -07:00

615 lines
16 KiB
Plaintext

{************************************************}
{ }
{ Turbo Pascal 6.0 }
{ Turbo Vision Demo }
{ Copyright (c) 1990 by Borland International }
{ }
{************************************************}
program TVDemo;
{$X+,S-}
{$M 16384,8192,655360}
{ Turbo Vision demo program. This program uses many of the Turbo
Vision standard and demo units, including:
StdDlg - Open file browser, change directory tree.
MsgBox - Simple dialog to display messages.
ColorSel - Color customization.
Gadgets - Shows system time and available heap space.
AsciiTab - ASCII table.
Calendar - View a month at a time
Calc - Desktop calculator.
FViewer - Scroll through text files.
HelpFile - Context sensitive help.
MouseDlg - Mouse options dialog.
Puzzle - Simple brain puzzle.
And of course this program includes many standard Turbo Vision
objects and behaviors (menubar, desktop, status line, dialog boxes,
mouse support, window resize/move/tile/cascade).
}
uses
Dos, Objects, Drivers, Memory, Views, Menus, Dialogs, StdDlg, MsgBox, App,
DemoCmds, Gadgets, Puzzle, Calendar, AsciiTab, Calc, FViewer, HelpFile,
DemoHelp, ColorSel, MouseDlg;
type
{ TTVDemo }
PTVDemo = ^TTVDemo;
TTVDemo = object(TApplication)
Clock: PClockView;
Heap: PHeapView;
constructor Init;
procedure FileOpen(WildCard: PathStr);
procedure GetEvent(var Event: TEvent); virtual;
function GetPalette: PPalette; virtual;
procedure HandleEvent(var Event: TEvent); virtual;
procedure Idle; virtual;
procedure InitMenuBar; virtual;
procedure InitStatusLine; virtual;
procedure LoadDesktop(var S: TStream);
procedure OutOfMemory; virtual;
procedure StoreDesktop(var S: TStream);
procedure ViewFile(FileName: PathStr);
end;
{ CalcHelpName }
function CalcHelpName: PathStr;
var
EXEName: PathStr;
Dir: DirStr;
Name: NameStr;
Ext: ExtStr;
begin
if Lo(DosVersion) >= 3 then EXEName := ParamStr(0)
else EXEName := FSearch('TVDEMO.EXE', GetEnv('PATH'));
FSplit(EXEName, Dir, Name, Ext);
if Dir[Length(Dir)] = '\' then Dec(Dir[0]);
CalcHelpName := FSearch('DEMOHELP.HLP', Dir);
end;
{ TTVDemo }
constructor TTVDemo.Init;
var
R: TRect;
I: Integer;
FileName: PathStr;
begin
TApplication.Init;
RegisterObjects;
RegisterViews;
RegisterMenus;
RegisterDialogs;
RegisterApp;
RegisterHelpFile;
RegisterPuzzle;
RegisterCalendar;
RegisterAsciiTab;
RegisterCalc;
RegisterFViewer;
GetExtent(R);
R.A.X := R.B.X - 9; R.B.Y := R.A.Y + 1;
Clock := New(PClockView, Init(R));
Insert(Clock);
GetExtent(R);
Dec(R.B.X);
R.A.X := R.B.X - 9; R.A.Y := R.B.Y - 1;
Heap := New(PHeapView, Init(R));
Insert(Heap);
for I := 1 to ParamCount do
begin
FileName := ParamStr(I);
if FileName[Length(FileName)] = '\' then
FileName := FileName + '*.*';
if (Pos('?', FileName) = 0) and (Pos('*', FileName) = 0) then
ViewFile(FExpand(FileName))
else FileOpen(FileName);
end;
end;
procedure TTVDemo.FileOpen(WildCard: PathStr);
var
D: PFileDialog;
FileName: PathStr;
begin
D := New(PFileDialog, Init(WildCard, 'Open a File',
'~N~ame', fdOpenButton + fdHelpButton, 100));
D^.HelpCtx := hcFOFileOpenDBox;
if ValidView(D) <> nil then
begin
if Desktop^.ExecView(D) <> cmCancel then
begin
D^.GetFileName(FileName);
ViewFile(FileName);
end;
Dispose(D, Done);
end;
end;
procedure TTVDemo.GetEvent(var Event: TEvent);
var
W: PWindow;
HFile: PHelpFile;
HelpStrm: PDosStream;
const
HelpInUse: Boolean = False;
begin
TApplication.GetEvent(Event);
case Event.What of
evCommand:
if (Event.Command = cmHelp) and not HelpInUse then
begin
HelpInUse := True;
HelpStrm := New(PDosStream, Init(CalcHelpName, stOpenRead));
HFile := New(PHelpFile, Init(HelpStrm));
if HelpStrm^.Status <> stOk then
begin
MessageBox('Could not open help file.', nil, mfError + mfOkButton);
Dispose(HFile, Done);
end
else
begin
W := New(PHelpWindow,Init(HFile, GetHelpCtx));
if ValidView(W) <> nil then
begin
ExecView(W);
Dispose(W, Done);
end;
ClearEvent(Event);
end;
HelpInUse := False;
end;
evMouseDown:
if Event.Buttons <> 1 then Event.What := evNothing;
end;
end;
function TTVDemo.GetPalette: PPalette;
const
CNewColor = CColor + CHelpColor;
CNewBlackWhite = CBlackWhite + CHelpBlackWhite;
CNewMonochrome = CMonochrome + CHelpMonochrome;
P: array[apColor..apMonochrome] of string[Length(CNewColor)] =
(CNewColor, CNewBlackWhite, CNewMonochrome);
begin
GetPalette := @P[AppPalette];
end;
procedure TTVDemo.HandleEvent(var Event: TEvent);
procedure ChangeDir;
var
D: PChDirDialog;
begin
D := New(PChDirDialog, Init(cdNormal + cdHelpButton, 101));
D^.HelpCtx := hcFCChDirDBox;
if ValidView(D) <> nil then
begin
DeskTop^.ExecView(D);
Dispose(D, Done);
end;
end;
procedure Tile;
var
R: TRect;
begin
Desktop^.GetExtent(R);
Desktop^.Tile(R);
end;
procedure Cascade;
var
R: TRect;
begin
Desktop^.GetExtent(R);
Desktop^.Cascade(R);
end;
procedure Puzzle;
var
P: PPuzzleWindow;
begin
P := New(PPuzzleWindow, Init);
P^.HelpCtx := hcPuzzle;
Desktop^.Insert(ValidView(P));
end;
procedure Calendar;
var
P: PCalendarWindow;
begin
P := New(PCalendarWindow, Init);
P^.HelpCtx := hcCalendar;
Desktop^.Insert(ValidView(P));
end;
procedure About;
var
D: PDialog;
Control: PView;
R: TRect;
begin
R.Assign(0, 0, 40, 11);
D := New(PDialog, Init(R, 'About'));
with D^ do
begin
Options := Options or ofCentered;
R.Grow(-1, -1);
Dec(R.B.Y, 3);
Insert(New(PStaticText, Init(R,
#13 +
^C'Turbo Vision Demo'#13 +
#13 +
^C'Copyright (c) 1990'#13 +
#13 +
^C'Borland International')));
R.Assign(15, 8, 25, 10);
Insert(New(PButton, Init(R, 'O~K', cmOk, bfDefault)));
end;
if ValidView(D) <> nil then
begin
Desktop^.ExecView(D);
Dispose(D, Done);
end;
end;
procedure AsciiTab;
var
P: PAsciiChart;
begin
P := New(PAsciiChart, Init);
P^.HelpCtx := hcAsciiTable;
Desktop^.Insert(ValidView(P));
end;
procedure Calculator;
var
P: PCalculator;
begin
P := New(PCalculator, Init);
P^.HelpCtx := hcCalculator;
if ValidView(P) <> nil then
Desktop^.Insert(P);
end;
procedure Colors;
var
D: PColorDialog;
begin
D := New(PColorDialog, Init('',
ColorGroup('Desktop',
ColorItem('Color', 32, nil),
ColorGroup('Menus',
ColorItem('Normal', 2,
ColorItem('Disabled', 3,
ColorItem('Shortcut', 4,
ColorItem('Selected', 5,
ColorItem('Selected disabled', 6,
ColorItem('Shortcut selected', 7, nil)))))),
ColorGroup('Dialogs/Calc',
ColorItem('Frame/background', 33,
ColorItem('Frame icons', 34,
ColorItem('Scroll bar page', 35,
ColorItem('Scroll bar icons', 36,
ColorItem('Static text', 37,
ColorItem('Label normal', 38,
ColorItem('Label selected', 39,
ColorItem('Label shortcut', 40,
ColorItem('Button normal', 41,
ColorItem('Button default', 42,
ColorItem('Button selected', 43,
ColorItem('Button disabled', 44,
ColorItem('Button shortcut', 45,
ColorItem('Button shadow', 46,
ColorItem('Cluster normal', 47,
ColorItem('Cluster selected', 48,
ColorItem('Cluster shortcut', 49,
ColorItem('Input normal', 50,
ColorItem('Input selected', 51,
ColorItem('Input arrow', 52,
ColorItem('History button', 53,
ColorItem('History sides', 54,
ColorItem('History bar page', 55,
ColorItem('History bar icons', 56,
ColorItem('List normal', 57,
ColorItem('List focused', 58,
ColorItem('List selected', 59,
ColorItem('List divider', 60,
ColorItem('Information pane', 61, nil))))))))))))))))))))))))))))),
ColorGroup('Viewer',
ColorItem('Frame passive', 8,
ColorItem('Frame active', 9,
ColorItem('Frame icons', 10,
ColorItem('Scroll bar page', 11,
ColorItem('Scroll bar icons', 12,
ColorItem('Text', 13, nil)))))),
ColorGroup('Puzzle',
ColorItem('Frame passive', 8,
ColorItem('Frame active', 9,
ColorItem('Frame icons', 10,
ColorItem('Scroll bar page', 11,
ColorItem('Scroll bar icons', 12,
ColorItem('Normal text', 13,
ColorItem('Highlighted text', 14, nil))))))),
ColorGroup('Calendar',
ColorItem('Frame passive', 16,
ColorItem('Frame active', 17,
ColorItem('Frame icons', 18,
ColorItem('Scroll bar page', 19,
ColorItem('Scroll bar icons', 20,
ColorItem('Normal text', 21,
ColorItem('Current day', 22, nil))))))),
ColorGroup('Ascii table',
ColorItem('Frame passive', 24,
ColorItem('Frame active', 25,
ColorItem('Frame icons', 26,
ColorItem('Scroll bar page', 27,
ColorItem('Scroll bar icons', 28,
ColorItem('Text', 29, nil)))))), nil)))))))));
D^.HelpCtx := hcOCColorsDBox;
if ValidView(D) <> nil then
begin
D^.SetData(Application^.GetPalette^);
if Desktop^.ExecView(D) <> cmCancel then
begin
Application^.GetPalette^ := D^.Pal;
DoneMemory; { Dispose all group buffers }
ReDraw; { Redraw application with new palette }
end;
Dispose(D, Done);
end;
end;
procedure Mouse;
var
D: PDialog;
begin
D := New(PMouseDialog, Init);
D^.HelpCtx := hcOMMouseDBox;
if ValidView(D) <> nil then
begin
D^.SetData(MouseReverse);
if Desktop^.ExecView(D) <> cmCancel then
D^.GetData(MouseReverse);
end;
end;
procedure DosShell;
begin
DoneSysError;
DoneEvents;
DoneVideo;
DoneMemory;
SetMemTop(HeapPtr);
PrintStr('Type EXIT to return...');
SwapVectors;
Exec(GetEnv('COMSPEC'), '');
SwapVectors;
SetMemTop(HeapEnd);
InitMemory;
InitVideo;
InitEvents;
InitSysError;
Redraw;
end;
procedure RetrieveDesktop;
var
S: PStream;
begin
S := New(PBufStream, Init('TVDEMO.DSK', stOpenRead, 1024));
if LowMemory then OutOfMemory
else if S^.Status <> stOk then
MessageBox('Could not open desktop file', nil, mfOkButton + mfError)
else
begin
LoadDesktop(S^);
if S^.Status <> stOk then
MessageBox('Error reading desktop file', nil, mfOkButton + mfError);
end;
Dispose(S, Done);
end;
procedure SaveDesktop;
var
S: PStream;
F: File;
begin
S := New(PBufStream, Init('TVDEMO.DSK', stCreate, 1024));
if not LowMemory and (S^.Status = stOk) then
begin
StoreDesktop(S^);
if S^.Status <> stOk then
begin
MessageBox('Could not create TVDEMO.DSK.', nil, mfOkButton + mfError);
{$I-}
Dispose(S, Done);
Assign(F, 'TVDEMO.DSK');
Erase(F);
Exit;
end;
end;
Dispose(S, Done);
end;
begin
TApplication.HandleEvent(Event);
case Event.What of
evCommand:
begin
case Event.Command of
cmFOpen: FileOpen('*.*');
cmChDir: ChangeDir;
cmCascade: Cascade;
cmTile: Tile;
cmAbout: About;
cmPuzzle: Puzzle;
cmCalendar: Calendar;
cmAsciiTab: AsciiTab;
cmCalculator: Calculator;
cmColors: Colors;
cmMouse: Mouse;
cmDosShell: DosShell;
cmSaveDesktop: SaveDesktop;
cmRetrieveDesktop: RetrieveDesktop;
else
Exit;
end;
ClearEvent(Event);
end;
end;
end;
procedure TTVDemo.Idle;
function IsTileable(P: PView): Boolean; far;
begin
IsTileable := P^.Options and ofTileable <> 0;
end;
begin
TApplication.Idle;
Clock^.Update;
Heap^.Update;
if Desktop^.FirstThat(@IsTileable) <> nil then
EnableCommands([cmTile, cmCascade])
else
DisableCommands([cmTile, cmCascade]);
end;
procedure TTVDemo.InitMenuBar;
var
R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y+1;
MenuBar := New(PMenuBar, Init(R, NewMenu(
NewSubMenu('~'#240'~', hcSystem, NewMenu(
NewItem('~A~bout', '', kbNoKey, cmAbout, hcSAbout,
NewLine(
NewItem('~P~uzzle', '', kbNoKey, cmPuzzle, hcSPuzzle,
NewItem('Ca~l~endar', '', kbNoKey, cmCalendar, hcSCalendar,
NewItem('Ascii ~t~able', '', kbNoKey, cmAsciiTab, hcSAsciiTable,
NewItem('~C~alculator', '', kbNoKey, cmCalculator, hcCalculator, nil))))))),
NewSubMenu('~F~ile', hcFile, NewMenu(
NewItem('~O~pen...', 'F3', kbF3, cmFOpen, hcFOpen,
NewItem('~C~hange dir...', '', kbNoKey, cmChDir, hcFChangeDir,
NewLine(
NewItem('~D~OS shell', '', kbNoKey, cmDosShell, hcFDosShell,
NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcFExit, nil)))))),
NewSubMenu('~W~indows', hcWindows, NewMenu(
NewItem('~R~esize/move','Ctrl-F5', kbCtrlF5, cmResize, hcWSizeMove,
NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcWZoom,
NewItem('~N~ext', 'F6', kbF6, cmNext, hcWNext,
NewItem('~C~lose', 'Alt-F3', kbAltF3, cmClose, hcWClose,
NewItem('~T~ile', '', kbNoKey, cmTile, hcWTile,
NewItem('C~a~scade', '', kbNoKey, cmCascade, hcWCascade, nil))))))),
NewSubMenu('~O~ptions', hcOptions, NewMenu(
NewItem('~M~ouse...', '', kbNoKey, cmMouse, hcOMouse,
NewItem('~C~olors...', '', kbNoKey, cmColors, hcOColors,
NewLine(
NewItem('~S~ave desktop', '', kbNoKey, cmSaveDesktop, hcOSaveDesktop,
NewItem('~R~etrieve desktop', '', kbNoKey, cmRetrieveDesktop, hcORestoreDesktop, nil)))))), nil)))))));
end;
procedure TTVDemo.InitStatusLine;
var
R: TRect;
begin
GetExtent(R);
R.A.Y := R.B.Y - 1;
StatusLine := New(PStatusLine, Init(R,
NewStatusDef(0, $FFFF,
NewStatusKey('~F1~ Help', kbF1, cmHelp,
NewStatusKey('~F3~ Open', kbF3, cmFOpen,
NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
NewStatusKey('~F5~ Zoom', kbF5, cmZoom,
NewStatusKey('', kbF10, cmMenu,
NewStatusKey('', kbCtrlF5, cmResize, nil)))))), nil)));
end;
procedure TTVDemo.OutOfMemory;
begin
MessageBox('Not enough memory available to complete operation.',
nil, mfError + mfOkButton);
end;
{ Since the safety pool is only large enough to guarantee that allocating
a window will not run out of memory, loading the entire desktop without
checking LowMemory could cause a heap error. This means that each
window should be read individually, instead of using Desktop's Load.
}
procedure TTVDemo.LoadDesktop(var S: TStream);
var
P: PView;
procedure CloseView(P: PView); far;
begin
Message(P, evCommand, cmClose, nil);
end;
begin
if Desktop^.Valid(cmClose) then
begin
Desktop^.ForEach(@CloseView); { Clear the desktop }
repeat
P := PView(S.Get);
Desktop^.InsertBefore(ValidView(P), Desktop^.Last);
until P = nil;
end;
end;
procedure TTVDemo.StoreDesktop(var S: TStream);
procedure WriteView(P: PView); far;
begin
if P <> Desktop^.Last then S.Put(P);
end;
begin
Desktop^.ForEach(@WriteView);
S.Put(nil);
end;
procedure TTVDemo.ViewFile(FileName: PathStr);
var
W: PWindow;
begin
W := New(PFileWindow,Init(FileName));
W^.HelpCtx := hcViewer;
if ValidView(W) <> nil then
Desktop^.Insert(W);
end;
var
Demo: TTVDemo;
begin
Demo.Init;
Demo.Run;
Demo.Done;
end.