(* Last week I found a bug in HELPFile.PAS and called Borland. After describing the error, the Borland representative agreed that it was a bug and that it hasn't been reported. ThereFore, I will describe the bug here and give a fix to the problem. Problem: Recall, HELPFile.PAS is the Turbo Vision Unit that TVDEMO.PAS Uses to provide on-line help to Turbo Vision Programs. The problem that occurred was that if a help panel was brought up that did not contain a cross reference entry (i.e. hyperText link), and the user pressed [Tab] or Shift+[Tab] then a run-time error is generated. notE: the run-time error is generated if the Program is Compiled With Range Checking on. if Range checking is off, then unpredicatable results occur. to see the bug in action, do the following: Fire up Turbo Pascal 6 and load the TVDEMO.PAS Program (by default it exists in the TVDEMOS subdirectory). Make sure Range checking is turned on. The option is in Options|Compiler. You will also want to turn debugging on in both the TVDEMO.PAS and HELPFile.PAS Files. to do this, you must edit the source code of both Files and change the {$D-} option to {$D+} at the beginning of both Files. Once you have done the above, press Ctrl+F9 to run TVDEMO. When TVDEMO comes up, press F1 to bring up the help Window. Now, press Shift+[Tab] or [Tab] and a RunTime error 201 will occur. This bug arises from the fact that the HELPFile.PAS Unit assumes that there will always be at least one cross reference field on a help panel. Obviously, this is an invalid assumption. Luckily, there is an easy solution to the problem. The following shows how to change the HELPFile.PAS Program so that this error doesn't occur. The only Procedure that needs to be changed is THelpViewer.HandleEvent. *) Procedure THelpViewer.HandleEvent(Var Event: TEvent); Var KeyPoint, Mouse: TPoint; KeyLength: Byte; KeyRef: Integer; KeyCount: Integer; { 1. Add the following Variable declaration } n : Integer; Procedure MakeSelectVisible; Var D: TPoint; begin topic^.GetCrossRef(Selected, KeyPoint, KeyLength, KeyRef); D := Delta; if KeyPoint.X < D.X then D.X := KeyPoint.X; if KeyPoint.X > D.X + Size.X then D.X := KeyPoint.X - Size.X; if KeyPoint.Y < D.Y then D.Y := KeyPoint.Y; if KeyPoint.Y > D.Y + Size.Y then D.Y := KeyPoint.Y - Size.Y; if (D.X <> Delta.X) or (D.Y <> Delta.Y) then Scrollto(D.X, D.Y); end; Procedure Switchtotopic(KeyRef: Integer); begin if topic <> nil then Dispose(topic, Done); topic := HFile^.Gettopic(KeyRef); topic^.SetWidth(Size.X); Scrollto(0, 0); SetLimit(Limit.X, topic^.NumLines); Selected := 1; DrawView; end; begin TScroller.HandleEvent(Event); Case Event.What of evKeyDown: begin Case Event.KeyCode of kbTab: begin { 2. Change This... Inc(Selected); if Selected > topic^.GetNumCrossRefs then Selected := 1; MakeSelectVisible; to this... } Inc(Selected); n := topic^.GetNumCrossRefs; if n > 0 then begin if Selected > n then Selected := 1; MakeSelectVisible; end else selected := 0; { end of Change 2 } end; kbShiftTab: begin { 3. Change this ... Dec(Selected); if Selected = 0 then Selected := topic^.GetNumCrossRefs; MakeSelectVisible; to this... } Dec(Selected); n := topic^.GetNumCrossRefs; if n > 0 then begin if Selected = 0 then Selected := n; MakeSelectVisible; end else Selected := 0; { end of Change 3 } end; kbEnter: begin { 4. Change this... if Selected <= topic^.GetNumCrossRefs then begin topic^.GetCrossRef(Selected, KeyPoint, KeyLength, KeyRef); Swithtotopic(KeyRef); end; to this...} n := topic^.GetNumCrossRefs; if n > 0 then begin if Selected <= n then begin topic^.GetCrossRef(Selected, KeyPoint, KeyLength, KeyRef); Switchtotopic(KeyRef); end; end; { end of Change 4 } end; kbEsc: begin Event.What := evCommand; Event.Command := cmClose; PutEvent(Event); end; else Exit; end; DrawView; ClearEvent(Event); end; evMouseDown: begin MakeLocal(Event.Where, Mouse); Inc(Mouse.X, Delta.X); Inc(Mouse.Y, Delta.Y); KeyCount := 0; Repeat Inc(KeyCount); if KeyCount > topic^.GetNumCrossRefs then Exit; topic^.GetCrossRef(KeyCount, KeyPoint, KeyLength, KeyRef); Until (KeyPoint.Y = Mouse.Y+1) and (Mouse.X >= KeyPoint.X) and (Mouse.X < KeyPoint.X + KeyLength); Selected := KeyCount; DrawView; if Event.Double then Switchtotopic(KeyRef); ClearEvent(Event); end; evCommand: if (Event.Command = cmClose) and (Owner^.State and sfModal <> 0) then begin endModal(cmClose); ClearEvent(Event); end; end; end;