home *** CD-ROM | disk | FTP | other *** search
/ Shareware Supreme Volume 6 #1 / swsii.zip / swsii / 215 / DDJ11A92.ZIP / TVTIME.ASC < prev    next >
Text File  |  1992-10-29  |  11KB  |  450 lines

  1. _EXTENDING TURBO VISION_
  2. by Scott Nichol
  3.  
  4. [LISTING ONE]
  5.  
  6.  
  7. {***********************************************************************}
  8. {   BIOSTICK.PAS                                                        }
  9. {                                                                       }
  10. {   Support for BIOS tick counter.  The new BIOS tick event is of class }
  11. {   evMetaBroadcast, command cmBiosTick.  The Event.InfoLong field      }
  12. {   contains the tick counter value at the time of the event.  The      }
  13. {   current value can be obtained using the GetBiosTicks function.      }
  14. {   Because this event is generated on a cooperative rather than        }
  15. {   preemptive basis, there may not be an event generated for every     }
  16. {   tick of the counter.  Nor should any assumptions be made about the  }
  17. {   accuracy of the periodicity of the event: the nominal periodicity   }
  18. {   of 55 milliseconds will only be obtained when no other events are   }
  19. {   generated and cmBiosTick handling takes under 55 milliseconds.      }
  20. {***********************************************************************}
  21.  
  22. {$R-,S-}
  23.  
  24. unit
  25.   BiosTick;
  26.  
  27. interface
  28.  
  29. uses
  30.   Drivers;
  31.  
  32. procedure GetBiosTickEvent(var Event: TEvent);
  33. function GetBiosTicks: LongInt;
  34.  
  35. implementation
  36.  
  37. uses
  38.   Cmds;
  39.  
  40. var
  41.   BiosTicks: LongInt absolute $40:$6c;
  42.  
  43. procedure GetBiosTickEvent(var Event: TEvent);
  44. const
  45.   OldTicks: LongInt = 0;
  46. begin
  47.   if BiosTicks <> OldTicks then begin
  48.     OldTicks := BiosTicks;
  49.     with Event do begin
  50.       What := evMetaBroadcast;
  51.       Command := cmBiosTick;
  52.       InfoLong := OldTicks;
  53.     end;
  54.   end else
  55.     Event.What := evNothing;
  56. end;
  57.  
  58. function GetBiosTicks: LongInt;
  59. begin
  60.   GetBiosTicks := BiosTicks;
  61. end;
  62.  
  63. end.
  64.  
  65. [LISTING TWO]
  66.  
  67. {***********************************************************************}
  68. {   TICKVIEW.PAS                                                        }
  69. {                                                                       }
  70. {   Views to be driven by cmBiosTick.  The heap and clock views were    }
  71. {   inspired by the Gadgets unit provided by Borland in the TVDEMOS     }
  72. {   subdirectory of Turbo Pascal 6.0.                                   }
  73. {***********************************************************************}
  74.  
  75. unit TickView;
  76.  
  77. {$R-,S-,V-}
  78.  
  79. interface
  80.  
  81. uses
  82.   Drivers, Objects, Views, App;
  83.  
  84. type
  85.   PTickView = ^TTickView;
  86.   TTickView = object(TView)
  87.     Display: Boolean;
  88.     constructor Init(var Bounds: TRect);
  89.     procedure Draw; virtual;
  90.     procedure HandleEvent(var Event: TEvent); virtual;
  91.     function DoDraw: Boolean; virtual;
  92.     procedure DrawInfo(var S: String); virtual;
  93.     procedure ToggleDisplay; virtual;
  94.   end;
  95.  
  96.   PHeapView = ^THeapView;
  97.   THeapView = object(TTickView)
  98.     OldMem: LongInt;
  99.     constructor Init(var Bounds: TRect);
  100.     function DoDraw: Boolean; virtual;
  101.     procedure DrawInfo(var S: String); virtual;
  102.   end;
  103.  
  104.   PClockView = ^TClockView;
  105.   TClockView = object(TTickView)
  106.     OldTime: LongInt;
  107.     TimeStr: String[8];
  108.     constructor Init(var Bounds: TRect);
  109.     function DoDraw: Boolean; virtual;
  110.     procedure DrawInfo(var S: String); virtual;
  111.   end;
  112.  
  113. implementation
  114.  
  115. uses
  116.   Dos,
  117.   BiosTick, Cmds;
  118.  
  119. {------ TTickView (abstract) ------}
  120.  
  121. constructor TTickView.Init(var Bounds: TRect);
  122. begin
  123.   TView.Init(Bounds);
  124.   EventMask := EventMask or evMetaBroadcast;
  125.   Display := True;
  126. end;
  127.  
  128. procedure TTickView.Draw;
  129. var
  130.   S: String;
  131.   B: TDrawBuffer;
  132.   C: Byte;
  133. begin
  134.   C := GetColor(2);
  135.   MoveChar(B, ' ', C, Size.X);
  136.   DrawInfo(S);
  137.   if Display then
  138.     MoveStr(B, S, C);
  139.   WriteLine(0, 0, Size.X, 1, B);
  140. end;
  141.  
  142. procedure TTickView.HandleEvent(var Event: TEvent);
  143. begin
  144.   TView.HandleEvent(Event);
  145.   if Event.What = evMetaBroadcast then
  146.     case Event.Command of
  147.     cmBiosTick:
  148.       if DoDraw then DrawView;
  149.     end;
  150. end;
  151.  
  152. function TTickView.DoDraw: Boolean;
  153. begin
  154.   Abstract;
  155. end;
  156.  
  157. procedure TTickView.DrawInfo(var S: String);
  158. begin
  159.   Abstract;
  160. end;
  161.  
  162. procedure TTickView.ToggleDisplay;
  163. begin
  164.   Display := not Display;
  165.   DrawView;
  166. end;
  167.  
  168. {----------- THeapView ------------}
  169.  
  170. constructor THeapView.Init(var Bounds: TRect);
  171. begin
  172.   TTickView.Init(Bounds);
  173.   OldMem := 0;
  174. end;
  175.  
  176. function THeapView.DoDraw: Boolean;
  177. begin
  178.   DoDraw := OldMem <> MemAvail;
  179. end;
  180.  
  181. procedure THeapView.DrawInfo(var S: String);
  182. begin
  183.   OldMem := MemAvail;
  184.   Str(OldMem: Size.X, S);
  185. end;
  186.  
  187. {---------- TClockView ------------}
  188.  
  189. constructor TClockView.Init(var Bounds: TRect);
  190. begin
  191.   TTickView.Init(Bounds);
  192.   OldTime := 0;
  193. end;
  194.  
  195. function TClockView.DoDraw: Boolean;
  196. begin
  197.   DoDraw := (GetBiosTicks - OldTime) >= 18;
  198. end;
  199.  
  200. procedure TClockView.DrawInfo(var S: String);
  201. var
  202.   Hour, Minute, Second, Sec100: Word;
  203.   Param: record
  204.     Hr, Min, Sec: LongInt;
  205.   end;
  206. begin
  207.   OldTime := GetBiosTicks;
  208.   GetTime(Hour, Minute, Second, Sec100);
  209.   with Param do begin
  210.     Hr := Hour;
  211.     Min := Minute;
  212.     Sec := Second;
  213.   end;
  214.   FormatStr(S, '%02d:%02d:%02d', Param);
  215. end;
  216.  
  217. end.
  218.  
  219.  
  220.  
  221.  
  222.  
  223. [EXTRA LISTING #1]
  224.  
  225. {***********************************************************************}
  226. {   TVTIME.PAS                                                          }
  227. {                                                                       }
  228. {   A short program to demonstrate the addition of a new TV event class }
  229. {   that can be broadcast outside of the event chain focus.  It uses a  }
  230. {   specific command based on the BIOS timer tick counter.              }
  231. {                                                                       }
  232. {   Copyright (c) 1992 Charles Scott Nichol.  All rights reserved.      }
  233. {***********************************************************************}
  234.  
  235. {$R-,S-,X+}
  236.  
  237. program
  238.   TVTime;
  239.  
  240. uses
  241.   App, Dialogs, Drivers, Menus, MsgBox, Objects, Views,
  242.   BiosTick, Cmds, TickView;
  243.  
  244. type
  245.   TTimeApp = object(TApplication)
  246.     MetaSupport: Boolean;
  247.     Clock: PClockView;
  248.     Heap: PHeapView;
  249.     constructor Init;
  250.     procedure GetEvent(var Event: TEvent); virtual;
  251.     procedure HandleEvent(var Event: TEvent); virtual;
  252.     procedure InitDeskTop; virtual;
  253.     procedure InitMenuBar; virtual;
  254.     procedure InitStatusLine; virtual;
  255.     procedure OutOfMemory; virtual;
  256.   end;
  257.  
  258. const
  259.   cmAbout = 100;
  260.   cmToggleClock = 101;
  261.   cmToggleHeap = 102;
  262.   cmToggleMeta = 103;
  263.  
  264. {----------- TTimeApp ------------}
  265.  
  266. constructor TTimeApp.Init;
  267. var
  268.   R: TRect;
  269. begin
  270.   TApplication.Init;
  271.  
  272.   MetaSupport := True;
  273.  
  274.   GetExtent(R);
  275.   R.A.X := R.B.X - 8; R.B.Y := R.A.Y + 1;  {End of top line}
  276.   Clock := New(PClockView, Init(R));
  277.   if ValidView(Clock) = nil then
  278.     Fail;
  279.   Insert(Clock);
  280.  
  281.   GetExtent(R);
  282.   R.A.X := R.B.X - 8; R.A.Y := R.B.Y - 1;  {End of bottom line}
  283.   Heap := New(PHeapView, Init(R));
  284.   if ValidView(Heap) = nil then begin
  285.     Dispose(Clock);
  286.     Fail;
  287.   end;
  288.   Insert(Heap);
  289. end;
  290.  
  291. procedure TTimeApp.GetEvent(var Event: TEvent);
  292. begin
  293.   TApplication.GetEvent(Event);
  294.   if Event.What = evNothing then begin
  295.     GetBiosTickEvent(Event);               {Hook to add the BIOS tick event}
  296.     if Event.What = evNothing then begin
  297.       Event.What := evMetaBroadcast;
  298.       Event.Command := cmIdle;             {Alternative to .Idle method}
  299.     end;
  300.     if MetaSupport and (Event.What = evMetaBroadcast) then begin
  301.       if TopView <> @Self then begin       {We are not the current modal view}
  302.         HandleEvent(Event);                {Force meta broadcast of event}
  303.         ClearEvent(Event);                 {Prevent redundant processing}
  304.       end;
  305.     end;
  306.   end;
  307. end;
  308.  
  309. procedure TTimeApp.HandleEvent(var Event: TEvent);
  310.  
  311.   procedure About;
  312.   const
  313.     S1 = #3'Bios Tick Time/Heap Display Demo';
  314.     S2 = #13#3'Copyright (c) 1992 Charles Scott Nichol';
  315.     S3 = #13#3'All rights reserved';
  316.     S4 = #13#3'Meta support is ';
  317.   var
  318.     D: PDialog;
  319.     R: TRect;
  320.     S5: String[15];
  321.   begin
  322.     R.Assign(0,0,49,10);
  323.     D := New(PDialog, Init(R, 'About'));
  324.     if MetaSupport then
  325.       S5 := 'enabled'
  326.     else
  327.       S5 := 'disabled';
  328.     with D^ do begin
  329.       Options := Options or ofCentered;
  330.       R.Assign(3, 2, Size.X - 2, Size.Y - 4);
  331.       Insert(New(PStaticText, Init(R, S1+S2+S3+S4+S5)));
  332.       R.Assign(19, 7, 29, 9);
  333.       Insert(New(PButton, Init(R, 'O~k~', cmOK, bfDefault)));
  334.       SelectNext(False);
  335.     end;
  336.     if ValidView(D) <> nil then begin
  337.       DeskTop^.ExecView(D);
  338.       Dispose(D, Done);
  339.     end;
  340.   end;
  341.  
  342.   procedure ToggleMeta;
  343.   begin
  344.     MetaSupport := not MetaSupport;
  345.   end;
  346.  
  347. begin
  348.   TApplication.HandleEvent(Event);
  349.   if Event.What = evCommand then begin
  350.     case Event.Command of
  351.     cmAbout:
  352.       About;
  353.     cmToggleClock:
  354.       Clock^.ToggleDisplay;
  355.     cmToggleHeap:
  356.       Heap^.ToggleDisplay;
  357.     cmToggleMeta:
  358.       ToggleMeta;
  359.     end;
  360.     ClearEvent(Event);
  361.   end;
  362. end;
  363.  
  364. procedure TTimeApp.InitDeskTop;
  365. var
  366.   R: TRect;
  367. begin
  368.   GetExtent(R);
  369.   R.Grow(0,-1);            {Leave room for menu bar and status line}
  370.   DeskTop := New(PDeskTop, Init(R));
  371. end;
  372.  
  373. procedure TTimeApp.InitMenuBar;
  374. var
  375.   R: TRect;
  376. begin
  377.   GetExtent(R);
  378.   R.B.Y := R.A.Y + 1;      {Top line only}
  379.   MenuBar := New(PMenuBar, Init(R, NewMenu(
  380.     NewSubMenu('~'#240'~', hcNoContext, NewMenu(
  381.       NewItem('~A~bout', '', kbNoKey, cmAbout, hcNoContext,
  382.       NewItem('Toggle ~C~lock Display', '', kbNoKey, cmToggleClock, hcNoContext,
  383.       NewItem('Toggle ~H~eap Display', '', kbNoKey, cmToggleHeap, hcNoContext,
  384.       NewLine(
  385.       NewItem('E~x~it', '', kbNoKey, cmQuit, hcNoContext, nil)))))),
  386.     nil))));
  387. end;
  388.  
  389. procedure TTimeApp.InitStatusLine;
  390. var
  391.   R: TRect;
  392. begin
  393.   GetExtent(R);
  394.   R.A.Y := R.B.Y - 1;      {Bottom line only}
  395.   StatusLine := New(PStatusLine, Init(R,
  396.     NewStatusDef(0, $FFFF,
  397.       NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
  398.       NewStatusKey('~Alt-M~ Toggle Meta Support', kbAltM, cmToggleMeta,
  399.       NewStatusKey('~F10~ Menu', kbF10, cmMenu, nil))),
  400.     nil)));
  401. end;
  402.  
  403. procedure TTimeApp.OutOfMemory;
  404. begin
  405.   MessageBox(#3'Insufficient memory to complete operation', nil,
  406.     mfError + mfOkButton);
  407. end;
  408.  
  409. {----------- Program ------------}
  410.  
  411. var
  412.   TimeApp: TTimeApp;
  413. begin
  414.   if TimeApp.Init then begin
  415.     TimeApp.Run;
  416.     TimeApp.Done;
  417.   end;
  418. end.
  419.  
  420.  
  421. [EXTRA LISTING #2]
  422.  
  423. {***********************************************************************}
  424. {   CMDS.PAS                                                            }
  425. {                                                                       }
  426. {   Constants for event and commands added.                             }
  427. {                                                                       }
  428. {   Copyright (c) 1992 Charles Scott Nichol.  All rights reserved.      }
  429. {***********************************************************************}
  430.  
  431. unit
  432.   Cmds;
  433.  
  434. interface
  435.  
  436. const
  437.   evMetaBroadcast = $400;  {Use an unallocated bit from Event.What}
  438.  
  439. const
  440.   cmBiosTick = 1000;       {These commands are for evMetaBroadcast}
  441.   cmIdle = 1001;
  442.  
  443. implementation
  444.  
  445. end.
  446.  
  447.  
  448.  
  449.  
  450.