home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / dos / prg / pas / swag / oop.swg / 0020_TV-HELP.PAS.pas < prev    next >
Pascal/Delphi Source File  |  1993-05-28  |  6KB  |  173 lines

  1. (*
  2. Last week I found a bug in HELPFile.PAS and called Borland.  After describing
  3. the error, the Borland representative agreed that it was a bug and that
  4. it hasn't been reported.  ThereFore, I will describe the bug here and give
  5. a fix to the problem.
  6.  
  7. Problem:
  8. Recall, HELPFile.PAS is the Turbo Vision Unit that TVDEMO.PAS Uses to
  9. provide on-line help to Turbo Vision Programs.  The problem that occurred
  10. was that if a help panel was brought up that did not contain a cross
  11. reference entry (i.e. hyperText link), and the user pressed [Tab] or
  12. Shift+[Tab] then a run-time error is generated.   notE: the run-time
  13. error is generated if the Program is Compiled With Range Checking on.
  14. if Range checking is off, then unpredicatable results occur.
  15.  
  16. to see the bug in action, do the following:
  17.  
  18. Fire up Turbo Pascal 6 and load the TVDEMO.PAS Program (by default it exists
  19. in the TVDEMOS subdirectory).  Make sure Range checking is turned on.
  20. The option is in Options|Compiler.  You will also want to turn debugging
  21. on in both the TVDEMO.PAS and HELPFile.PAS Files.  to do this, you must
  22. edit the source code of both Files and change the {$D-} option to {$D+}
  23. at the beginning of both Files.
  24.  
  25. Once you have done the above, press Ctrl+F9 to run TVDEMO.  When TVDEMO
  26. comes up, press F1 to bring up the help Window.  Now, press Shift+[Tab]
  27. or [Tab] and a RunTime error 201 will occur.
  28.  
  29. This bug arises from the fact that the HELPFile.PAS Unit assumes that
  30. there will always be at least one cross reference field on a help panel.
  31. Obviously, this is an invalid assumption.
  32.  
  33. Luckily, there is an easy solution to the problem.  The following shows
  34. how to change the HELPFile.PAS Program so that this error doesn't occur.
  35. The only Procedure that needs to be changed is THelpViewer.HandleEvent.
  36.  
  37. *)
  38.  
  39. Procedure THelpViewer.HandleEvent(Var Event: TEvent);
  40. Var
  41.   KeyPoint, Mouse: TPoint;
  42.   KeyLength: Byte;
  43.   KeyRef: Integer;
  44.   KeyCount: Integer;
  45. { 1. Add the following Variable declaration }
  46.   n : Integer;
  47.  
  48. Procedure MakeSelectVisible;
  49. Var
  50.   D: TPoint;
  51. begin
  52.   topic^.GetCrossRef(Selected, KeyPoint, KeyLength, KeyRef);
  53.   D := Delta;
  54.   if KeyPoint.X < D.X then D.X := KeyPoint.X;
  55.   if KeyPoint.X > D.X + Size.X then D.X := KeyPoint.X - Size.X;
  56.   if KeyPoint.Y < D.Y then D.Y := KeyPoint.Y;
  57.   if KeyPoint.Y > D.Y + Size.Y then D.Y := KeyPoint.Y - Size.Y;
  58.   if (D.X <> Delta.X) or (D.Y <> Delta.Y) then Scrollto(D.X, D.Y);
  59. end;
  60.  
  61. Procedure Switchtotopic(KeyRef: Integer);
  62. begin
  63.   if topic <> nil then Dispose(topic, Done);
  64.   topic := HFile^.Gettopic(KeyRef);
  65.   topic^.SetWidth(Size.X);
  66.   Scrollto(0, 0);
  67.   SetLimit(Limit.X, topic^.NumLines);
  68.   Selected := 1;
  69.   DrawView;
  70. end;
  71.  
  72. begin
  73.   TScroller.HandleEvent(Event);
  74.   Case Event.What of
  75.     evKeyDown:
  76.       begin
  77.         Case Event.KeyCode of
  78.           kbTab:
  79.             begin
  80. { 2. Change This...
  81.               Inc(Selected);
  82.               if Selected > topic^.GetNumCrossRefs then Selected := 1;
  83.               MakeSelectVisible;
  84. to this... }
  85.               Inc(Selected);
  86.               n := topic^.GetNumCrossRefs;
  87.  
  88.               if n > 0 then
  89.               begin
  90.                   if Selected > n then
  91.                       Selected := 1;
  92.                   MakeSelectVisible;
  93.               end
  94.               else
  95.                   selected := 0;
  96. { end of Change 2 }
  97.             end;
  98.           kbShiftTab:
  99.             begin
  100. { 3. Change this ...
  101.               Dec(Selected);
  102.               if Selected = 0 then Selected := topic^.GetNumCrossRefs;
  103.               MakeSelectVisible;
  104. to this... }
  105.               Dec(Selected);
  106.               n := topic^.GetNumCrossRefs;
  107.               if n > 0 then
  108.               begin
  109.                   if Selected = 0 then
  110.                       Selected := n;
  111.                   MakeSelectVisible;
  112.               end
  113.               else
  114.                   Selected := 0;
  115. { end of Change 3 }
  116.             end;
  117.           kbEnter:
  118.             begin
  119. { 4. Change this...
  120.               if Selected <= topic^.GetNumCrossRefs then
  121.               begin
  122.                 topic^.GetCrossRef(Selected, KeyPoint, KeyLength, KeyRef);
  123.                 Swithtotopic(KeyRef);
  124.               end;
  125. to this...}
  126.               n := topic^.GetNumCrossRefs;
  127.               if n > 0 then
  128.               begin
  129.                   if Selected <= n then
  130.                   begin
  131.                     topic^.GetCrossRef(Selected, KeyPoint, KeyLength, KeyRef);
  132.                     Switchtotopic(KeyRef);
  133.                   end;
  134.               end;
  135. { end of Change 4 }
  136.             end;
  137.           kbEsc:
  138.             begin
  139.               Event.What := evCommand;
  140.               Event.Command := cmClose;
  141.               PutEvent(Event);
  142.             end;
  143.         else
  144.           Exit;
  145.         end;
  146.         DrawView;
  147.         ClearEvent(Event);
  148.       end;
  149.     evMouseDown:
  150.       begin
  151.         MakeLocal(Event.Where, Mouse);
  152.         Inc(Mouse.X, Delta.X); Inc(Mouse.Y, Delta.Y);
  153.         KeyCount := 0;
  154.         Repeat
  155.           Inc(KeyCount);
  156.           if KeyCount > topic^.GetNumCrossRefs then Exit;
  157.           topic^.GetCrossRef(KeyCount, KeyPoint, KeyLength, KeyRef);
  158.         Until (KeyPoint.Y = Mouse.Y+1) and (Mouse.X >= KeyPoint.X) and
  159.           (Mouse.X < KeyPoint.X + KeyLength);
  160.         Selected := KeyCount;
  161.         DrawView;
  162.         if Event.Double then Switchtotopic(KeyRef);
  163.         ClearEvent(Event);
  164.       end;
  165.     evCommand:
  166.       if (Event.Command = cmClose) and (Owner^.State and sfModal <> 0) then
  167.       begin
  168.         endModal(cmClose);
  169.         ClearEvent(Event);
  170.       end;
  171.   end;
  172. end;
  173.