home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / Borland Plateform / Turbo Pascal V7.0 / TVDEBUG.ZIP / TVDEBUG.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1992-10-30  |  13.6 KB  |  516 lines

  1. {************************************************}
  2. {                                                }
  3. {   Turbo Vision Debuging Unit                   }
  4. {   Copyright (c) 1992 by Borland International  }
  5. {                                                }
  6. {************************************************}
  7.  
  8. unit TVDebug;  
  9.  
  10. interface
  11.  
  12. uses Objects, Drivers, Views, App, TextView;
  13.  
  14. const
  15.   cmTextWinAppendLine = 30000;
  16.  
  17.   { Custom options flag so TextInterior will know whether to scroll
  18.     its text as new lines are added or not.  Uses an unused bit of the
  19.     TView options field.    Default is not to scroll on append. }
  20.  
  21.   ofScrollonAppend = $0400;
  22.  
  23. type
  24.  
  25.   { TApplication }
  26.   {  A debugging version of APP's TApplication that will create a
  27.      Event window and a Log window on the bottom of the desktop. }
  28.   TApplication = object(App.TApplication)
  29.     constructor Init;
  30.     procedure GetEvent(var E: TEvent);  virtual;
  31.   end;
  32.   PApplication = ^TApplication;
  33.  
  34.   { TTextCollection }
  35.   {  Used internally by TTextInterior to hold the text to display }
  36.   PTextCollection = ^TTextCollection;
  37.   TTextCollection = object(TCollection)
  38.     procedure FreeItem(Item: Pointer); virtual;
  39.   end;
  40.  
  41.   { TTextInterior }
  42.   {  A scrolling view of the text stored in Lines. If the view recieves
  43.      a cmTextWinAppendLine as an evBroadcast the InfoPtr field is assumed
  44.      to contain a PString containing a new line to add to Lines. }
  45.   PTextInterior = ^TTextInterior;
  46.   TTextInterior = object(TScroller)
  47.     Lines: TTextCollection;
  48.     constructor Init( R: TRect; MaxLines: Integer;
  49.       AHScrollbar, AVScrollbar: PScrollbar);
  50.     destructor Done; virtual;
  51.     procedure Draw; virtual;
  52.     procedure HandleEvent(var E: TEvent); virtual;
  53.   end;
  54.  
  55.   { TTextWindow }
  56.   {  A window designed to contain a TTextInterior }
  57.   PTextWindow = ^TTextWindow;
  58.   TTextWindow = object(TWindow)
  59.     constructor Init(R: TRect; NewTitle: String; Num, MaxLines: Integer);
  60.     procedure MakeInterior( MaxLines: integer);  virtual;
  61.   end;
  62.  
  63.   { TEventWindow }
  64.   {  A text window that will a list of the last MaxLines events
  65.      sent to it by DisplayEvent.  TApplication above calls this
  66.      method upon receiving an event in GetEvent.  If this unit
  67.      is included after Views in a unit, all Message calls in that
  68.      unit are also displayed. NOTE: only one of these windows is
  69.      allowed.  If more than one is created the second will return
  70.      False from Valid causing InsertWindow to refuse to insert the
  71.      window in the desktop. }
  72.   PEventWindow = ^TEventWindow;
  73.   TEventWindow = object(TTextWindow)
  74.     Filters: Word;
  75.     constructor Init(var R: TRect; ATitle: String; Num, MaxLines: Integer);
  76.     destructor Done; virtual;
  77.     procedure DisplayEvent(var E: TEvent); virtual;
  78.     procedure FiltersDialog;
  79.     function GetPalette: PPalette; virtual;
  80.     procedure HandleEvent(var Event: TEvent); virtual;
  81.     procedure MakeInterior(Maxlines: Integer); virtual;
  82.     function Valid(Command: Word): Boolean; virtual; 
  83.   end;
  84.  
  85.   { TLogWindow }
  86.   {  Creating a TLogWindow will redirect all Write and Writeln's to
  87.      the window.  Only one of these windows should be created, if more
  88.      than one is create Valid will return False and InsertWindow will
  89.      refuse to insert the window into the desktop. }
  90.   PLogWindow = ^TLogWindow;
  91.   TLogWindow = object(TWindow)
  92.     Interior: PTerminal;
  93.     constructor Init(var Bounds: TRect; BufSize: Word);
  94.     destructor Done; virtual;
  95.     function Valid(Command: Word): Boolean; virtual;
  96.   end;
  97.  
  98. { An alternate Message from View's that will log the message to the
  99.   event window before sending it. }
  100. function Message(Receiver: PView; What, Command: Word;
  101.   InfoPtr: Pointer): Pointer;
  102.  
  103. implementation
  104.  
  105. uses Dos, Menus, Dialogs, KeyNamer, CmdNamer;
  106.  
  107. { If you get a FILE NOT FOUND error when compiling this program
  108.   from a DOS IDE, change to the \BP\EXAMPLES\DOS\TVDEBUG directory
  109.   (use File|Change dir).
  110.  
  111.   This will enable the compiler to find all of the units used by
  112.   this program.
  113. }
  114.  
  115. var
  116.   EventWindow: PEventWindow;
  117.  
  118. { TApplication }
  119.  
  120. constructor TApplication.Init;
  121. var
  122.   R: TRect;
  123. begin
  124.   inherited Init;
  125.  
  126.   BuiltInCommandNames;
  127.  
  128.   Desktop^.GetExtent(R);
  129.   R.Assign(R.A.X, R.B.Y-10, R.B.X div 2, R.B.Y);
  130.   InsertWindow(New(PEventWindow, Init(R, 'Event Window', wnNoNumber, 100)));
  131.  
  132.   Desktop^.GetExtent(R);
  133.   R.Assign(R.B.X div 2, R.B.Y-10, R.B.X, R.B.Y);
  134.   InsertWindow(New(PLogWindow, Init(R, 1024)));
  135. end;
  136.  
  137. procedure TApplication.GetEvent(var E: TEvent);
  138. begin
  139.   inherited GetEvent(E); 
  140.   if EventWindow <> nil then
  141.     EventWindow^.DisplayEvent(E);
  142. end;
  143.  
  144. const
  145.   CEWMenu = #9#10#11#12#13#14;
  146.  
  147. { TEWMenubox }
  148.  
  149. type
  150.   PEWMenubox = ^TEWMenubox;
  151.   TEWMenubox = object(TMenubox)
  152.     function GetPalette: PPalette; virtual;
  153.   end;
  154.  
  155. function TEWMenubox.GetPalette: PPalette;
  156. const
  157.   P: String[length(CEWMenu)] = CEWMenu;
  158. begin
  159.   GetPalette:= @P;
  160. end;
  161.  
  162. { TEWMenubar }
  163.  
  164. type
  165.   PEWMenubar = ^TEWMenubar;
  166.   TEWMenubar = object(TMenubar)
  167.     function GetPalette: PPalette; virtual;
  168.     function NewSubView(var Bounds: TRect; AMenu: PMenu;
  169.        AParentMenu: PMenuView): PMenuView; virtual;
  170.   end;
  171.  
  172. function TEWMenubar.GetPalette: PPalette;
  173. const
  174.   P: string[length(CEWMenu)] = CEWMenu;
  175. begin
  176.   GetPalette:= @P;
  177. end;
  178.  
  179. function TEWMenubar.NewSubView(var Bounds: TRect; AMenu: PMenu;
  180.   AParentMenu: PMenuView): PMenuView;
  181. begin
  182.   NewSubView := New(PEWMenuBox, Init(Bounds, AMenu, AParentMenu));
  183. end;
  184.  
  185. { TTextCollection }
  186.  
  187. procedure TTextCollection.FreeItem(Item: Pointer);
  188. begin
  189.   DisposeStr(Item);
  190. end;
  191.  
  192. { TTextInterior }
  193.  
  194. constructor TTextInterior.Init( R: TRect; MaxLines: Integer;
  195.   AHScrollbar, AVScrollbar: PScrollbar);
  196. begin
  197.   inherited Init(R, AHScrollbar, AVScrollbar);
  198.   if MaxLines = 0 then
  199.     Lines.Init(Size.X, 1)     { let it grow unchecked:  16K items max}
  200.   else
  201.     Lines.Init(Maxlines, 0);  { fix size and rollover when full }
  202.   SetLimit(128,Size.X);
  203.   GrowMode:= gfGrowHiX + gfGrowHiY;
  204. end;
  205.  
  206. destructor TTextInterior.Done;
  207. begin
  208.   Lines.Done;
  209.   inherited Done;
  210. end;
  211.  
  212. procedure TTextInterior.Draw;
  213. var
  214.   color: byte;
  215.   Y, I: Integer;
  216.   B: TDrawBuffer;
  217. begin                            { draw only what's visible }
  218.   Color:= GetColor(1);
  219.   for y:= 0 to Size.Y-1 do
  220.   begin
  221.     MoveChar(B,' ',Color,Size.X);
  222.     I:= Delta.Y+Y;
  223.     if (I < Lines.Count) and (Lines.At(I) <> nil) then
  224.       MoveStr(B, Copy(PString(Lines.At(I))^,Delta.X+1, Size.X), Color);
  225.     WriteLine(0,Y,Size.X,1,B);
  226.   end;
  227. end;
  228.  
  229. procedure TTextInterior.HandleEvent(var E: TEvent);
  230. begin
  231.   inherited HandleEvent(E);
  232.   case E.What of
  233.     evBroadcast:
  234.       case E.Command of
  235.         cmTextWinAppendLine:
  236.           begin
  237.             if Lines.Count < Lines.Limit then    { let it grow }
  238.             begin
  239.               Lines.Insert(E.Infoptr);
  240.               if Lines.Count > Size.Y then
  241.               begin
  242.                 SetLimit(128,Lines.Count);
  243.                 if (Owner <> nil) and
  244.                     ((Owner^.Options and ofScrollonAppend) <> 0) then
  245.                   VScrollbar^.SetValue(Lines.Count);
  246.               end;
  247.             end
  248.             else
  249.             begin
  250.               Lines.AtFree(0);           { zap the first item }
  251.               Lines.Insert(E.InfoPtr);   { before adding new one }
  252.             end;
  253.             DrawView;
  254.             end                           { show the changes }
  255.           else
  256.             Exit;
  257.          end;
  258.     else
  259.       Exit;
  260.     end;
  261.   ClearEvent(E);
  262. end;
  263.  
  264. { TTextWindow }
  265.  
  266. constructor TTextWindow.Init( R: TRect; NewTitle: String;
  267.   Num, MaxLines: Integer);
  268. begin
  269.   inherited Init(R,NewTitle, Num);
  270.   MakeInterior(MaxLines);
  271. end;
  272.  
  273. procedure TTextWindow.MakeInterior( MaxLines: Integer);
  274. var
  275.   R: TRect;
  276. begin
  277.   GetExtent(R);
  278.   R.Grow(-1, -1);
  279.   Insert(New(PTextInterior, Init(R, MaxLines,
  280.     StandardScrollBar(sbHorizontal),
  281.     StandardScrollBar(sbVertical))));
  282. end;
  283.  
  284. { TEventWindow }
  285.  
  286. const
  287.   cmEventFilters = 503;
  288.  
  289. constructor TEventWindow.Init(var R: TRect; ATitle: String; Num,
  290.   Maxlines: Integer);
  291. begin
  292.   inherited Init(R, ATitle, Num, MaxLines);
  293.  
  294.   { custom option flag for TextWindow's interior}
  295.   Options:= Options or (ofScrollOnAppend + ofFirstClick);
  296.   Filters := evMouse or evKeyBoard or evMessage;
  297.  
  298.   EventWindow := @Self; 
  299. end;
  300.  
  301. destructor TEventWindow.Done;
  302. begin
  303.   inherited Done;
  304.   EventWindow := nil;
  305. end;
  306.  
  307. procedure TEventWindow.DisplayEvent(var E: TEvent);
  308. var
  309.   st,xs,ys: String;
  310.   Event: Word;
  311. begin
  312.   st:='';
  313.   if State and sfSelected = 0 then
  314.   begin
  315.     Event := E.What and Filters;
  316.     case Event of
  317.       evNothing: Exit;
  318.       evMouseDown,
  319.       evMouseUp,
  320.       evMouseMove,
  321.       evMouseAuto:
  322.         begin
  323.           st := 'Mouse ';
  324.           case E.What of
  325.             evMouseDown: st := st + 'Down, ';
  326.             evMouseUp:   st := st + 'Up, ';
  327.             evMouseMove: st := st + 'Move, ';
  328.             evMouseAuto: st := st + 'Auto, ';
  329.           end;
  330.           case E.Buttons of
  331.             mbLeftButton:  st := st + 'Left Button, ';
  332.             mbRightButton: st := st + 'Right Button, ';
  333.             $04:           st := st + 'Center Button, ';
  334.           end;
  335.           if (E.Buttons <> 0) and E.Double then
  336.             st := st +'Double Click ';
  337.           Str(E.Where.X:0, xs);
  338.           Str(E.Where.Y:0, ys);
  339.           st := st + 'X:' + xs + ' Y:' + ys;
  340.         end;
  341.       evKeyDown:
  342.         begin
  343.           st := KeyName(E.KeyCode);
  344.           if st = '' then
  345.             st := KeyName(Word(E.CharCode));
  346.           st := 'Keyboard ' + st;
  347.         end;
  348.       evCommand,
  349.       evBroadcast:
  350.         begin
  351.           if E.What = evCommand then
  352.             st := 'Command '
  353.           else
  354.             st := 'Broadcast ';
  355.           St := Concat(St, CommandName(E.Command));
  356.         end;
  357.       else
  358.         Str(E.What:0, xs);
  359.         st := 'Unknown Event.What: ' + xs;
  360.       end;  {case}
  361.  
  362.       Views.Message(@Self, evBroadcast, cmTextWinAppendLine, NewStr(st));
  363.   end;  { if }
  364. end;
  365.  
  366. procedure TEventWindow.FiltersDialog;
  367. var
  368.   D: PDialog;
  369.   R: TRect;
  370.   DataRec: Word;
  371. begin
  372.   R.Assign(10,6,40,20);
  373.   D := New(PDialog, Init(R, 'Message Filters'));
  374.  
  375.   with D^ do
  376.   begin
  377.     R.Assign(7,2,22,10);
  378.     Insert(New(PCheckBoxes, Init(R,
  379.       NewSItem('Mouse ~D~own',
  380.       NewSItem('Mouse ~U~p',
  381.       NewSItem('Mouse ~M~ove',
  382.       NewSItem('Mouse ~A~uto',
  383.       NewSItem('~K~eyboard',
  384.       NewSItem('~C~ommand',
  385.       NewSItem('~B~roadcast',
  386.       NewSItem('~O~ther', nil)))))))))));
  387.  
  388.     R.Assign(5,11,13,13);
  389.     Insert(New(PButton, Init(R, 'Ok', cmOk, bfDefault)));
  390.  
  391.     R.Assign(14,11,24,13);
  392.     Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal)));
  393.  
  394.     SelectNext(False);
  395.   end;
  396.  
  397.   { transfer data from filters to a more linear datarec }
  398.   DataRec := 0;
  399.   DataRec := Filters and (evMouse or evKeyDown);
  400.   DataRec := DataRec or ((Filters - DataRec) shr 3);
  401.  
  402.   if Application^.ExecuteDialog(D, @DataRec) <> cmCancel then
  403.   begin
  404.     Filters := 0;
  405.     Filters := DataRec and (evMouse or evKeyDown);
  406.     Filters := Filters or ((DataRec - Filters) shl 3);
  407.   end;
  408. end;
  409.  
  410. function TEventWindow.GetPalette: PPalette;
  411. const
  412.   P: String[length(CBlueWindow)+ length(CMenuView)] = CBlueWindow + CMenuView;
  413. begin
  414.   GetPalette := @P;
  415. end;
  416.  
  417. procedure TEventWindow.HandleEvent(var Event: TEvent);
  418. begin
  419.   inherited HandleEvent(Event);
  420.   if (Event.What = evCommand) and (Event.Command = cmEventFilters) then
  421.   begin
  422.     FiltersDialog;
  423.     ClearEvent(Event);
  424.   end;
  425. end;
  426.  
  427. procedure TEventWindow.MakeInterior(Maxlines: Integer);
  428. var
  429.   R: TRect;
  430.   M: PMenubar;
  431. begin
  432.   GetExtent(R);
  433.   R.Grow(-1,-1);
  434.   R.B.Y:= R.A.Y+1;
  435.   Insert(New(PEWMenubar, Init(R, NewMenu(
  436.     NewSubMenu('~O~ptions', hcNoContext, NewMenu(
  437.       NewItem('~F~ilters', '', 0, cmEventFilters, hcNoContext, nil)),
  438.     nil)))));
  439.  
  440.   GetExtent(R);
  441.   R.Grow(-1, -1);
  442.   Inc(R.A.Y);
  443.   Insert(New(PTextInterior, Init(R, MaxLines,
  444.     StandardScrollBar(sbHorizontal+sbHandleKeyboard),
  445.     StandardScrollBar(sbVertical+sbHandleKeyboard))));
  446. end;
  447.  
  448. function TEventWindow.Valid(Command: Word): Boolean;
  449. begin
  450.   if inherited Valid(Command) then
  451.     Valid := EventWindow = @Self
  452.   else
  453.     Valid := False;
  454. end;
  455.  
  456. { TLogWindow }
  457.  
  458. function AssignedTo(var T: Text; View: PTextDevice): Boolean;
  459. begin
  460.   AssignedTo :=  Pointer((@TextRec(T).UserData)^) = View;
  461. end;
  462.  
  463. constructor TLogWindow.Init(var Bounds: TRect; BufSize: Word);
  464. var
  465.   R: TRect;
  466.   vSB, hSB: PScrollBar;
  467. begin
  468.   inherited Init(Bounds, 'Messages Log', wnNoNumber);
  469.   vSB := StandardScrollBar(sbVertical + sbHandleKeyboard);
  470.   Insert(vSB);
  471.   hsb := StandardScrollBar(sbHorizontal + sbHandleKeyboard);
  472.   Insert(hSB);
  473.   GetExtent(R);
  474.   R.Grow(-1, -1);
  475.   Interior := New(PTerminal, Init(R, hSB, vSB, BufSize));
  476.   Insert(Interior);
  477.   AssignDevice(Output, Interior);
  478.   Rewrite(Output);
  479. end;
  480.  
  481. destructor TLogWindow.Done;
  482. begin
  483.   if AssignedTo(Output, Interior) then
  484.   begin
  485.     Assign(Output, '');
  486.     Rewrite(Output);
  487.   end;
  488.   inherited Done;
  489. end;
  490.  
  491. function TLogWindow.Valid(Command: Word): Boolean;
  492. begin
  493.   Valid := AssignedTo(Output, Interior);
  494. end;
  495.  
  496. { Message }
  497.  
  498. function Message(Receiver: PView; What, Command: Word;
  499.   InfoPtr: Pointer): Pointer;
  500. var
  501.   E: TEvent;
  502. begin
  503.   E.What := What;
  504.   E.Command := Command;
  505.   E.Infoptr := Infoptr;
  506.  
  507.   { no point in displaying our own message to display an event...}
  508.  
  509.   if (EventWindow <> nil) and (Command <> cmTextWinAppendLine) then
  510.     EventWindow^.DisplayEvent(E);
  511.  
  512.   { pass the intercepted data on to the Message function it was intended for }
  513.   Message:= Views.Message(Receiver, What, Command, InfoPtr);
  514. end;
  515.  
  516. end.