home *** CD-ROM | disk | FTP | other *** search
/ PC-X 1998 July / pcx23_9807.iso / PC-XUSER / PC-XUSER.18 / OOP / TVDEMO.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1998-06-14  |  18.9 KB  |  712 lines

  1. {************************************************}
  2. {                                                }
  3. {   Turbo Vision Demo                            }
  4. {   Copyright (c) 1992 by Borland International  }
  5. {                                                }
  6. {************************************************}
  7.  
  8. program TVDemo;
  9.  
  10. {$X+,S-}
  11. {$M 16384,8192,655360}
  12.  
  13. { Turbo Vision demo program. This program uses many of the Turbo
  14.   Vision standard and demo units, including:
  15.  
  16.     StdDlg    - Open file browser, change directory tree.
  17.     MsgBox    - Simple dialog to display messages.
  18.     ColorSel  - Color customization.
  19.     Gadgets   - Shows system time and available heap space.
  20.     AsciiTab  - ASCII table.
  21.     Calendar  - View a month at a time
  22.     Calc      - Desktop calculator.
  23.     HelpFile  - Context sensitive help.
  24.     MouseDlg  - Mouse options dialog.
  25.     Puzzle    - Simple brain puzzle.
  26.     Editors   - Text Editor object.
  27.  
  28.   And of course this program includes many standard Turbo Vision
  29.   objects and behaviors (menubar, desktop, status line, dialog boxes,
  30.   mouse support, window resize/move/tile/cascade).
  31. }
  32.  
  33. uses
  34.   Dos, Objects, Drivers, Memory, Views, Menus, Dialogs, StdDlg, HistList,
  35.   MsgBox, App, DemoCmds, Gadgets, Puzzle, Calendar, AsciiTab, Calc,
  36.   HelpFile, DemoHelp, ColorSel, MouseDlg, Editors,
  37.   PCX_App, PCX_Dlg, PCX_Util,
  38.   R4s_Dlg; {Ezt a TChDIRDialog miatt tettem be, de ki lehet venni.
  39.             (S a szükséges R4s elôtagokat kitörölve mûködik ennélkül !)}
  40.  
  41. { If you get a FILE NOT FOUND error when compiling this program
  42.   from a DOS IDE, change to the \BP\EXAMPLES\DOS\TVDEMO directory
  43.   (use File|Change dir).
  44.  
  45.   This will enable the compiler to find all of the units used by
  46.   this program.
  47. }
  48.  
  49. const
  50.   HeapSize = 48 * (1024 div 16);  { Save 48k heap for main program }
  51.  
  52.   { Desktop file signature information }
  53.   SignatureLen = 21;
  54.   DSKSignature : String[SignatureLen] = 'TV Demo Desktop File'#26;
  55.   cmAbout      = 1111;
  56.  
  57. var ClipWindow: PPCXEditBlueWindow;
  58.  
  59. type
  60.  
  61.   { TTVDemo }
  62.  
  63.   PTVDemo = ^TTVDemo;
  64.   TTVDemo = object(TPCXApplication)
  65.     Clock: PR4sClockView;
  66.     Heap : PHeapView;
  67.     constructor Init;
  68.     procedure FileOpen(WildCard: PathStr);
  69.     function  OpenEditor(FileName: FNameStr; Visible: Boolean): PPCXEditBlueWindow;
  70.     procedure GetEvent(var Event: TEvent); virtual;
  71.     function  GetPalette: PPalette; virtual;
  72.     procedure HandleEvent(var Event: TEvent); virtual;
  73.     procedure Idle; virtual;
  74.     procedure InitMenuBar; virtual;
  75.     procedure InitStatusLine; virtual;
  76.     procedure LoadDesktop(var S: TStream);
  77.     procedure OutOfMemory; virtual;
  78.     procedure StoreDesktop(var S: TStream);
  79.   end;
  80.  
  81. { CalcHelpName }
  82.  
  83. function CalcHelpName: PathStr;
  84. var
  85.   EXEName: PathStr;
  86.   Dir: DirStr;
  87.   Name: NameStr;
  88.   Ext: ExtStr;
  89. begin
  90.   if Lo(DosVersion) >= 3 then EXEName := ParamStr(0)
  91.   else EXEName := FSearch('TVDEMO.EXE', GetEnv('PATH'));
  92.   FSplit(EXEName, Dir, Name, Ext);
  93.   if Dir[Length(Dir)] = '\' then Dec(Dir[0]);
  94.   CalcHelpName := FSearch('DEMOHELP.HLP', Dir);
  95. end;
  96.  
  97. function CreateFindDialog: PPCXBlueDialog;
  98. var
  99.   D: PPCXBlueDialog;
  100.   Control: PView;
  101.   R: TRect;
  102. begin
  103.   R.Assign(0, 0, 38, 12);
  104.   D := New(PPCXBlueDialog, Init(R, 'Find'));
  105.   with D^ do
  106.   begin
  107.     Options := Options or ofCentered;
  108.  
  109.     R.Assign(3, 3, 32, 4);
  110.     Control := New(PInputLine, Init(R, 80));
  111.     Insert(Control);
  112.     R.Assign(2, 2, 15, 3);
  113.     Insert(New(PLabel, Init(R, '~T~ext to find', Control)));
  114.     R.Assign(32, 3, 35, 4);
  115.     Insert(New(PHistory, Init(R, PInputLine(Control), 10)));
  116.  
  117.     R.Assign(3, 5, 35, 7);
  118.     Insert(New(PPCXCheckBoxes, Init(R,
  119.       NewSItem('~C~ase sensitive',
  120.       NewSItem('~W~hole words only', nil)), False)));
  121.  
  122.     R.Assign(14, 9, 24, 11);
  123.     Insert(New(PPCXButton, Init(R, 'O~K~', cmOk, bfDefault)));
  124.     Inc(R.A.X, 12); Inc(R.B.X, 12);
  125.     Insert(New(PPCXButton, Init(R, 'Cancel', cmCancel, bfNormal)));
  126.  
  127.     SelectNext(False);
  128.   end;
  129.   CreateFindDialog := D;
  130. end;
  131.  
  132. function CreateReplaceDialog: PPCXBlueDialog;
  133. var
  134.   D: PPCXBlueDialog;
  135.   Control: PView;
  136.   R: TRect;
  137. begin
  138.   R.Assign(0, 0, 40, 16);
  139.   D := New(PPCXBlueDialog, Init(R, 'Replace'));
  140.   with D^ do
  141.   begin
  142.     Options := Options or ofCentered;
  143.  
  144.     R.Assign(3, 3, 34, 4);
  145.     Control := New(PInputLine, Init(R, 80));
  146.     Insert(Control);
  147.     R.Assign(2, 2, 15, 3);
  148.     Insert(New(PLabel, Init(R, '~T~ext to find', Control)));
  149.     R.Assign(34, 3, 37, 4);
  150.     Insert(New(PHistory, Init(R, PInputLine(Control), 10)));
  151.  
  152.     R.Assign(3, 6, 34, 7);
  153.     Control := New(PInputLine, Init(R, 80));
  154.     Insert(Control);
  155.     R.Assign(2, 5, 12, 6);
  156.     Insert(New(PLabel, Init(R, '~N~ew text', Control)));
  157.     R.Assign(34, 6, 37, 7);
  158.     Insert(New(PHistory, Init(R, PInputLine(Control), 11)));
  159.  
  160.     R.Assign(3, 8, 37, 12);
  161.     Insert(New(PPCXCheckBoxes, Init(R,
  162.       NewSItem('~C~ase sensitive',
  163.       NewSItem('~W~hole words only',
  164.       NewSItem('~P~rompt on replace',
  165.       NewSItem('~R~eplace all', nil)))), False)));
  166.  
  167.     R.Assign(17, 13, 27, 15);
  168.     Insert(New(PPCXButton, Init(R, 'O~K~', cmOk, bfDefault)));
  169.     R.Assign(28, 13, 38, 15);
  170.     Insert(New(PPCXButton, Init(R, 'Cancel', cmCancel, bfNormal)));
  171.  
  172.     SelectNext(False);
  173.   end;
  174.   CreateReplaceDialog := D;
  175. end;
  176.  
  177. function DoEditDialog(Dialog: Integer; Info: Pointer): Word; far;
  178. var
  179.   R: TRect;
  180.   T: TPoint;
  181. begin
  182.   case Dialog of
  183.     edOutOfMemory:
  184.       DoEditDialog := PCXMsgBox('Not enough memory for this operation.',
  185.         nil, mfError + mfOkButton);
  186.     edReadError:
  187.       DoEditDialog := PCXMsgBox('Error reading file %s.',
  188.         @Info, mfError + mfOkButton);
  189.     edWriteError:
  190.       DoEditDialog := PCXMsgBox('Error writing file %s.',
  191.         @Info, mfError + mfOkButton);
  192.     edCreateError:
  193.       DoEditDialog := PCXMsgBox('Error creating file %s.',
  194.         @Info, mfError + mfOkButton);
  195.     edSaveModify:
  196.       DoEditDialog := PCXMsgBox('%s has been modified. Save?',
  197.         @Info, mfInformation + mfYesNoCancel);
  198.     edSaveUntitled:
  199.       DoEditDialog := PCXMsgBox('Save untitled file?',
  200.         nil, mfInformation + mfYesNoCancel);
  201.     edSaveAs:
  202.       DoEditDialog := Application^.ExecuteDialog(New(PPCXFileDialog, Init('*.*',
  203.         'Save file as', '~N~ame', fdOkButton, 101)), Info);
  204.     edFind:
  205.       DoEditDialog := Application^.ExecuteDialog(CreateFindDialog, Info);
  206.     edSearchFailed:
  207.       DoEditDialog := PCXMsgBox('Search string not found.',
  208.         nil, mfError + mfOkButton);
  209.     edReplace:
  210.       DoEditDialog := Application^.ExecuteDialog(CreateReplaceDialog, Info);
  211.     edReplacePrompt:
  212.       begin
  213.         { Avoid placing the dialog on the same line as the cursor }
  214.         R.Assign(0, 1, 40, 8);
  215.         R.Move((Desktop^.Size.X - R.B.X) div 2, 0);
  216.         Desktop^.MakeGlobal(R.B, T);
  217.         Inc(T.Y);
  218.         if TPoint(Info).Y <= T.Y then
  219.           R.Move(0, Desktop^.Size.Y - R.B.Y - 2);
  220.         DoEditDialog := PCXMsgBoxRect(R, 'Replace this occurence ?',
  221.           nil, mfYesNoCancel + mfInformation);
  222.       end;
  223.   end;
  224. end;
  225.  
  226. { TTVDemo }
  227. constructor TTVDemo.Init;
  228. var
  229.   R: TRect;
  230.   I: Integer;
  231.   FileName: PathStr;
  232. begin
  233.   MaxHeapSize := HeapSize;
  234.   inherited Init('PC-X User Extended Turbo Vision Demo', '', '', '');
  235.   RegisterObjects;
  236.   RegisterViews;
  237.   RegisterMenus;
  238.   RegisterDialogs;
  239.   RegisterApp;
  240.   RegisterHelpFile;
  241.   RegisterPuzzle;
  242.   RegisterCalendar;
  243.   RegisterAsciiTab;
  244.   RegisterCalc;
  245.   RegisterEditors;
  246.  
  247.   { Initialize demo gadgets }
  248.  
  249.   GetExtent(R);
  250.   R.A.X := R.B.X - 9; R.B.Y := R.A.Y + 1;
  251.   Clock := New(PR4sClockView, Init(R));
  252.   Insert(Clock);
  253.  
  254.   GetExtent(R);
  255.   Dec(R.B.X);
  256.   R.A.X := R.B.X - 9; R.A.Y := R.B.Y - 1;
  257.   Heap := New(PHeapView, Init(R));
  258.   Insert(Heap);
  259.  
  260.   DisableCommands([cmSave, cmSaveAs, cmCut, cmCopy, cmPaste, cmClear,
  261.     cmUndo, cmFind, cmReplace, cmSearchAgain, cmCloseAll]);
  262.   EditorDialog := DoEditDialog;
  263.   ClipWindow := OpenEditor('', False);
  264.   if ClipWindow <> nil then
  265.   begin
  266.     Clipboard := ClipWindow^.Editor;
  267.     Clipboard^.CanUndo := False;
  268.   end;
  269.  
  270.   for I := 1 to ParamCount do
  271.   begin
  272.     FileName := ParamStr(I);
  273.     if FileName[Length(FileName)] = '\' then
  274.       FileName := FileName + '*.*';
  275.     if (Pos('?', FileName) = 0) and (Pos('*', FileName) = 0) then
  276.       OpenEditor(FExpand(FileName), True)
  277.     else FileOpen(FileName);
  278.   end;
  279. end;
  280.  
  281. function TTVDemo.OpenEditor(FileName: FNameStr; Visible: Boolean): PPCXEditBlueWindow;
  282. var
  283.   P: PView;
  284.   R: TRect;
  285. begin
  286.   DeskTop^.GetExtent(R);
  287.   P := Application^.ValidView(New(PPCXEditBlueWindow,
  288.     Init(R, FileName, wnNoNumber)));
  289.   if not Visible then P^.Hide;
  290.   DeskTop^.Insert(P);
  291.   OpenEditor := PPCXEditBlueWindow(P);
  292. end;
  293.  
  294. procedure TTVDemo.FileOpen(WildCard: PathStr);
  295. var
  296.   FileName: FNameStr;
  297. begin
  298.   FileName := '*.*';
  299.   if ExecuteDialog(New(PPCXFileDialog, Init(WildCard, 'Open a file',
  300.     '~N~ame', fdOpenButton + fdHelPButton, 100)), @FileName) <> cmCancel then
  301.     OpenEditor(FileName, True);
  302. end;
  303.  
  304. procedure TTVDemo.GetEvent(var Event: TEvent);
  305. var
  306.   W: PWindow;
  307.   HFile: PHelpFile;
  308.   HelpStrm: PDosStream;
  309. const
  310.   HelpInUse: Boolean = False;
  311. begin
  312.   inherited GetEvent(Event);
  313.   case Event.What of
  314.     evCommand:
  315.       if (Event.Command = cmHelp) and not HelpInUse then
  316.       begin
  317.         HelpInUse := True;
  318.         HelpStrm := New(PDosStream, Init(CalcHelpName, stOpenRead));
  319.         HFile := New(PHelpFile, Init(HelpStrm));
  320.         if HelpStrm^.Status <> stOk then
  321.         begin
  322.           PCXMsgBox('Could not open help file.', nil, mfError + mfOkButton);
  323.           Dispose(HFile, Done);
  324.         end
  325.         else
  326.         begin
  327.           W := New(PHelpWindow,Init(HFile, GetHelpCtx));
  328.           if ValidView(W) <> nil then
  329.           begin
  330.             ExecView(W);
  331.             Dispose(W, Done);
  332.           end;
  333.           ClearEvent(Event);
  334.         end;
  335.         HelpInUse := False;
  336.       end;
  337.     evMouseDown:
  338.       if Event.Buttons <> 1 then Event.What := evNothing;
  339.   end;
  340. end;
  341.  
  342. function TTVDemo.GetPalette: PPalette;
  343. const
  344.   CNewColor = CPCXColor + CHelpColor;
  345.   CNewBlackWhite = CPCXBlackWhite + CHelpBlackWhite;
  346.   CNewMonochrome = CPCXMonochrome + CHelpMonochrome;
  347.   P: array[apColor..apMonochrome] of string[Length(CNewColor)] =
  348.     (CNewColor, CNewBlackWhite, CNewMonochrome);
  349. begin
  350.   GetPalette := @P[AppPalette];
  351. end;
  352.  
  353. procedure TTVDemo.HandleEvent(var Event: TEvent);
  354.  
  355. procedure ChangeDir;
  356. var
  357.   D: PR4sChDirDialog;
  358. begin
  359.   D := New(PR4sChDirDialog, Init(cdNormal + cdHelPButton, 101));
  360.   D^.HelpCtx := hcFCChDirDBox;
  361.   ExecuteDialog(D, nil);
  362. end;
  363.  
  364. procedure Puzzle;
  365. var
  366.   P: PPuzzleWindow;
  367. begin
  368.   P := New(PPuzzleWindow, Init);
  369.   P^.HelpCtx := hcPuzzle;
  370.   InsertWindow(P);
  371. end;
  372.  
  373. procedure Calendar;
  374. var
  375.   P: PCalendarWindow;
  376. begin
  377.   P := New(PCalendarWindow, Init);
  378.   P^.HelpCtx := hcCalendar;
  379.   InsertWindow(P);
  380. end;
  381.  
  382. procedure About;
  383. var
  384.   D: PPCXBlueDialog;
  385.   Control: PView;
  386.   R: TRect;
  387. begin
  388.   R.Assign(0, 0, 40, 11);
  389.   D := New(PPCXBlueDialog, Init(R, 'About'));
  390.   with D^ do
  391.   begin
  392.     Options := Options or ofCentered;
  393.  
  394.     R.Grow(-1, -1);
  395.     Dec(R.B.Y, 3);
  396.     Insert(New(PStaticText, Init(R,
  397.       #13 +
  398.       ^C'Turbo Vision Demo'#13 +
  399.       #13 +
  400.       ^C'Copyright (c) 1992'#13 +
  401.       #13 +
  402.       ^C'Borland International')));
  403.  
  404.     R.Assign(15, 8, 25, 10);
  405.     Insert(New(PPCXButton, Init(R, 'O~K', cmOk, bfDefault)));
  406.   end;
  407.   if ValidView(D) <> nil then
  408.   begin
  409.     Desktop^.ExecView(D);
  410.     Dispose(D, Done);
  411.   end;
  412. end;
  413.  
  414. procedure AsciiTab;
  415. var
  416.   P: PAsciiChart;
  417. begin
  418.   P := New(PAsciiChart, Init);
  419.   P^.HelpCtx := hcAsciiTable;
  420.   InsertWindow(P);
  421. end;
  422.  
  423. procedure Calculator;
  424. var
  425.   P: PCalculator;
  426. begin
  427.   P := New(PCalculator, Init);
  428.   P^.HelpCtx := hcCalculator;
  429.   InsertWindow(P);
  430. end;
  431.  
  432. procedure Colors;
  433. var
  434.   D: PColorDialog;
  435. begin
  436.   D := New(PColorDialog, Init('',
  437.     ColorGroup('Desktop',       DesktopColorItems(nil),
  438.     ColorGroup('Menus',         MenuColorItems(nil),
  439.     ColorGroup('Dialogs/Calc',  DialogColorItems(dpGrayDialog, nil),
  440.     ColorGroup('Editor/Puzzle', WindowColorItems(wpBlueWindow, nil),
  441.     ColorGroup('Ascii table',   WindowColorItems(wpGrayWindow, nil),
  442.     ColorGroup('Calendar',
  443.       WindowColorItems(wpCyanWindow,
  444.       ColorItem('Current day',       22, nil)),
  445.       nil))))))));
  446.  
  447.   D^.HelpCtx := hcOCColorsDBox;
  448.  
  449.   if ExecuteDialog(D, Application^.GetPalette) <> cmCancel then
  450.   begin
  451.     DoneMemory;    { Dispose all group buffers }
  452.     ReDraw;        { Redraw application with new palette }
  453.   end;
  454. end;
  455.  
  456. procedure Mouse;
  457. var
  458.   D: PDialog;
  459.   P: PPCXBlueWindow;
  460.   PD: PPCXScrollBar;
  461.   R: TRect;
  462. begin
  463.   D := New(PMouseDialog, Init);
  464.   D^.HelpCtx := hcOMMouseDBox;
  465.   ExecuteDialog(D, @MouseReverse);
  466. (* {próba:}
  467.   R.Assign(1,1,50,15);
  468.   New(P, Init(R, 'asd', 0));
  469.  
  470.   with P^ do
  471.   begin
  472.     R.Assign(5,5,7,10);
  473.     New(PD, Init(R));
  474.     with PD^ do
  475.     begin
  476.       SetParams(3, 1, 10, 1,1);
  477.     end;
  478.     Insert(PD);
  479.   end;
  480.   InsertWindow(P);
  481.              *)
  482. end;
  483.  
  484. procedure RetrieveDesktop;
  485. var
  486.   S: PStream;
  487.   Signature: string[SignatureLen];
  488. begin
  489.   S := New(PBufStream, Init('TVDEMO.DSK', stOpenRead, 1024));
  490.   if LowMemory then OutOfMemory
  491.   else if S^.Status <> stOk then
  492.     PCXMsgBox('Could not open desktop file', nil, mfOkButton + mfError)
  493.   else
  494.   begin
  495.     Signature[0] := Char(SignatureLen);
  496.     S^.Read(Signature[1], SignatureLen);
  497.     if Signature = DSKSignature then
  498.     begin
  499.       LoadDesktop(S^);
  500.       LoadIndexes(S^);
  501.       LoadHistory(S^);
  502.       if S^.Status <> stOk then
  503.         PCXMsgBox('Error reading desktop file', nil, mfOkButton + mfError);
  504.     end
  505.     else
  506.       PCXMsgBox('Error: Invalid Desktop file.', nil, mfOkButton + mfError);
  507.   end;
  508.   Dispose(S, Done);
  509. end;
  510.  
  511. procedure SaveDesktop;
  512. var
  513.   S: PStream;
  514.   F: File;
  515. begin
  516.   S := New(PBufStream, Init('TVDEMO.DSK', stCreate, 1024));
  517.   if not LowMemory and (S^.Status = stOk) then
  518.   begin
  519.     S^.Write(DSKSignature[1], SignatureLen);
  520.     StoreDesktop(S^);
  521.     StoreIndexes(S^);
  522.     StoreHistory(S^);
  523.     if S^.Status <> stOk then
  524.     begin
  525.       PCXMsgBox('Could not create TVDEMO.DSK.', nil, mfOkButton + mfError);
  526.       {$I-}
  527.       Dispose(S, Done);
  528.       Assign(F, 'TVDEMO.DSK');
  529.       Erase(F);
  530.       Exit;
  531.     end;
  532.   end;
  533.   Dispose(S, Done);
  534. end;
  535.  
  536. procedure FileNew;
  537. begin
  538.   OpenEditor('', True);
  539. end;
  540.  
  541. procedure ShowClip;
  542. begin
  543.   ClipWindow^.Select;
  544.   ClipWindow^.Show;
  545. end;
  546.  
  547. begin
  548.   inherited HandleEvent(Event);
  549.   case Event.What of
  550.     evCommand:
  551.       begin
  552.         case Event.Command of
  553.           cmOpen: FileOpen('*.*');
  554.           cmNew: FileNew;
  555.           cmShowClip: ShowClip;
  556.           cmChangeDir: ChangeDir;
  557.           cmAbout: About;
  558.           cmPuzzle: Puzzle;
  559.           cmCalendar: Calendar;
  560.           cmAsciiTab: AsciiTab;
  561.           cmCalculator: Calculator;
  562.           cmColors: Colors;
  563.           cmMouse: Mouse;
  564.           cmSaveDesktop: SaveDesktop;
  565.           cmRetrieveDesktop: RetrieveDesktop;
  566.         else
  567.           Exit;
  568.         end;
  569.         ClearEvent(Event);
  570.       end;
  571.   end;
  572. end;
  573.  
  574. procedure TTVDemo.Idle;
  575.  
  576.   function IsTileable(P: PView): Boolean; far;
  577.   begin
  578.     IsTileable := (P^.Options and ofTileable <> 0) and
  579.       (P^.State and sfVisible <> 0);
  580.   end;
  581.  
  582. begin
  583.   inherited Idle;
  584.   Clock^.Update;
  585.   Heap^.Update;
  586.   if Desktop^.FirstThat(@IsTileable) <> nil
  587.   then EnableCommands([cmTile, cmCascade])
  588.   else DisableCommands([cmTile, cmCascade]);
  589. end;
  590.  
  591. procedure TTVDemo.InitMenuBar;
  592. var
  593.   R: TRect;
  594. begin
  595.   GetMenuBarExtent(R);
  596.   MenuBar := New(PPCXMenuBar, Init(R, NewMenu(
  597.     NewSubMenu('~'#240'~', hcSystem, NewMenu(
  598.       NewItem('~A~bout', '', kbNoKey, cmAbout, hcSAbout,
  599.       NewLine(
  600.       NewItem('~P~uzzle', '', kbNoKey, cmPuzzle, hcSPuzzle,
  601.       NewItem('Ca~l~endar', '', kbNoKey, cmCalendar, hcSCalendar,
  602.       NewItem('Ascii ~t~able', '', kbNoKey, cmAsciiTab, hcSAsciiTable,
  603.       NewItem('~C~alculator', '', kbNoKey, cmCalculator, hcCalculator, nil))))))),
  604.     NewSubMenu('~F~ile', hcFile, NewMenu(
  605.       StdFileMenuItems(nil)),
  606.     NewSubMenu('~E~dit', hcEdit, NewMenu(
  607.       StdEditMenuItems(
  608.       NewLine(
  609.       NewItem('~S~how clipboard', '', kbNoKey, cmShowClip, hcShowClip,
  610.       nil)))),
  611.     NewSubMenu('~S~earch', hcSearch, NewMenu(
  612.       NewItem('~F~ind...', '', kbNoKey, cmFind, hcFind,
  613.       NewItem('~R~eplace...', '', kbNoKey, cmReplace, hcReplace,
  614.       NewItem('~S~earch again', '', kbNoKey, cmSearchAgain, hcSearchAgain,
  615.       nil)))),
  616.     NewSubMenu('~W~indow', hcWindows, NewMenu(
  617.       StdWindowMenuItems(nil)),
  618.     NewSubMenu('~O~ptions', hcOptions, NewMenu(
  619.       NewItem('~M~ouse...', '', kbNoKey, cmMouse, hcOMouse,
  620.       NewItem('~C~olors...', '', kbNoKey, cmColors, hcOColors,
  621.       NewLine(
  622.       NewItem('~S~ave desktop', '', kbNoKey, cmSaveDesktop, hcOSaveDesktop,
  623.       NewItem('~R~etrieve desktop', '', kbNoKey, cmRetrieveDesktop, hcORestoreDesktop, nil)))))),
  624.       nil)))))))));
  625. end;
  626.  
  627. procedure TTVDemo.InitStatusLine;
  628. var
  629.   R: TRect;
  630. begin
  631.   GetExtent(R);
  632.   R.A.Y := R.B.Y - 1;
  633.   StatusLine := New(PStatusLine, Init(R,
  634.     NewStatusDef(0, $FFFF,
  635.       NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
  636.       NewStatusKey('~F1~ Help', kbF1, cmHelp,
  637.       NewStatusKey('~F3~ Open', kbF3, cmOpen,
  638.       NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
  639.       NewStatusKey('~F5~ Zoom', kbF5, cmZoom,
  640.       NewStatusKey('', kbF10, cmMenu,
  641.       NewStatusKey('', kbCtrlF5, cmResize,
  642.       nil))))))),
  643.     nil)));
  644. end;
  645.  
  646. procedure TTVDemo.OutOfMemory;
  647. begin
  648.   PCXMsgBox('Not enough memory available to complete operation.',
  649.     nil, mfError + mfOkButton);
  650. end;
  651.  
  652. { Since the safety pool is only large enough to guarantee that allocating
  653.   a window will not run out of memory, loading the entire desktop without
  654.   checking LowMemory could cause a heap error.  This means that each
  655.   window should be read individually, instead of using Desktop's Load.
  656. }
  657.  
  658. procedure TTVDemo.LoadDesktop(var S: TStream);
  659. var
  660.   P: PView;
  661.   Pal: PString;
  662.  
  663. procedure CloseView(P: PView); far;
  664. begin
  665.   Message(P, evCommand, cmClose, nil);
  666. end;
  667.  
  668. begin
  669.   if Desktop^.Valid(cmClose) then
  670.   begin
  671.     Desktop^.ForEach(@CloseView); { Clear the desktop }
  672.     repeat
  673.       P := PView(S.Get);
  674.       Desktop^.InsertBefore(ValidView(P), Desktop^.Last);
  675.     until P = nil;
  676.     Pal := S.ReadStr;
  677.     if Pal <> nil then
  678.     begin
  679.       Application^.GetPalette^ := Pal^;
  680.       DoneMemory;
  681.       Application^.ReDraw;
  682.       DisposeStr(Pal);
  683.     end;
  684.   end;
  685. end;
  686.  
  687. procedure TTVDemo.StoreDesktop(var S: TStream);
  688. var
  689.   Pal: PString;
  690.  
  691. procedure WriteView(P: PView); far;
  692. begin
  693.   if P <> Desktop^.Last then S.Put(P);
  694. end;
  695.  
  696. begin
  697.   Desktop^.ForEach(@WriteView);
  698.   S.Put(nil);
  699.   Pal := @Application^.GetPalette^;
  700.   S.WriteStr(Pal);
  701. end;
  702.  
  703.  
  704. var Demo: TTVDemo;
  705.  
  706. BEGIN
  707.   SetPCXGraphChars(True);
  708.   SetR4sGraphChars(True);
  709.   Demo.Init;
  710.   Demo.Run;
  711.   Demo.Done;
  712. END.