The Delphi Bug List

Visual Component Library (VCL)

Standard


The color codes indicate in which version(s) of Delphi the bug occurs and what its status is.
Latest update: 13 February 1999
Bug # Delphi versions Description
21 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TComboBox
TDBLookupCombo Style values csDropDown and csDropDownList override identical values of TComboBox/TDBComboBox/TDBLookupComboBox. Use StdCtrls.csDropDown and StdCtrls.csDropDownList to change the Style property at runtime.
25 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TComboBox
There is a bug in the write access methods of the SelStart and SelLength properties
26 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TComboBox
When setting the ItemIndex property, the combobox control is redrawn regardless of the new value.
27 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TComboBox
TComboBox (csDropDown) loses focus if Sorted is changed
28 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TComboBox
DropDownCount property does not work correctly in certain cases with owner drawn controls.
384 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TComboBox
Text replaced by matching item unexpectedly.
529 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TComboBox
It seems there is a bug in the TForm.Print function : if you print a form with comboboxes, the texts of the comboboxes are not printed.
36 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TCustomListBox
See TListBox
42 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TEdit
When using the read-only style, the control is not changed to have a gray background, like suggested in the Windows Interface Guidelines for Software Design by Microsoft, page 158.
52 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TLabel
TLabel.Alignment only works if TLabel.Layout = tlTop
512 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TLabel
TLabel does not show the correct background color after it is loaded if the color is clWindow
53 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TListBox
If you select an item in a ListBox with MultiSelect set to False an index out of range error can occur
54 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TListBox
TListBox.Items is declared as "TStrings" in the help file, however it is "TListboxStrings" which overrides, among other things, the Clear method of TStrings.
55 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TListBox
Handle cannot be registered with DragAcceptFiles API function.
56 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TListBox
General Protection Fault when ListBox is Freed while having focus.
401 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TListBox
The help documentation for the ItemIndex property does not describe its lack of functionality with multiple-selection list box styles.
433 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TListBox
The ItemIndex property of TListBox does not work property.
60 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TMainMenu
The TMainMenu of a main form will receive keyboard shortcuts even in the presence of another TMainMenu on an active child window.
64 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TMemo
Invisible TMemo becomes visible when assigned text
390 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TMemo
Adding strings with embedded Chr(0)'s in it gives inappropriate exception.
525 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TMemo
TMemo.WordWrap fails to enable word wrapping if ScrollBars is set to ssBoth or ssHorizontal.
527 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TMemo
TMemo is not grayed when its Enabled property is set to False
12 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TMenuItem
There is a bug in Menus.pas (in IterateMenus). It produces GPFs but it's very unlikely that this one gives you trouble.
65 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TMenuItem
MenuItems do not reflect changes to Caption, Visible, or Enabled properties..
516 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TMenuItem
If you assign an image list to a TMainMenu, and the height of your imagelist is small compared to the height of your menu text, the text gets cramped together and some of the text actually gets chopped off.
13 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TPopupMenu
There's something wrong with multi-level popup menus having hint properties
531 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 TStringGrid
There's a bug in TCustomGrid.InvalidateCol

Bug #25; last modified: before April 1998
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Unknown Exists Unknown Unknown Unknown Unknown Unknown Unknown
Standard - TComboBox

There is a bug in the write access methods of the SelStart and SelLength properties

Description
Reported by Hallvard Vassbotn
These properies are meant to set and return the start and length of the selection within the edit box of combobox. No matter what you set these properties to, the selection will start in position 0.

The reason for this erroneous behaviour seems to be a bug in the TCustomComboBox.SetSelStart and TCustomComboBox.SetSelLength methods in \DELPHI20\SOURCE\VCL\STDCTRLS.PAS for those that have the VCL source. I will not repeat the code here, but they send a CB_SETEDITSEL message to the control with wrong parameters in wParam and lParam.

According to my Win32 help file, the correct parameters are:

CB_SETEDITSEL (Win32)
wParam = 0;                           /* not used, must be zero */
lParam = MAKELPARAM((ichStart), (ichEnd);  /* start and end pos */
"An application sends a CB_SETEDITSEL message to select characters in the edit control of a combo box."
Solution / workaround
With the above information, we can fix the problematic methods. You could include these corrections directly in STDCTRLS.PAS, but a cleaner approach is to inherit from the buggy TComboBox and do a static override of the SelStart and SelLength properties. This new combobox can then be installed into the component palette.

Source code of TComboFix


Bug #26; last modified: before April 1998
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Unknown Exists Unknown Unknown Unknown Unknown Unknown Unknown
Standard - TComboBox

When setting the ItemIndex property, the combobox control is redrawn regardless of the new value.

Description
Reported by Jani Järvinen
If the new index value is equal to the old index, the control is redrawn, thus causing unpleasant and unnecessary flicker.
[Note: This bug does not apply to TListBox.]
Problem example:
Var I: Integer;
  ...
  With ComboBox1 do Begin
    I := ItemIndex;
    ItemIndex := I; { re-set to old value --> flicker }
  End;
The above code sets the ItemIndex of the combobox to the same value it already was. This causes the the control to be redrawn unnecessarily. This can lead to performance problems, or at least unpleasant flicker especially if the combobox items are "owner-drawn".

Problem location:
The STDCTRLS.PAS file in procedural method TCustomComboBox.SetItemIndex. The code sends a CB_SETCURSEL message to the control without checking if the item index has actually changed.

Solution / workaround
Solution #1: Check to see if the ItemIndex actually needs to be set.

Solution #1 example:
Var I : Integer;
  ...
  With ComboBox1 do Begin
    I := 123;                { set to the new value }
    If (I <> ItemIndex) Then { compare with old value }
      ItemIndex := I;        { if not equal, set property }
  End;
Solution #2: If you want to avoid this problem in the future and you have the VCL source code, you could modify STDCTRLS.PAS directly.
Solution #2 example:
{
New version of SetItemIndex: this version checks to see
if the "new" value is actually different than the
previous one.
}
procedure TCustomComboBox.SetItemIndex(Value: Integer);
begin
  if GetItemIndex <> Value then
    SendMessage(Handle, CB_SETCURSEL, Value, 0);
end;

Bug #27; 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
Standard - TComboBox

TComboBox (csDropDown) loses focus if Sorted is changed

Description
Reported by Eric Fookes; checked and improved by Stefan Hoffmeister
If the Sorted property of a TComboBox with style "csDropDown" is changed at runtime while the combobox has focus, the control will lose focus. It will only regain the focus if a task switch is performed or the user clicks into the control. It is *not* possible to set the focus by using TComboBox.SetFocus.

The reason for this misbehaviour is that a TComboBox actually consists of two windows each having a handle but only if it has the style "csDropDown": the combobox itself and an associated edit control. When Delphi changes the Sorted property, it will test whether the combobox has focus, remember this, recreate the window and finally restore the window (TWinControl.RecreateWnd). Unfortunately the focus test code tests the combobox for being focused (which it is not) and not the associated edit control (which does have focus) (see TWinControl.Focused). Delphi thus comes to the conclusion that the combobox is not focused and, consequentially, does not transfer back the focus once the window has be recreated.

The reason that TComboBox.SetFocus fails is that Delphi internally never noticed that the active control ("FActiveControl") changed - the call to SetFocus is optimized away.

Solution / workaround
There are two alternatives to solve this problem:
a) If you want to restrict yourself to VCL calls make the TComboBox control NOT the active control before setting the Sorted property. This circumvents the optimization. Example:
 if ComboBox1.HasFocus {and (ComboBox1.Style = csDropDown)} then
 begin
   Form1.ActiveControl := nil; { or any other control }
   RestoreFocus := true;
 end else
   RestoreFocus := false;

 ComboBox1.Sorted := true;

 if RestoreFocus then
   ComboBox1.SetFocus;
b) Manually set the focus using the Windows API; this solves the problem directly and is the preferred solution:
 if ComboBox1.HasFocus {and (ComboBox1.Style = csDropDown)} then
   RestoreFocus := true
 else
   RestoreFocus := false;

 ComboBox1.Sorted := true;

 if RestoreFocus then
   WinProcs.SetFocus(ComboBox1.Handle);

Bug #28; last modified: before April 1998
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Exists Fixed Fixed Fixed Fixed Fixed Fixed Fixed
Standard - TComboBox

DropDownCount property does not work correctly in certain cases with owner drawn controls.

Description
TComboBox controls with the Style property set to csOwnerDrawFixed or csOwnerDrawVariable do not correctly calculate the size of the drop down list in certain cases. The DropDownCount property is used to specify how many items are to be displayed when the ComboBox is "opened." This property works fine as long as the size of the item you are displaying is based on the font assigned to the control. If you look at the TCustomComboBox.AdjustDropDown method in the VCL source code (STDCTRLS.PAS), you will see that to calculate the size of the dropdown window, the DropDownCount property is multiplied by the height of the control's font. This calculation should be using the ItemHeight property. This can cause problems which draw items that are not based on a font, such as icons.
Solution / workaround
The simplest way to fix this is to just ensure that Font.Height is equal to ItemHeight. Note that you should probably use a TrueType font for Font.Name so that it can cover a wide range of sizes.

The best way is to fix the VCL source code so that AdjustDropDown does the calculation properly using ItemHeight.


Bug #384; last modified: 13-Aug-98
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Unknown Unknown Unknown Unknown Exists Exists Exists Unknown
Standard - TComboBox

Text replaced by matching item unexpectedly.

Description
Reported by Bevan Arps; checked by Reinier Sterkenburg
I've found what seems to be a problem with the standard TComboBox component.
Try this ...
  1. Create a new application and put two buttons and a combo box on it.
    Arrange these as pleases your eye.
  2. Set the items property of the combo box to:
    one
    two
    three
    2a. Set the Text property of the combo box to empty
  3. Set one button to set the colour of the font used to blue:
    ComboBox1.Font.Color := clBlue
  4. Set the other button to set the colour to black:
    ComboBox2.Font.Color := clBlack;
  5. Run the application
  6. Type a single "o" into the combo
  7. Press one of the buttons
Just like magic, the "o" you typed in will be replaced with "one".

It seems that whenever you change the font color, the contents of the text property are replaced by the first matching entry from items.

Solution / workaround
In my descendant I've worked around this as follows:
    sText := Text;
    nSelStart := SelStart;
    nSelLen   := SelLength;
    Font.Color := nTextColor;
    inherited Text := sText;
    SelStart  := nSelStart;
    SelLength := nSelLen;
But this is kinda messy.

I'd be interested to see a cleaner workaround and would like to ask the Borland reps to fix this in Delphi 4?


Bug #42; last modified: 25-Oct-98
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Unknown Exists Exists Exists Exists Exists Exists Exists
Standard - TEdit

When using the read-only style, the control is not changed to have a gray background, like suggested in the Windows Interface Guidelines for Software Design by Microsoft, page 158.

Description
Reported by Jani Järvinen; checked by Erik Berry
Solution / workaround
  1. Set the color manually.
      With Edit1 do Begin
        ReadOnly := True; { set to read-only }
        Color := clBtnFace; { indicate different behavior to user}
       ...
        ReadOnly := False; { back to read-write }
        Color := clWindow; { restore normal color }
      End;
  2. Derive a new component (TFixedEdit) from TEdit in which this correction is applied
  3. Apply the correction in the VCL source (StdCtrls.TCustomEdit.SetReadOnly)

Bug #52; last modified: before April 1998
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
N/A N/A Exists Unknown Unknown Unknown Unknown Unknown
Standard - TLabel

TLabel.Alignment only works if TLabel.Layout = tlTop

Description
Reported by Mike Wishart; confirmed by Stefan Hoffmeister; fix by Jim Rofkar
Setting the Alignment property of TLabel has no effect in Delphi 3 (5.53) if the Layout property is anything but tlTop.
Example:
With Layout = tlCenter and Alignment = taCenter, you would expect the caption to be centered both vertically and horizontally in the ClientRect, however, it is only centered vertically and left justified.
Solution / workaround
To fix this bug:
procedure TCustomLabel.Paint;
const
  Alignments: array[TAlignment] of Word = (DT_LEFT, DT_RIGHT, DT_CENTER);
  WordWraps: array[Boolean] of Word = (0, DT_WORDBREAK);
var
  Rect: TRect;
  TxtRect: TRect; // Add this!
  DrawStyle: Integer;
begin
  with Canvas do
  begin
    if not Transparent then
    begin
      Brush.Color := Self.Color;
      Brush.Style := bsSolid;
      FillRect(ClientRect);
    end;
    Brush.Style := bsClear;
    Rect := ClientRect;
    DrawStyle := DT_EXPANDTABS or WordWraps[FWordWrap] or 
                 Alignments[FAlignment];
    { Calculate vertical layout }
    if FLayout <> tlTop then
    begin
      // Modifications start here!
      TxtRect := Rect;
      DoDrawText(TxtRect, DrawStyle or DT_CALCRECT);
      if FLayout = tlBottom then 
        OffsetRect(Rect, 0, Height - (TxtRect.Bottom - TxtRect.Top))
      else 
        OffsetRect(Rect, 0, (Height - (TxtRect.Bottom - TxtRect.Top)) div 2);
      // Modifications end here!
    end;
    DoDrawText(Rect, DrawStyle);
  end;
end;

Bug #512; last modified: 20-Dec-98
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
N/A N/A Exists Exists Exists Exists Exists Exists
Standard - TLabel

TLabel does not show the correct background color after it is loaded if the color is clWindow

Description
Reported by Mike Lischke; checked by Reinier Sterkenburg
To reproduce:
Take any TForm, place a label on it, set its Color property to clWindow. Switch to "View as text" and switch back to "View as form". Now the label's color is clBtnFace (or whatever color the parent of the label has).
Solution / workaround
Explicitly set the label's Color to clWindow after creation.

Bug #53; last modified: 13-Feb-99
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Exists Exists Exists Exists Exists Unknown Unknown Unknown
Standard - TListBox

If you select an item in a ListBox with MultiSelect set to False an index out of range error can occur

Description
Reported by Enzo Lombardi; checked by Neil Booth
If you select an item in a ListBox with MultiSelect set to False with a line like this:
ListBox1.Items.Add('Now there is one item');
ListBox1.Selected[0] := True;
an index out of range error occurs.

Verification, edited description and workaround by Neil Booth:
This does indeed produce an exception on running, when ListBox1.MultiSelect is False. A cure is to have ListBox1.MultiSelect set to True at the time of setting Selected[0] to True. This is not very desirable as this involves recreating the window and flicker.

The cause of the problem is that Selected[0] calls the VCL TCustomListBox.SetSelected, which posts an LB_SETSEL message to the list box. In the Windows help under LB_SETSEL, it states "Use this message only with multiple-selection list boxes."

Thus it is a bug in Delphi, as they do not state this limitation in Delphi's documentation.

Solution / workaround
The solution is to use LB_SELECTSTRING for non-multiselect boxes. The following works OK under 32 bit Delphi.

Replace the original VCL code:
procedure TCustomListBox.SetSelected(Index: Integer; Value: Boolean);
begin
  if SendMessage(Handle, LB_SETSEL, Longint(Value), Index) = LB_ERR then
    raise EListError.CreateFmt(SListIndexError, [Index]);
end;
with:
procedure TCustomListBox.SetSelected(Index: Integer; Value: Boolean);
begin
  if (MultiSelect and 
      (SendMessage(Handle, LB_SETSEL, Longint(Value), Index) = LB_ERR)) 
     or
     (not MultiSelect and 
      (SendMessage(Handle, LB_SELECTSTRING, LongInt(Index), 
                   LongInt(PChar(Items[Index]))) = LB_ERR)) 
  then 
    raise EListError.CreateFmt(SListIndexError, [Index]);
end;

Bug #54; last modified: before April 1998
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Unknown Exists Unknown Unknown Unknown Unknown Unknown Unknown
Standard - TListBox

TListBox.Items is declared as "TStrings" in the help file, however it is "TListboxStrings" which overrides, among other things, the Clear method of TStrings.

Description
By Per-Eric Larsson

TListBox.Items is declared as "TStrings" in the help file, however it is created as "TListboxStrings", which overrides, among other things, the Clear method of TStrings. I've had a problem when filling a listbox with objects, using the lbOwnerDrawFixed style and drawing the contents myself: When erasing the contents of the listbox, only the strings were removed, the memory allocated by the objects was still in use.
The problem can be explained by this bug.
Code from stdctrls.pas:
constructor TCustomListBox.Create(AOwner: TComponent);
const
  ListBoxStyle = [csSetCaption, csDoubleClicks];
begin
  inherited Create(AOwner);
  ...
  FItems := TListBoxStrings.Create;
So, although FItems is declared as TStrings, the Items are NOT TStrings but TListBoxStrings! And here is the Clear method of TListBoxStrings:
procedure TListBoxStrings.Clear;
begin
  SendMessage(ListBox.Handle, LB_RESETCONTENT, 0, 0);
end;
Just a Windows message - could possibly work if items are inserted by the pointer method - as used in Win3.X when inserting large numbers of data into a Listbox but ....

Is this a bug or simply Bad documentation? I'd say this is a bug. And therefore it's placed here and not on the docs page - RS

Solution / workaround
I had to do the following to make sure all the contents of the listbox was erased:
  with listbox1 do begin
    while items.count>0 do begin
      items.objects[items.count-1].free;
      items.delete(items.count-1);
    end;
  end;

Bug #55; last modified: before April 1998
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Exists Fixed Fixed Fixed Fixed Fixed Fixed Fixed
Standard - TListBox

Handle cannot be registered with DragAcceptFiles API function.

Description
The Windows API function DragAcceptFiles that is used to register windows as able to receive files dropped from file manager applications will not work with TListBox components. To see the error, create a new form with a TListBox, TButton and TEdit control. In the form's OnCreate or OnShow event, add the following lines (you will need to add ShellAPI to your uses clause):
  DragAcceptFiles(Edit1.Handle);
  DragAcceptFiles(Button1.Handle);
  DragAcceptFiles(ListBox1.Handle);
Run the application and drag a file from File Manager over each of the controls. The cursor will indicate that it can be dropped on the button and edit controls, but not on the listbox. Note for PCTools for Windows users: It will appear as if the file can be dropped on the listbox, but doing so actually passes the dropped file on to the desktop window, creating a new icon on it. Very strange indeed.
Solution / workaround
A quick glance and the VCL did not reveal any strange manipulation of the Handle property, so I am not sure what is causing this problem. If anyone has any ideas, please send them to me and I will investigate further. A viable work-around for the problem is to register the handle of the form that owns the listbox and handle the event there.

Bug #56; last modified: 25-Oct-98
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
Exists Exists Exists Unknown Unknown Unknown Fixed Fixed
Standard - TListBox

General Protection Fault when ListBox is Freed while having focus.

Description
If a listbox with a style of lbOwnerDrawFixed is placed on a form, and it has the focus, then freeing it will cause a GPF in the TCanvas.SetFont method. In order to avoid the GPF, the control must be disabled first.

To reproduce:
  • Place a listbox on a form
  • Set the listbox's Style to lbOwnerDrawFixed
  • Set focus to the listbox
  • Free the listbox
  • CRASH! (GPF)
    Solution / workaround
    The workaround is to set the listbox's Enabled property to false to remove focus from it prior to freeing it. Then the GPF does not occur.

    Bug #401; last modified: 29-Dec-98
    1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
    Exists Exists Exists Exists Exists Exists Exists Exists
    Standard - TListBox

    The help documentation for the ItemIndex property does not describe its lack of functionality with multiple-selection list box styles.

    Description
    Reported by Chris Cheney; checked by Reinier Sterkenburg
    To see what's wrong:
    1. Start a new, default project and drop 2 ListBox components onto the form.
    2. Set the OnFormCreate event routine to
      procedure TForm1.FormCreate(Sender: TObject);
      var
        I: Integer;
      begin
        { populate both list boxes }
        for I := 0 to 9 do ListBox1.Items.Add(Format('%d', [I]));
        ListBox2.Items.Assign(ListBox1.Items);
         { set ItemIndex and Selected properties }
        ListBox1.ItemIndex := 2;
        ListBox2.Selected[2] := True;
      end;
    3. Using the Object Inspector, set the MultiSelect property for ListBox2 to True, leaving that for ListBox1 as False.
    4. (Compile and) Run.
    5. The string '2' in each list box will be highlighted, as documented.
    6. Close the form and, using the Object Inspector, set the MultiSelect property for ListBox1 to True.
    7. (Compile and) Run.
    8. The string '2' will NOT be highlighted in ListBox1, contrary to documentation.
    To summarize:
    Setting ItemIndex has no effect on the list box selection if MultiSelect is True.

    This limitation is not documented. One would expect the ItemIndex list box properties to be settable independent of whether or not the list box is MultiSelect.

    Cause:
    The VCL code (STDCTRLS.PAS) for TCustomListBox and its TListBox descendant is not written to overcome the lack of functionality for the Windows 3.1 API (LB_SETCURSEL and LB_SETSEL messages) affecting the ItemIndex and Selected list box properties and their associated methods for multiple-selection and single-selection styles respectively.

    When the Selected property is used on a single-select list box, LB_ERR is returned as the result of the LB_SETSEL windows message; this causes the exception to be raised (in the TCustomListBox.SetSelection method).

    Windows 3.1 API specifies that the LB_SETCURSEL message (used to set the ItemIndex property) has no effect on multiple-selection list boxes and that the LB_SETSEL message (used to set the Selected property) delivers LB_ERR as the result. These limitations have not been carried through to the ItemIndex and Selected documentation.


    Bug #433; last modified: 13-Aug-98
    1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
    Absent Absent Absent Absent Absent Exists Fixed Fixed
    Standard - TListBox

    The ItemIndex property of TListBox does not work property.

    Description
    Reported by Mark Bracey; confirmed by several people on the newsgroups
    To reproduce:
    Create a project with a TListbox component on it, and add 5 items to the listbox. Set the listbox's MultiSelect property to TRUE. Add two buttons to the form. In the first button's OnClick handler, add this code:
      ListBox1.ItemIndex := -1;
    In the second button's OnClick handler, add this:
      ShowMessage(IntToStr(Listbox1.ItemIndex));
    Run the app. Select an item in the listbox. Click button 1. Notice that the selection remains, even though ItemIndex := -1 should clear it. Click the second button. Notice that it reports -1 even though a selection still exists in the listbox.

    Also with MultiSelect = FALSE, the behaviour is not what you would expect: If an item is selected and you press Button1, the selection disappears, but if you then press Button2, it reports a value >=0 for ItemIndex.

    The cause of this second problem lies in the D4 Implementation of GetItemIndex:

    function TCustomListBox.GetItemIndex: Integer;
    begin
      if not MultiSelect then
        Result := SendMessage(Handle, LB_GETCARETINDEX, 0, 0) else
        Result := SendMessage(Handle, LB_GETCURSEL, 0, 0);
    end;
    D3:
    function TCustomListBox.GetItemIndex: Integer;
    begin
        Result := SendMessage(Handle, LB_GETCURSEL, 0, 0);
    end;
    And the D4 implementation is obviously not correct.
    Solution / workaround
    #1) Make the correction in StdCtrls.pas and recompile the VCL. This is not a very favourable solution as this makes it impossible to use packages.

    #2) Create a descendant of TListBox and replace the ItemIndex property completely, supplying your own read and write methods with the above fixed code. The write method is correct, so it can simply be copied from the existing VCL source.

    #3) Don't use the ItemIndex property. Instead use the LB_GETCARETINDEX/LB_SETCARETINDEX messages directly with SendMessage for multiselect listboxes, and LB_GETCURSEL/LB_SETCURSEL messages with non-multiselect listboxes.


    Bug #60; 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
    Standard - TMainMenu

    The TMainMenu of a main form will receive keyboard shortcuts even in the presence of another TMainMenu on an active child window.

    Description
    When launching a modeless child form with a TMainMenu from the main form (parent form) which also has a TMainMenu, all keyboard shortcuts that are not handled by the child's TMainMenu go to the parent form.
    Example: if the parent has "&Help" and the child has no such menu item, pressing Alt+H will activate the parent form and open its "Help" menu.
    Ray Lischner's explanation for this problem is:
    The way this works is that the child form notifies the Application object of the key strokes by sending the Cm_AppKeyDown and Cm_AppSysCommand messages. The Application then forwards these messages to the main form, which handles them.
    Solution / workaround
    By Ray Lischner
    You can set a message hook for the main form, to intercept these messages, and prevent them from reaching the main form. That lets the child form handle the keyboard events normally.
    To set the hook, read about TApplication.HookMainWindow in the on-line documentation. Unfortunately, the Cm_AppKeyDown and Cm_AppSysCommand messages are not documented (Note: They are documented in Ray Lischner's book "Secrets of Delphi 2"). To handle these messages, the hook function returns True, saying that the message has been handled, but the handler leaves the message Result as 0, which tells the child form to continue processing the message normally.
    For example:
    function TMainForm.AppKeyDownHook(var Msg: TMessage): Boolean;
    begin
      case Msg.Msg of
        Cm_AppkeyDown:
          Result := True; { test here whether to act locally }
        Cm_AppSysCommand:
          Result := True; { test here whether to act locally }
        else
          Result := False; { event will go to the parent's main menu }
      end;
    end; 
    
    procedure TMainForm.FormCreate(Sender: TObject);
    begin
      Application.HookMainWindow(AppKeyDownHook)
    end;

    Bug #64; last modified: before April 1998
    1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
    Exists Fixed Fixed Fixed Fixed Fixed Fixed Fixed
    Standard - TMemo

    Invisible TMemo becomes visible when assigned text

    Description
    Reported by Henry In 't Veld; checked by Stefan Hoffmeister
    To reproduce the problem
  • drop two TMemo components and a button on a form
  • set TMemo1.Visible := false in the Object Inspector
  • drop a TButton onto the form and assign to its event handler
  • procedure TForm1.Button1Click(Sender: TObject);
    begin
      Memo1.Lines.Assign(Memo2.Lines);
    end;
  • Run this program, click the button and see Memo1 appear.
  • Solution / workaround
    By Borland (Delphi 3.0 (5.53) source code)

    Since the comments by Borland say it all we reproduce the corresponding routine from the Delphi 3 VCL source code. It is safe to use; the conditional defines are added here to single out the changes.
    procedure TMemoStrings.SetUpdateState(Updating: Boolean);
    begin
    {$IFDEF FixAppearingMemoBug}
      if Memo.HandleAllocated then
      begin
    {$ENDIF}
    
        SendMessage(Memo.Handle, WM_SETREDRAW, Ord(not Updating), 0);
        if not Updating then
        { WM_SETREDRAW causes visibility side effects in memo controls }
        begin    
    
    {$IFDEF FixAppearingMemoBug}
          { This reasserts the visibility we want }
          Memo.Perform(CM_SHOWINGCHANGED,0,0);  
    {$ENDIF}
    
          Memo.Refresh;
        end;
    
    {$IFDEF FixAppearingMemoBug}
      end;
    {$ENDIF}
    
    end;
    There appears (ha ha - Neil) to be no work-around.

    Bug #390; last modified: 13-Apr-98
    1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
    Exists Fixed Fixed Fixed Fixed Fixed Fixed Fixed
    Standard - TMemo

    Adding strings with embedded Chr(0)'s in it gives inappropriate exception.

    Description
    Reported by Chris Cheney; checked by Reinier Sterkenburg
    An out of resources exception (EOutOfResources) occurs if a (Pascal) string which contains one or more null characters (Chr(0)) is passed to the Add or Insert methods of a TMemo's Lines property in Delphi 1.
    To reprod\uce the bug:
    1. Create a new (default) project with a main form Form1.
    2. Drop a Memo component (Memo1) from the Standard controls palette onto the form.
    3. Add an OnFormShow event handler (display Form1 in the Object Inspector, select the Events tab, double-click in the OnFormShow value box) with the following code:
      procedure TForm1.FormShow(Sender: TObject);
      begin
        Memo1.Lines.Add('Here is a null char >' + Chr(0) + '<')
      end;
    4. (Compile and) Run.
      Now you get the EOutOfResources exception with the message "Unable to insert a line". If you continue running, you'll see that the part before the Chr(0) has actually been inserted.

    Although the message of the exception *is* appropriate, the type of the exception is not.

    The expected behaviour would be:
    Any one of the following:
    a) Embedded null characters translated to other characters, e.g. blanks, and the result inserted/added into the memo; or
    b) Embedded null characters eliminated from the string and the result inserted/ added into the memo; or
    c) The string up to the first null character inserted/added to the memo
    This is what actually happens in Delphi 2 and Delphi 3, RPS; or
    d) An exception indicating the presence of a null character in the Pascal string parameter.
    What one should/could expect is not described in the documentation.

    Solution / workaround
    a) User-level: check for embedded nulls before calling the add/insert methods.
    or
    b) fix the VCL (stdctrls.pas) in MemoStrings.Insert by changing
      if Memo.SelStart <> (Selection.EndPos + Length (S) + 2) then
        raise EOutOfResources.Create(LoadStr(SInsertLineError));
    to
      if Memo.SelStart <> (Selection.EndPos + StrLen(Text)) then
        raise EOutOfResources.Create(LoadStr(SInsertLineError));

    Bug #525; last modified: 19-Jan-99
    1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
    Unknown Unknown Unknown Unknown Unknown Unknown Unknown Gotcha
    Standard - TMemo

    TMemo.WordWrap fails to enable word wrapping if ScrollBars is set to ssBoth or ssHorizontal.

    Description
    Reported by Graham Wideman
    This is a gotcha -- cuz the Help (a) doesn't warn of this interaction, and (b) in fact implies otherwise, stating "There should be no use for a horizontal scroll bar if WordWrap is True".

    Bug #527; last modified: 7-Feb-99
    1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
    Exists Fixed Fixed Fixed Fixed Fixed Fixed Fixed
    Standard - TMemo

    TMemo is not grayed when its Enabled property is set to False

    Description
    Reported by Chris Cheney; checked by Reinier Sterkenburg
    TEdit/TComboBox controls do not appear dimmed if their Enabled properties are False when first made visible; TMemo never appears dimmed when not Enabled. Note: The TMemo problem has been reproduced independently; the other two seem not to occur on an NT system(?)

    The Delphi 1 online help on the Enabled Property states that 'Disabled controls appear dimmed'. (The version of Delphi is 1.02, running on Windows 3.1 and Windows for WorkGroups 3.11, both with Win32s.)

    To reproduce:

    In summary:
    Bug 1: TMemo is never greyed.
    Workaround: set the font colour explicitly to clGrayText when required.

    Bug 2, 3: TEdit and TComboBox will be greyed only if they are made visible and then changed from enabled to disabled. Note that 'made visible' means that their Visible property and the Visible properties of all their parent controls are True.
    Workaround: if, when these controls first become visible, they are in the disabled state, set their Enabled properties to True and then immediately back to False.


    Bug #12; last modified: 27-Dec-98
    1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
    Exists N/A N/A N/A N/A N/A N/A N/A
    Standard - TMenuItem

    There is a bug in Menus.pas (in IterateMenus). It produces GPFs but it's very unlikely that this one gives you trouble.

    Description
    Reported by Paul Sleigh; edited by Stefan Hoffmeister
    ONLY if you are using the VCL *source* code to compile your projects and ONLY if you have turned on "Force Far Calls" ({$F+}) for the *complete* project you will notice this bug. So if you never touched MENUS.PAS you do not have this problem:
    A GPF will occur in MENUS.PAS if a menu is created in the project. This is because a short piece of inline assembler in "Iterate", a local function of "IterateMenus" assumes that calls will always be made to a "near" procedure.
    Solution / workaround
    Either turn off the project option "Force Far Calls" or add a line at the start of MENUS.PAS saying "{$F-}" which will turn off far calls for MENUS.PAS.

    Bug #65; last modified: 11-Jul-98
    1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
    Exists Exists Unknown Unknown Unknown Unknown Unknown Unknown
    Standard - TMenuItem

    MenuItems do not reflect changes to Caption, Visible, or Enabled properties..

    Description
    Reported by Jeff Lawrence
    It happens (the bug) with MDI Child windows setting menu items in the *top* level, that is, on the menu bar itself. Changes *are* seen when the menu items to be changed are not on the title bar.
    Caveat: The changes do eventually manifest if other child window are focused, and you return to the first window (and call AdjustUpdates from OnActivate).

    Code snippet. The changes to Top-level menus do not show; the changes to lower level menus do show. All menu items are owned by the MDI child.

    Procedure AdjustMenus;
      begin {AdjustMenus}
        if sType = sDNA then begin
          MnDNA.Enabled := TRUE;         {top level - WILL NOT SHOW}
          MnParse.Enabled := TRUE;       {lower level - works}
          MnAddORFs.Enabled := TRUE;     {lower level - works}
          MnProtein.Enabled := FALSE;    {top level - WILL NOT SHOW}
          end else begin
            MnDNA.Enabled := FALSE;         {top level - WILL NOT SHOW}
            MnParse.Enabled := FALSE;       {lower level - works}
            MnAddORFs.Enabled := FALSE;     {lower level - works}
            MnProtein.Enabled := TRUE;      {top level - WILL NOT SHOW}
            end; {else}
      end; {AdjustMenus}

    Bug #516; last modified: 20-Dec-98
    1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
    N/A N/A N/A N/A N/A Exists Exists Exists
    Standard - TMenuItem

    If you assign an image list to a TMainMenu, and the height of your imagelist is small compared to the height of your menu text, the text gets cramped together and some of the text actually gets chopped off.

    Description
    Reported by Luu Tran; checked by Reinier Sterkenburg
    D4 is not respecting the system metrics settings for menu items. It seems only to consider the height of the bitmap and not the text and proper vertical spacing between menu items.

    To reproduce, create an imagelist with dimension 16x16 or so. In Windows Control panel, use Large Font display, and set menu text to MS Sans Serif 10. You will see your D4 menus with bitmaps are cramped vertically, compared to regular menus.


    Bug #13; last modified: before April 1998
    1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
    Unknown Unknown Exists Unknown Unknown Unknown Unknown Unknown
    Standard - TPopupMenu

    There's something wrong with multi-level popup menus having hint properties

    Description
    Reported by Tianyu Wen; checked by Glenn Crouch
    Follow these steps to reproduce it:
    1. Create a popup menu with 2 levels. On the first level, place 2 items, item1 and item2. For the submenu of item1, add item11 and item12. For the submenu of item2, add item21 and item22.
    2. Add some unique verbage to each of the above menu items' hint property.
    3. Now create a small DisplayHint() procedure to display the Application.Hint onto a status bar or a panel.
    4. Run the program and see if the popup menu items' hint get displayed properly.
    What I've noticed is that item1 and item2 hint properties do NOT get displayed, but item11, item12, item21 and item22 hint property are displayed. And sometimes junk values get displayed for item1 and item2 hint property. Hmm, seems like a bug to me.

    Comment from checker:
    I was able to reproduce this problem. IMHO this is a bug...


    Bug #531; last modified: 9-Feb-99
    1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02
    Unknown Unknown Unknown Unknown Unknown Unknown Unknown Exists
    Standard - TStringGrid

    There's a bug in TCustomGrid.InvalidateCol

    Description
    Reported by Rune Moberg
    The following works:
    procedure TCustomGrid.InvalidateCol(ACol: Longint);
    var
      Rect: TGridRect;
    begin
      if not HandleAllocated then Exit;
      Rect.Top := TopRow;
      Rect.Left := ACol;
      Rect.Bottom := TopRow+VisibleRowCount;
      Rect.Right := ACol;
      InvalidateRect(Rect);
    end;
    This is the original D4.02 code:
    procedure TCustomGrid.InvalidateCol(ACol: Longint);
    var
      Rect: TGridRect;
    begin
      if not HandleAllocated then Exit;
      Rect.Top := 0;
      Rect.Left := ACol;
      Rect.Bottom := VisibleRowCount+1;
      Rect.Right := ACol;
      InvalidateRect(Rect);
    end;
    I have a grid that needs to have dynamic content in the topmost cell. When the user scrolls upwards, the entire left column needs to be repainted (actually, it would suffice to only paint the uppermost cells, but TCustomGrid doesn't bother surfacing InvalidateRect from its private section).

    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.