Delphi Clinic C++Builder Gate Training & Consultancy Delphi Notes Weblog Dr.Bob's Webshop
Bob Swart (aka Dr.Bob) - Medical Officer Delphi 6 Developer's Guide
 Dr.Bob's Tip-Of-The-Hat #5
See Also: Delphi Papers, Columns and other Tip-Of-The-Hats

TCustomOutLine Exception
For this Tip-Of-The-Hat I take you to one of the components that can be found on the Win 3.1 tab. In fact, the problem I want to identify (and solve) today is only a problem introduced at the TCustomOutline component inside file outline.pas of Delphi 1.0x (it was fixed in later versions of Delphi and C++Builder).
Here are the steps to reproduce the problem:

  1. Start a new project in Delphi 1.0x
  2. Drop a OutLine component on it (additional or "Win 3.1" page)
  3. Fill "Lines" property of Outline1 with the following:
  4. Hit F9 to run the program (collapsed root node Bob)
  5. Click on '+'-key to expand Bob
  6. Hit End key to go to Erik, click on '+'-key to expand Erik
  7. Hit Home key to go to Bob
  8. Hit End key to go to Erik
At this time, a "List index out of bounds" exception will appear.

The error is due by the fact that the KeyDown method of TCustomOutline does not check if an expanded nodes has actual child nodes; it just moves to the last child node (and if there are no children, then last will return something that is "out of bounds" indeed).

Dr.Bob's Fix
In file outline.pas, find procedure TCustomOutline.KeyDown(var Key: Word; Shift: TShiftState); and change the code for VK_END to the following (one line added):

      Node := TOutlineNode(FRootNode.List.Last);
      while (Node.Expanded) and
            (Node.List.Count > 0) do // Dr.Bob's fix
             Node := TOutlineNode(Node.List.Last);
      SelectedItem := Node.Index;
Delphi 2 and higher (and C++Builder) no longer have this problem, although my suggested test for (Node.List.Count > 0) was actually implemented by a test for Node.HasItems

This webpage © 2001-2009 by Bob Swart (aka Dr.Bob - All Rights Reserved.