The Delphi Bug List

Visual Component Library (VCL)

Win 3.1


The color codes indicate in which version(s) of Delphi the bug occurs and what its status is.
Latest update: 9 December 1998
Bug # Delphi versions Description
41 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TDirectoryListbox
TDirectoryListBox has problems when an active directory becomes invalid (e.g. after renaming, or removing a diskette).
402 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TFileListBox
If TFileListBox MultiSelect=True, the ApplyFilePath method sets FileMask to the selected file name, preventing the display of other files in the directory.
43 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TFileListbox
When the 'current drive' becomes invalid (e.g. after renaming or removing diskette), it becomes impossible to choose a different drive
69 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TOutline
TCustomItem.DrawCell passes wrong index to (F)OnDrawItem
70 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TOutline
TOutline.OnDrawItem passes incorrect index.
71 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TOutline
TOutline: Horizontal scrolling and resizing not correct.
92 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TTabbedNotebook
Tab controls does not respond if application does not have focus.
510 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TTabbedNotebook
TTabbedNotebook duplicates its pages as a response to RecreateWnd

Bug #41; last modified: before April 1998
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Exists Exists Exists Unknown Unknown Unknown Unknown Unknown
Win 3.1 - TDirectoryListbox

TDirectoryListBox has problems when an active directory becomes invalid (e.g. after renaming, or removing a diskette).

Description
Reported by Jan Pijnacker; checked by Hallvard Vassbotn
I've got a strange bug in Delphi 1 & 2. I do not have Delphi 3 yet, so I'm not sure if it's there too.
Steps to reproduce:
  1. Make a small application with a DriveComboBox and a FileListBox.
  2. Start the app
  3. Put a diskette in the a-drive
  4. Choose the a-drive from the DriveComboBox, the FileListBox will show the files on the diskette
  5. Remove the diskette
  6. Choose an other drive from the DriveComboBox, you'll get some errors
You'll never be able to display the files of another drive unless you put in a diskette again!
I know how to avoid this problem by using some try .. except statements and setting the ErrorMode, but it always requires me to have a diskette in the drive before changing to another drive and displaying the new contents. This is especially annoying when network connections are lost and I cannot choose another drive.

Comment from checker:
I can confirm this bug. It still exists in Delphi 3 (build 5.53). The culprit is the TFileListBox.SetDirectory method in the FileCtrl unit:

procedure TFileListBox.SetDirectory(const NewDirectory: string);
begin
  if AnsiCompareFileName(NewDirectory, FDirectory) <> 0 then
  begin
       { go to old directory first, in case not complete pathname
         and curdir changed - probably not necessary }
    ChDir(FDirectory);
    ChDir(NewDirectory);     { exception raised if invalid dir }
    GetDir(0, FDirectory);   { store correct directory name }
    ReadFileNames;
  end;
end;
The first ChDir with FDirectory as the argument changes the current directory back to the old directory before changing it to the new directory. Note from the Borland comments that they had doubts about this as well...
Solution / workaround
A possible workaround is to write your own TFileListBox descendant that overrides the virtual ApplyFilePath method. It calls the version of SetDirectory method above - this could be changed so that it calls a corrected version of SetDirectory.

Bug #402; last modified: 12-May-98
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Exists Unknown Unknown Unknown Unknown Unknown Unknown Unknown
Win 3.1 - TFileListBox

If TFileListBox MultiSelect=True, the ApplyFilePath method sets FileMask to the selected file name, preventing the display of other files in the directory.

Description
Reported by Chris Cheney; checked by Reinier Sterkenburg
To see what's wrong:
  1. Start a new, default project.
  2. Drop two FileListBox components onto the form and use the Object Inspector to set the MultiSelect property of FileListBox1 to True, leaving that for FileListBox2 as False.
  3. Set the OnFormCreate event routine to the following:
    procedure TForm1.FormCreate(Sender: TObject);
    var
      WinDirBuff: array[0..255] of Char;
      WinDirString: String;
      DirLen: Word;
    begin
      DirLen := GetWindowsDirectory(@WinDirBuff, SizeOf(WinDirBuff));
      if DirLen > 0 then
        begin
          WinDirString := StrPas(WinDirBuff);
          if WinDirString[Length(WinDirString)] <> '\' then
            WinDirString := WinDirString + '\';
          FileListBox1.ApplyFilePath(WinDirString + 'win.ini');
          FileListBox2.ApplyFilePath(WinDirString + 'win.ini')
        end
      else ShowMessage('Windows directory error')
    end;
  4. (Compile and) Run.
What you see is that FileListBox1 shows 1 file (assuming that win.ini is in the windows directory) whereas FileListBox2 shows all files in the directory.
One would expect FileListBox1 to show the same as FileListBox2.

No difference is documented in the help topic for the ApplyFilePath method (and no difference would be expected). ApplyFilePath is documented as enabling a Open dialog to be approximated. The Windows Open dialog (GetOpenFileName) behaves sensibly when OFN_ALLOWMULTISELECT is set.

Cause:
The ApplyFilePath method in FileCtrl.pas calls the SetFileName method and SetFileName sets ItemIndex (twice). ItemIndex is a TCustomListBox property in StdCtrls.pas using the Windows LB_SETCURSEL message which has no effect for a multiple-selection list box and is documented thus in the Windows API documentation.

Solution / workaround
Only by recompiling the VCL:
In the TFileListBox.SetFileName method in FileCtrl.pas, change
   ItemIndex := -1;
to
   if MultiSelect then Selected[-1] := False else ItemIndex := -1;
and change
   ItemIndex := Item
to
   if MultiSelect then Selected[Item] := True else ItemIndex := Item;

Bug #69; last modified: before April 1998
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Absent Exists Exists Exists Exists Unknown Unknown Unknown
Win 3.1 - TOutline

TCustomItem.DrawCell passes wrong index to (F)OnDrawItem

Description
Reported by Andrew Jakobs; checked by Neil Booth
Because I was converting a Delphi 1.0 to Delphi 3.0 (for a 32bit version of the program), i ran into a problem with the Outline component. UC, I use the OnDrawItem Event, for drawing the items, but when I tried it in Delphi 3.0 is was all screwed up. The bug is, the OnDrawItem gets the ROW of the grid as the index of the node, and not the index of the node that needs to be drawn:
Original:  OUTLINE.PAS (delphi 3.0 (maybe also in 2.0))
----line 2147 (or near this line)

  if (Style = otOwnerDraw) and Assigned(FOnDrawItem) then
  begin
    if Row = ARow then
    begin
      if GetFocus = Self.Handle then
      begin
        FOnDrawItem(Self, ARow, ARect, [odFocused, odSelected]);
                          ^^^^^
        if ooDrawFocusRect in Options then
          DrawFocusRect(Canvas.Handle, ARect);
      end
      else FOnDrawItem(Self, ARow, ARect, [odSelected])
                             ^^^^^
    end
    else OnDrawItem(Self, ARow, ARect, []);
                          ^^^^^
    Exit;
  end;
Solution / workaround
Modify the above part of Outline.pas:
Correction: OUTLINE.PAS (delphi 3.0 (maybe also in 2.0))

  if (Style = otOwnerDraw) and Assigned(FOnDrawItem) then
  begin
    Node := GetVisibleNode(ARow);
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    if Row = ARow then
    begin
      if GetFocus = Self.Handle then
      begin
        FOnDrawItem(Self, Node.Index, ARect, [odFocused, odSelected]);
                          ^^^^^^^^^
        if ooDrawFocusRect in Options then
          DrawFocusRect(Canvas.Handle, ARect);
      end
      else FOnDrawItem(Self, Node.Index, ARect, [odSelected])
                             ^^^^^^^^^
    end
    else OnDrawItem(Self, Node.Index, ARect, []);
                          ^^^^^^^^^
    Exit;
  end;

Bug #70; last modified: before April 1998
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Exists Unknown Unknown Unknown Unknown Unknown Unknown Unknown
Win 3.1 - TOutline

TOutline.OnDrawItem passes incorrect index.

Description
The OnDrawItem event for owner-drawn TOutlines passes the index of the visible item to be drawn, not the actual item index. Also, the index is 0 based, whereas the TOutline index is 1 based. For example, if you have two nodes, each containing 5 subitems, the second node has an index of 7 (1 is the first node, 2-6 are the subnodes of 1). However, if the first node is collapsed and the second node is to be drawn, an index of 1 is passed (0 for the first node and the 5 subitems are not counted).
Solution / workaround
The following subroutine (provided by Marc Hoffman; with a correction by Tom Jensen) will convert the index passed to the actual item index:
procedure OutlineCorrectIndex(Outline: TOutline; var Index: longint): longint;
var
  x, visible: longint;
begin
  inc(Index);  { Adjust for 1 based, not 0 based }
  Visible := 0;
  x := 1;
  while (Visible < Index) and (x <= Outline.ItemCount)
  do begin
    if Outline.Items[x].IsVisible 
    then begin
      inc(Visible);
      if Visible = Index 
      then begin
        Index := x;
        break;
      end;
    end;
    inc(x);
  end;
end;

Bug #71; last modified: before April 1998
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Exists Unknown Unknown Unknown Unknown Unknown Unknown Unknown
Win 3.1 - TOutline

TOutline: Horizontal scrolling and resizing not correct.

Description
(A longer description with more elaboration on the cause is in the original mail message: rpt1_22a.txt)

Create a new project, put a TOutline on the form.
Set the following properties:
Align: alClient;
Scrollbars: ssHorizontal (or ssBoth)
Enter a LOOOONG line into the editor.
Resize the form so that it's width is rather small.
You will notice that a horizontal scrollbar has appeared. Now move the thumb to the right end of the scrollbar.
Increase the form's width (that is to increase the width of the TOutline). You will notice that what you expected to be drawn on the left side now is drawn on the right side of the box, eg: If the line you entered was
abcdefghiklmnopqrs then you now might see
-bitmap-   abcdefghij
and before resizing and after horizontal scrolling you will see
efghiklmnopqrs
after resizing you might see:
efghiklmnopqrs   -bitmap-   abcd

Solution / workaround
By Stefan Hoffmeister
I have uploaded to the Delphi Super Page a file called GRID_FIX.ZIP which contains a newly built GRIDS.DCU for Delphi __1.01__ This is because Borland has not released the source for VCL 1.02.

In that file you fill find some more details and as well the source patches that have to be applied to the 1.01 source to fix the problem.

NOTE: There may be problems with Delphi 1.02 and this bugfix.


Bug #92; last modified: before April 1998
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Exists Unknown Unknown Unknown Unknown Unknown Unknown Unknown
Win 3.1 - TTabbedNotebook

Tab controls does not respond if application does not have focus.

Description
TTabbedNotebook components in MDI child windows do not respond to mouse clicks if the MDI application does not have focus (i.e. is the active application).
Solution / workaround
There is no workaround known other than to click on the form somewhere besides a tab control.

Bug #510; last modified: 9-Dec-98
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Absent Exists Exists Exists Exists Exists Exists Exists
Win 3.1 - TTabbedNotebook

TTabbedNotebook duplicates its pages as a response to RecreateWnd

Description
Reported by Ed Eichman; checked by Reinier Sterkenburg
To reproduce:
Create a new app and drop a TabbedNotebook on the default form. Go to the Pages property and change the "default" page to "clone". On the Form.OnDblClick method, add one line: "RecreateWnd;" (which is used internally by the VCL for a number of different functions).
If you run the application, then every time you double click on the form, you will get a new "clone" page in your TabbedNotebook. This is due to the fact that the "pages" are saved off in TCustomTabControl.DestroyWnd and restored in TCustomTabControl.CreateWnd - even if they already exist!
Solution / workaround
Use TPageControls in stead of TTabbedNotebooks

Index page
The Delphi Bug Lists are maintained by Reinier Sterkenburg, with help from the DeBug Team.
All feedback is appreciated. See also the feedback section of the Delphi Bug List home page.