home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / tvision / gravis / gv / demo.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-05-23  |  17.4 KB  |  652 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Graphics Vision Demo program                    }
  5. {                                                       }
  6. {       Copyright (c) 1993 Stefan Milius                }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. Program Demo;
  11.  
  12. { Dieses Programm demonstriert die Fähigkeiten der grafischen Oberfläche
  13.   Graphics Vision. Es ist nur lauffähig, wenn zuvor die zugehörige
  14.   Resourcendatei mit Hilfe des Programs DEMOREZ.PAS generiert wird.
  15.   Es ist nicht nötig den Grafiktreiber (BGI) in das Programm zu linken.
  16.   Dies wird durch GV automatisch erledigt.
  17.  
  18.   This program demonstrates the abilities of the graphical environment
  19.   Graphics Vision. It is only executable if you first build the accessory
  20.   resource file using DEMOREZ.PAS. It is not neccessary to link the graphic
  21.   driver (BGI) into the program. This is done by GV automatically.
  22. }
  23.  
  24. {$DEFINE change}
  25.  
  26. Uses CRT, Dos, Objects, Drivers, GVDriver, Views, GVViews, GVDialog, GVMenus,
  27.      GVGadget, GVStdDlg, GVMsgBox, GVColor, GVApp, Graph, BGI, DemoType,
  28.      MyMouse, ExtGraph, MetaGr, HistList;
  29.  
  30. const
  31.  
  32. { Palettes }
  33.  
  34.   CTextInterior = #21#19;
  35.  
  36. type
  37.  
  38. { TDemoApp object }
  39.  
  40.   PDemoApp = ^TDemoApp;
  41.   TDemoApp = object (TApplication)
  42.                Heap: PHeapView;
  43.                Clock: PClockView;
  44.                constructor Init;
  45.                procedure InitMenuBar; virtual;
  46.                procedure InitStatusLine; virtual;
  47.                procedure InitDesktop; virtual;
  48.                procedure HandleEvent (var Event: TEvent); virtual;
  49.                procedure Idle; virtual;
  50.              private
  51.                Tune: Word;
  52.                TuneEnabled: Boolean;
  53.                procedure Play;
  54.              end;
  55.  
  56. { TTextInterior object }
  57.  
  58.   PTextInterior = ^TTextInterior;
  59.   TTextInterior = object (TScroller)
  60.                     Strings: TStringCollection;
  61.                     constructor Init (var Bounds: TRect; AHScrollBar,
  62.                         AVScrollBar: PScrollBar; FileName: PathStr);
  63.                     destructor Done; virtual;
  64.                     procedure Draw; virtual;
  65.                     function GetPalette: PPalette; virtual;
  66.                     procedure HandleEvent(var Event: TEvent); virtual;
  67.                   private
  68.                     procedure ReadFile (FileName: PathStr); virtual;
  69.                   end;
  70.  
  71. { TTextWindow object }
  72.  
  73.   PTextWindow = ^TTextWindow;
  74.   TTextWindow = object (TWindow)
  75.                   constructor Init (var Bounds: TRect; WinTitle: String);
  76.                 end;
  77.  
  78. { TKoord record }
  79.  
  80.   PKoord = ^TKoord;
  81.   TKoord = record
  82.              x, y, r: Integer;
  83.              Col, fCol: Byte;
  84.            end;
  85.  
  86. { TKoordCollection object }
  87.  
  88.   PKoordCollection = ^TKoordCollection;
  89.   TKoordCollection = object (TCollection)
  90.                        procedure FreeItem (Item: Pointer); virtual;
  91.                      end;
  92.  
  93. { TGraphicsInterior object }
  94.  
  95.   PGraphicInterior = ^TGraphicInterior;
  96.   TGraphicInterior = object (TGView)
  97.                        Rect: TRect;
  98.                        Koords: TKoordCollection;
  99.                        constructor Init (var Bounds: TRect);
  100.                        destructor Done; virtual;
  101.                        procedure Draw; virtual;
  102.                        procedure DrawRect; virtual;
  103.                        procedure ChMCursor; virtual;
  104.                        procedure HandleEvent (var Event: TEvent); virtual;
  105.                      end;
  106.  
  107.   PGraphicWindow = ^TGraphicWindow;
  108.   TGraphicWindow = object (TWindow)
  109.                      constructor Init (var Bounds: TRect; WinTitle: String);
  110.                    end;
  111.  
  112. (***************************** TDemoApp object ******************************)
  113.  
  114. constructor TDemoApp.Init;
  115. var R: TRect;
  116.     Treiber, Mode: Integer;
  117.     RezName: PathStr;
  118.  
  119. Begin
  120.   If Lo (DosVersion)>=3 then RezName := 'DEMO.REZ'
  121.   Else Begin
  122.     RezName := FSearch('DEMO.REZ', GetEnv('PATH'));
  123.     If RezName = '' then WriteLn ('DEMO.REZ konnte nicht gefunden werden');
  124.     Halt(2);
  125.   End;
  126.  
  127.   { Setting language }
  128.  
  129.   {$IFDEF change}
  130.   {$IFDEF english }
  131.   Language := lfEnglish;
  132.   {$ENDIF}
  133.   {$ENDIF}
  134.  
  135.   { Initialize resource file }
  136.  
  137.   RezStream := New(PProtectedStream, Init (RezName, stOpenRead, 4096));
  138.   RezFile.Init(RezStream);
  139.  
  140.   RegisterType (RStringList);
  141.   RegisterDemo;
  142.  
  143.   StatusHints:=PStringList (RezFile.Get ('StatusHints'));
  144.  
  145.   { Initialize Application }
  146.  
  147.   {$IFNDEF VER60}
  148.   PathToDriver := 'C:\BP\BGI';
  149.   {$ELSE}
  150.   PathToDriver := 'C:\TP\BGI';
  151.   {$ENDIF}
  152.  
  153.         (* Vergessen Sie nie diese Variable vor der Initialisierung
  154.            der Applikation zu setzen, wenn Sie BGI Routinen zur Ausgabe
  155.            verwenden möchten.
  156.  
  157.            Do never forget to set this variable before initializing
  158.            the application if you wish to use BGI routines.
  159.         *)
  160.  
  161.   WindowCmds := WindowCmds + [cmCloseAll];
  162.   DisableCommands([cmCloseAll]);
  163.   TApplication.Init;
  164.  
  165.   R.Assign (Size.X-71, Size.Y-21, Size.X+1, Size.Y+1);
  166.   Heap:=New (PHeapView, Init (R));
  167.   If Heap<>nil then Insert (Heap);
  168.   R.Assign (Size.X-71, -1, Size.X+1, 21);
  169.   Clock:=New (PClockView, Init (R));
  170.   If Clock<>nil then Insert (Clock);
  171.  
  172.   Tune := cmIndyTune;
  173.   TuneEnabled := true;
  174. End;
  175.  
  176. procedure TDemoApp.InitMenuBar;
  177. Begin
  178.   MenuBar := PMenuBar (RezFile.Get ('MenuBar'));
  179. End;
  180.  
  181. procedure TDemoApp.InitStatusLine;
  182. Begin
  183.   StatusLine := PDemoStatusLine (RezFile.Get ('StatusLine'));
  184. End;
  185.  
  186. procedure TDemoApp.InitDesktop;
  187. Begin
  188.   Desktop := PDesktop (RezFile.Get ('Desktop'));
  189. End;
  190.  
  191. procedure TDemoApp.HandleEvent;
  192.  
  193.  procedure FileOpen;
  194.  var D: PDialog;
  195.      C: Word;
  196.      Filename: PathStr;
  197.      R: TRect;
  198.  Begin
  199.    D := PFileDialog (RezFile.Get ('FOpenDlg'));
  200.    If ValidView (D)<> nil then Begin
  201.      C:=Desktop^.ExecView (D);
  202.  
  203.      If C=cmFileOpen then Begin
  204.        D^.GetData (Filename);
  205.        Desktop^.GetExtent (R);
  206.        Desktop^.Insert (New (PTextWindow, Init (R, Filename)));
  207.      End;
  208.  
  209.      Dispose (D, Done);
  210.    End;
  211.  End;
  212.  
  213.  procedure ChangeDir;
  214.  var D: PDialog;
  215.  Begin
  216.    D := PChDirDialog (RezFile.Get ('FChDirDlg'));
  217.    If ValidView (D)<> nil then Begin
  218.      Desktop^.ExecView (D);
  219.      Dispose (D, Done);
  220.    End;
  221.  End;
  222.  
  223.  procedure ColorDlg;
  224.  var D: PDialog;
  225.  Begin
  226.    D := PColorDialog (RezFile.Get ('ColorDlg'));
  227.  
  228.    If ValidView (D)<> nil then Begin
  229.      D^.SetData (Application^.GetPalette^);
  230.      If Desktop^.ExecView (D) = cmOK then Begin
  231.        D^.GetData (Application^.GetPalette^);
  232.        ReDraw;
  233.      End;
  234.      Dispose (D, Done);
  235.    End;
  236.  End;
  237.  
  238.  procedure ShowInfo;
  239.  var D: PDialog;
  240.  Begin
  241.    D := PDialog (RezFile.Get ('Info'));
  242.    If ValidView (D) <> nil then Begin
  243.      Desktop^.ExecView (D);
  244.      Dispose (D, Done);
  245.    End;
  246.  End;
  247.  
  248.  procedure NewGWindow;
  249.  const Count: Word = 1;
  250.        Texts: Array [1..2] of String[23] =
  251.           ('Graphical window no. ','Grafisches Fenster Nr. ');
  252.  var S: String [5];
  253.      R: TRect;
  254.  Begin
  255.    Str (Count, S);
  256.    Desktop^.GetExtent (R);
  257.    Desktop^.Insert (New (PGraphicWindow, Init (R, Texts[Language]+S)));
  258.  
  259.          (* Graphics Vision unterstützt sowohl die englische als auch die
  260.             deutsche Sprache. Die Variable Language (UNIT GVApp) wird auf
  261.             einen Wert, der die entsprechende Sprache symbolisiert, gesetzt
  262.             und wird bei der Erzeugung von Fensterüberschriften u.s.w.
  263.             ausgewertet (z.B. in GVStdDlg).
  264.  
  265.             Graphics Vision supports the English as well as the German
  266.             language. To use a particular language just set the variable
  267.             Language (UNIT GVApp). It is examined e.g. when creating
  268.             window headlines (e.g. in GVStdDlg).
  269.  
  270.          *)
  271.  
  272.    Inc (Count);
  273.  End;
  274.  
  275.  procedure NewDialog;
  276.  var D: PDialog;
  277.  {$IFDEF VER60}
  278.      S: String;
  279.  {$ENDIF}
  280.  const Texts: Array [1..2] Of String[31] =
  281.            ('A list for input recording!',
  282.         'Eine Eingabeaufzeichnungsliste!');
  283.  Begin
  284.    D := PDialog (RezFile.Get ('DemoDialog'));
  285.    If ValidView (D)<>nil then Begin
  286.      {$IFNDEF VER60}
  287.      HistoryAdd(40, Texts[Language]);
  288.      {$ELSE}
  289.      S := Texts[Language];
  290.      HistoryAdd(40, S);
  291.      {$ENDIF}
  292.      If TuneEnabled then Play;
  293.      Desktop^.ExecView (D);
  294.      Dispose (D, Done);
  295.    End;
  296.  End;
  297.  
  298.  procedure CloseAll;
  299.  var Win, NWin: PGView;
  300.  Begin
  301.    Win := Desktop^.First;
  302.    With Desktop^ do While (Win <> Last) and (Win <> nil) do Begin
  303.      NWin := Win^.NextView;
  304.      Message(Win, evCommand, cmClose, nil);
  305.      Win := NWin;
  306.    End;
  307.  End;
  308.  
  309. const Texts: Array [1..2,0..2] of String[86] =
  310.     ((#13'A standard information box in Graphics Vision', 'By the way...',
  311.       '... in Graphics Vision there are information boxes with user defined '+
  312.       'window headlines.'),
  313.      (#13'Eine Standard Informations - Box in Graphics Vision','Übrigens...',
  314.       '... es gibt in Graphics Vision auch Info-Boxen mit veränderlichen '+
  315.       'Überschriften.'));
  316. Begin
  317.   TApplication.HandleEvent (Event);
  318.   If Event.What = evCommand then Begin
  319.     Case Event.Command Of
  320.       cmOpen        : FileOpen;
  321.       cmChDir       : ChangeDir;
  322.       cmColor       : ColorDlg;
  323.       cmInfo        : ShowInfo;
  324.       cmGWindow     : NewGWindow;
  325.       cmDialog      : NewDialog;
  326.       cmCloseAll    : CloseAll;
  327.       cmEnableMusic : TuneEnabled := not TuneEnabled;
  328.       cmIndyTune,
  329.       cmNormalTune  : Tune := Event.Command;
  330.       cmPlay        : Play;
  331.      else Exit;
  332.     End;
  333.     ClearEvent (Event);
  334.   End
  335.   Else If Event.What = evBroadCast then Begin
  336.          Case Event.Command Of
  337.            cmGButton : MessageBox (Texts[Language,0], nil, mfOKCancel+mfInformation);
  338.            cmButton  : MessageBoxTitle (Texts[Language,1], Texts[Language,2],
  339.                           nil, mfOKCancel + mfError);
  340.           else Exit;
  341.          End;
  342.          ClearEvent (Event);
  343.        End;
  344. End;
  345.  
  346. procedure TDemoApp.Idle;
  347. Begin
  348.   TApplication.Idle;
  349.   Heap^.UpDate;
  350.   Clock^.UpDate;
  351. End;
  352.  
  353. procedure TDemoApp.Play;
  354. var I, J: Integer;
  355. Begin
  356.   If Tune = cmIndyTune then Begin
  357.     SetCurrentCursor(mcHourGlass);
  358.     Sound (659 {Round (164.810*4)});
  359.     Delay (220);
  360.     NoSound;
  361.     Delay (30);
  362.  
  363.     Sound (698 {Round (174.610*4)});
  364.     Delay (150);
  365.     NoSound;
  366.  
  367.     Sound (784 {Round (196.000*4)});
  368.     Delay (100);
  369.     NoSound;
  370.     Delay (200);
  371.  
  372.     Sound (1047 {Round (261.630*4)});
  373.     Delay (600);
  374.     NoSound;
  375.     SetCurrentCursor(mcNoCursor);
  376.   End else If Tune = cmNormalTune then Begin
  377.     SetCurrentCursor(mcHourGlass);
  378.     For J := 1 to 3 do
  379.       For I := 50 to 1000 do Begin
  380.         Sound(I);
  381.         Delay(1);
  382.        End;
  383.     NoSound;
  384.     SetCurrentCursor(mcNoCursor);
  385.   End;
  386. End;
  387.  
  388. (*************************** TTextInterior object ***************************)
  389.  
  390. constructor TTextInterior.Init;
  391. Begin
  392.   TScroller.Init (Bounds, AHScrollBar, AVScrollBar);
  393.   GrowMode:=gfGrowHiX + gfGrowHiY;
  394.   ReadFile (FileName);
  395. End;
  396.  
  397. destructor TTextInterior.Done;
  398. Begin
  399.   Strings.Done;
  400.   TGView.Done;
  401. End;
  402.  
  403. procedure TTextInterior.Draw;
  404. var I: Integer;
  405.     C: Byte;
  406.     R: TRect;
  407.     S: String;
  408. Begin
  409.   SetViewPort;
  410.   HideMouse;
  411.   { Hintergrund - background }
  412.   SetFillStyle (SolidFill, GetColor (1));
  413.   Bar (0, 0, Size.X-1, Size.Y-1);
  414.   { Text }
  415.   SetGVStyle (ftMonoSpace);
  416.   R.Assign (0, 0, Size.X, 18);
  417.   C:=GetColor (2);
  418.   For I:=Delta.Y to Delta.Y + Size.Y div TextSize.Y do
  419.     If I<Strings.Count then Begin
  420.       S:=PString (Strings.At (I))^;
  421.       Delete (S, 1, Delta.X);
  422.       OutGVText (R.A, S, C, C, R.B, false);
  423.       Inc (R.A.Y, 18);
  424.     End;
  425.   ShowMouse;
  426.   RestoreViewPort;
  427. End;
  428.  
  429. procedure TTextInterior.ReadFile;
  430. var F: Text;
  431.     S: String;
  432.     I: Integer;
  433. Begin
  434.   Strings.Init (30,10);
  435.   Strings.Duplicates:=true;
  436.   Assign (F, FileName);
  437.   {$I-}
  438.   Reset (F);
  439.   While not EOF (F) and (IOResult = 0) do Begin
  440.     ReadLn (F, S);
  441.     If S='' then S:=' ';
  442.     Strings.AtInsert (Strings.Count, NewStr (S));
  443.   End;
  444.   Close (F);
  445.   {$I+}
  446.   SetLimit (100, Strings.Count);
  447. End;
  448.  
  449. function TTextInterior.GetPalette;
  450. const
  451.   P: String [Length (CTextInterior)] = CTextInterior;
  452. Begin
  453.   GetPalette:=@P;
  454. End;
  455.  
  456. procedure TTextInterior.HandleEvent;
  457. var M: PGView;
  458.     R: TRect;
  459.     P: TPoint;
  460. Begin
  461.   TScroller.HandleEvent(Event);
  462.   If ((Event.What = evMouseDown) and (Event.Buttons = mbRightButton) and
  463.        MouseInView(Event.Where)) or
  464.      ((Event.What = evCommand) and (Event.Command = cmLocalMenu)) then Begin
  465.     M := PGView(RezFile.Get('LocalMenu'));
  466.     LongInt(P) := 0; MakeGlobal(P, P);
  467.     M^.GetExtent(R);
  468.     R.Move(Size.X div 2 - M^.Size.X div 2 + P.X,
  469.            Size.Y div 2 - M^.Size.Y div 2 + P.Y);
  470.     M^.ChangeBounds(R);
  471.     Application^.ExecView(M);
  472.   End;
  473. End;
  474.  
  475. (**************************** TTextWindow object ****************************)
  476.  
  477. constructor TTextWindow.Init;
  478. var R: TRect;
  479. Begin
  480.   TWindow.Init (Bounds, WinTitle);
  481.   HelpCtx := hcTextWindow;
  482.   Delete (Background);
  483.   Dispose (Background,Done);
  484.   Background:=nil;
  485.   GetExtent (R);
  486.   R.Grow (-4,-4);
  487.   R.A.Y:=23;
  488.   Dec (R.B.X, 17); Dec (R.B.Y, 17);
  489.   Insert (New (PTextInterior, Init (R,
  490.     StandardScrollBar (sbHorizontal+sbHandleKeyboard),
  491.     StandardScrollBar (sbVertical+sbHandleKeyboard),
  492.     WinTitle)));
  493. End;
  494.  
  495. (*************************** TKoordCollection object ************************)
  496.  
  497. procedure TKoordCollection.FreeItem;
  498. Begin
  499.   Dispose (PKoord (Item));
  500. End;
  501.  
  502. (*************************** TGraphicInterior object ************************)
  503.  
  504. constructor TGraphicInterior.Init;
  505. var I: Integer;
  506.     K: PKoord;
  507. Begin
  508.   TGView.Init (Bounds);
  509.   Options:=Options or ofPostProcess;
  510.   GrowMode:=gfGrowHiX + gfGrowHiY;
  511.   GetExtent (Rect);
  512.  
  513.   Koords.Init (20,5);
  514.   Randomize;
  515.   For I:=1 to 10 do Begin
  516.     New (K);
  517.     With K^ do Begin
  518.       x:=Random (Size.X);
  519.       y:=Random (Size.Y);
  520.       r:=Random (Size.Y div 3)+1;
  521.       Col:=Random (15)+1;
  522.       fCol:=Random (15)+1;
  523.     End;
  524.     Koords.Insert (K);
  525.   End;
  526. End;
  527.  
  528. destructor TGraphicInterior.Done;
  529. Begin
  530.   Koords.Done;
  531.   TGView.Done;
  532. End;
  533.  
  534. procedure TGraphicInterior.Draw;
  535. { Wichtig ist es, erst SetViewPort und dann HideMouse aufzurufen, um ein
  536.   unnötiges Flackern des Mauskursors zu vermeiden.
  537.  
  538.   It is important to call SetViewPort first and then HideMouse to avoid
  539.   an unneccessary flicker of the mouse cursor.
  540. }
  541. var I: Integer;
  542.     K: TKoord;
  543. const Pattern: FillPatternType = ($55,$AA,$55,$AA,$55,$AA,$55,$AA);
  544. Begin
  545.   SetViewPort;
  546.   HideMouse;
  547.   SetFillStyle (SolidFill, Black);
  548.   Bar (0, 0, Size.X-1, Size.Y-1);
  549.   For I:=0 to Koords.Count-1 do Begin
  550.     K:=PKoord (Koords.At (I))^;
  551.     SetColor (K.Col);
  552.     SetFillStyle (SolidFill, K.fCol);
  553.     FillCircle (K.x, K.y, K.r);
  554.   End;
  555.   { Ausgaben mit BGI-Routinen - using BGI routines }
  556.   SetFillPattern (Pattern, White);
  557.   SetColor (DarkGray);
  558.   FillEllipse (200,100,100,50);
  559.  
  560.    (* Bei Ausgaben mit BGI-Routinen, die nicht durch die Unit BGI
  561.       bereitgestellt werden, muß zuvor die Routine GrClipBgi (Unit BGI)
  562.       aufgerufen werden. Außerdem müssen zu den Ausgabekoordinaten
  563.       die Werte BgiX bzw. BgiY addiert werden.
  564.  
  565.       When using BGI routines which are not supported by the unit BGI
  566.       you first have to call GrClipBgi (unit BGI). Besides you will have
  567.       to add the values BgiX or BgiY to the draw coordinates.
  568.    *)
  569.  
  570.   Graph.SetColor (LightRed);
  571.   Graph.SetFillStyle (SolidFill, LightRed);
  572.   GrClipBgi;
  573.   PieSlice (400 + BgiX, 200 + BgiY, 0, 285, 70);
  574.   ShowMouse;
  575.   RestoreViewPort;
  576.   DrawRect;
  577. End;
  578.  
  579. procedure TGraphicInterior.DrawRect;
  580. Begin
  581.   SetViewPort;
  582.   HideMouse;
  583.   SetColor (White);
  584.   SetWriteMode (XORPut);
  585.   With Rect do Rectangle (A.X, A.Y, B.X, B.Y);
  586.   SetWriteMode (NormalPut);
  587.   ShowMouse;
  588.   RestoreViewPort;
  589. End;
  590.  
  591. procedure TGraphicInterior.ChMCursor;
  592. var R: TRect;
  593. Begin
  594.   R.Assign (0,0,Size.X,Size.Y);
  595.   MakeGlobal (R.A, R.A);
  596.   MakeGlobal (R.B, R.B);
  597.   If R.Contains (MyMouse.MouseWhere) then NewNum:=mcLargeCross;
  598. End;
  599.  
  600. procedure TGraphicInterior.HandleEvent;
  601. var EvWhere: TPoint;
  602.     First: Boolean;
  603. Begin
  604.   TGView.HandleEvent (Event);
  605.   If (Event.What=evMouseDown) and MouseInView (Event.Where) then Begin
  606.     First:=True;
  607.     Repeat
  608.       MakeLocal (Event.Where, EvWhere);
  609.       If (Rect.B.X <> EvWhere.X) or (Rect.B.Y <> EvWhere.Y) then Begin
  610.         DrawRect;
  611.         If First then Begin
  612.           Rect.A:=EvWhere;
  613.           First:=False;
  614.         End;
  615.         Rect.B:=EvWhere;
  616.         DrawRect;
  617.       End;
  618.     Until not MouseEvent (Event, evMouseMove+evMouseAuto);
  619.   End;
  620. End;
  621.  
  622. (*************************** TGraphicWindow object **************************)
  623.  
  624. constructor TGraphicWindow.Init;
  625. var R: TRect;
  626. Begin
  627.   TWindow.Init (Bounds, WinTitle);
  628.   Options := Options and not (ofBuffer+ofMetaFile);
  629.  
  630.   (* Da ein TGraphicsWindow ein Objekt enthält, daß BGI-Routinen bei der
  631.      Ausgabe nutzt, müssen die Flags ofBuffer und ofMetaFile gelöscht werden.
  632.  
  633.      Because a TGraphicWindow contains an object that uses BGI routines to
  634.      draw the flags ofBuffer and ofMetaFile has to be cleared in Options.
  635.   *)
  636.  
  637.   Delete (Background);
  638.   Dispose (Background,Done);
  639.   Background:=nil;
  640.   GetExtent (R);
  641.   R.Grow (-4,-4);
  642.   R.A.Y:=23;
  643.   Insert (New (PGraphicInterior, Init (R)));
  644. End;
  645.  
  646. var DemoApp: TDemoApp;
  647.  
  648. Begin
  649.   DemoApp.Init;
  650.   DemoApp.Run;
  651.   DemoApp.Done;
  652. End.