| Bug # | Delphi versions | Description |
| 20 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TCheckListBox There is a memory leak in TCheckListBox when calling GetItemData |
| 33 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TCustomGrid TCustomGrid unnecessarily shows scrollbars |
| 34 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TCustomGrid MoveColRow method's final parameter "Show" has no effect |
| 35 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TCustomGrid Descendant components cause run-time error 210. |
| 48 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TImage TImage causes memory leak. |
| 61 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TMaskEdit On some computer/keyboard combinations, TMaskEdit causes a keyboard lock or a big slowdown and a blinking numlock. |
| 62 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TMaskEdit This control will not correctly process ENTER and ESC keys in dialogs. |
| 63 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TMaskEdit Some mask characters are not properly handled if specified as literal characters. |
| 104 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TNoteBook Deleting the first page of a TNoteBook gets you in trouble. |
| 81 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TSpeedButton OnDblClick Event is never called if AllowAllUp = true. |
| 85 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TStringGrid See also TCustomGrid |
| 86 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TStringGrid TStringGrid's Cursor won't move at Shift-TAB |
| 87 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TStringGrid Calling Insert and Delete methods of Cols and Rows properties gives Error 210. |
| 88 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TStringGrid Bug in TStringGrid with goRowSelection |
| 89 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TStringGrid TStringGrid needs string content to store object data |
| 406 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TStringGrid If any TabStops[col] are set to False but no non-default ColumnWidths are set in a TDrawGrid/TStringGrid and the ColumnCount is increased, random tab stops result and, store overwriting and GPFs could occur. |
| 407 | 1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 |
TStringGrid If the last row height (column width, tab stop) of a TDrawGrid/TStringGrid is not equal to the DefaultRowHeight (DefaultColWidth, True) and the number of rows (columns) is increased, the height of that row (width of that column, tabstop) gets set to the default. |
Bug #20; 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 | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
Bug #33; 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 |
function ScrollBarVisible(Code: Word): Boolean;
var
Min, Max: Integer;
begin
Result := False;
case Code of
sb_Horz:
if (Scrollbars = ssBoth) or
(Scrollbars = ssHorizontal) then
Result := (GetWindowLong(Handle, gwl_Style) and WS_HSCROLL) <> 0;
sb_Vert:
if (Scrollbars = ssBoth) or
(Scrollbars = ssVertical) then
Result := (GetWindowLong(Handle, gwl_Style) and WS_VSCROLL) <> 0;
end;
end;
Bug #34; 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 |
TCustomGrid.MoveColRow(ACol, ARow: Longint; MoveAnchor, Show: Boolean);Contrary to CWG, the final parameter "show" has no effect (because MoveColRow directly calls the private MoveCurrent (same parameters), which does not use its last parameter).
Bug #35; last modified: before April 1998| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Gotcha | Fixed | Fixed | Fixed | Fixed | Fixed | Fixed | Fixed |
protected
{ Protected declarations }
procedure DrawCell(ACol, ARow: Longint;
ARect: TRect; AState: TGridDrawState); override;
{ ..... }
procedure TMyGrid.DrawCell(ACol, ARow: Longint;
ARect: TRect; AState: TGridDrawState);
begin
{ Print Column, Row in each cell }
Canvas.TextOut(ARect.Left, ARect.Top, IntToStr(ACol)+', '+IntToStr(ARow));
end;
Bug #48; 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 |
procedure MemFree(Ptr: Pointer; Size: LongInt);
begin
if Size > $FFFF then
GlobalFreePtr(Ptr)
else
FreeMem(Ptr, Word(Size))
end;
Bug #62; last modified: before April 1998| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Gotcha | Gotcha | Gotcha | Gotcha | Gotcha | Gotcha | Gotcha | Gotcha |
Solution:
If you would like the MaskEdit to behave like any other component,
either modify the WMGetDlgCode method of the TCustomMaskEdit component
in the VCL source code or create a descendant component that handles the
WMGetDlgCode differently, like in the following example:
type TMyMaskEdit = class(TMaskEdit)
protected
procedure wmGetDlgCode(Var Msg: TWMGetDlgCode); message WM_GETDLGCODE;
end;
procedure TMyMaskEdit.wmGetDlgCode(var Msg: TWMGetDlgCode);
begin
{ do not call inherited message handler, instead specify wanted keys here }
Msg.Result := DLGC_HASSETSEL or DLGC_WANTARROWS or DLGC_WANTCHARS;
end;
Bug #63; 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 |
To see the problem, start the International applet in Control Panel. Choose the Change button for Date Format. Enter any character other than / as the Separator. Close the International applet completely, as changes will not take effect until you do. Now try a TMaskEdit control that has "99\/99\:99" for it's EditMask property. According to documentation, the edit control with data in it should look like "34/12:32", but it really discards the \ literal specifier and uses the international settings, the same as it would if you had not given the literal at all. This problem is especially bad for applications that will be used outside of the US, which is becoming common with shareware programs distributed via the Internet.
There is no solution known at this time short of fixing the bug in the VCL source code. I have not had time to do this, so cannot advise on how to. If anyone knows of a work-around, or has fixed the VCL source, please send it to me so that it can be published here.
Bug #104; last modified: before April 1998| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Exists | Exists | Unknown | Unknown | Unknown | Unknown | Unknown | Unknown |
Bug #81; last modified: 25-Oct-98| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Exists | Exists | Exists | Exists | Exists | Exists | Exists | Unknown |
Erik Berry added to this (22 Oct 98):
In fact, OnDblClick is never called, regardless of the value
of AllowAllUp
procedure TSpeedButton.WMLButtonDblClk(var Message: TWMLButtonDown);
begin
inherited;
{$IFDEF FixSpeedButtonDblClick}
DblClick;
{$ELSE}
if FDown then DblClick;
{$ENDIF}
end;
This is the preferred solution as it avoids adding irritating logic in
case of the workaround below.
procedure TForm1.SpeedButton1DblClick(Sender: TObject);
begin
ShowMessage('Double-Click');
end;
procedure TForm1.SpeedButton1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if (Button = mbLeft) and (ssDouble in Shift) then
SpeedButton1DblClick(Sender);
{ continued processing }
end;
Bug #86; last modified: before April 1998| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| N/A | Unknown | Exists | Unknown | Unknown | Unknown | Unknown | Unknown |
Shift := [];Move this to line 2955,
end; Shift := []; MaxTopLeft.X := ColCount - 1;Notes from checker:
inherited;
if ssShift in Shift then
DoSomething;
This expression will never be true using the above fix. A better solution
might be to replace line 2940 of grids.pas with this:
if TabStops[NewCurrent.X] or (NewCurrent.X = FCurrent.X) then Shift := [];
Bug #87; 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 |
Bug #88; 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 |
procedure TCustomGrid.MoveAnchor(const NewAnchor: TGridCoord);
var
OldSel: TGridRect;
begin
if [goRangeSelect, goEditing] * Options = [goRangeSelect] then
begin
OldSel := Selection;
FAnchor := NewAnchor;
{$IFDEF FixRowSelectBug}
if goRowSelect in Options then FAnchor.X := ColCount - 1;
{$ELSE}
if goRowSelect in Options then FAnchor.Y := ColCount - 1;
{$ENDIF}
ClampInView(FAnchor);
SelectionMoved(OldSel);
end
else MoveCurrent(NewAnchor.X, NewAnchor.Y, True, True);
end;
Bug #89; last modified: 25-Oct-98| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Exists | Unknown | Unknown | Unknown | Unknown | Unknown | Fixed | Fixed |
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
{ this will cause the problem }
StringGrid1.Cells[1, 1] := '';
StringGrid1.Objects[1, 1] := TObject.Create;
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
StringGrid1.Cells[1, 1] := 'Any text';
StringGrid1.Objects[1, 1] := TObject.Create;
end;
procedure TStringSparseList.PutObject(Index: Integer; AObject: TObject);
var
p: PStrItem;
begin
p := PStrItem(FList[Index]);
if p <> nil
then p^.FObject := AObject
else if AObject <> nil
then Error;
Changed
end;
Here the developer simply raises an exception since no non-empty string
item has been assigned yet.
procedure TStringSparseList.PutObject(Index: Integer; AObject: TObject);
var
p: PStrItem;
begin
p := PStrItem(FList[Index]);
if p <> nil then
p^.FObject := AObject
else
if AObject <> nil then
{$IFDEF FixEmptyCellBug}
FList[Index] := NewStrItem('', AObject);
{$ELSE}
Error;
{$ENDIF}
Changed;
end;
Bug #406; last modified: 13-Aug-98| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Exists | Exists | Exists | Exists | Exists | Exists | Exists | Unknown |
procedure TForm1.FormCreate(Sender: TObject);
const
Gap = 100;
procedure SetupStringGrid(SG: TStringGrid; TheTop: Integer);
begin
with SG do
begin
Left := 0;
Width := Self.ClientWidth;
Top := TheTop;
Height := (Self.ClientHeight - Gap) div 2;
TabStops[0] := False { this causes the TabStops array to be built }
end;
end;
begin
{ set the form to make use of the full screen width and height }
Left := 0;
Width := Screen.Width;
Top := 0;
Height := Screen.Height;
{ set the stringgrids to be able to use the full width available }
SetupStringGrid(StringGrid1, Gap); { allow gap at top }
SetupStringGrid(StringGrid2, StringGrid1.Top + StringGrid1.Height);
{ StringGrid2 only: causes ColWidths array to be built }
StringGrid2.ColWidths[0] := 50
end;
procedure TForm1.FormClick(Sender: TObject);
begin
with StringGrid1 do ColCount := ColCount + 1;
with StringGrid2 do ColCount := ColCount + 1;
FormShow(Sender)
end;
procedure TForm1.FormShow(Sender: TObject);
var
I: Integer;
begin
with StringGrid1 do for I := 0 to ColCount - 1 do
Cells[I, 0] := Format('%d', [Ord(TabStops[I])]);
with StringGrid2 do for I := 0 to ColCount - 1 do
Cells[I, 0] := Format('%d', [Ord(TabStops[I])]);
end;
Cause:
In the VCL unit Grids.pas, DoChange procedure of TCustomGrid.ChangeSize
method, a test is made on FColWidths not being nil before calling UpdateExtents
for the array that is pointed to by FTabStops.
if FColWidths <> nil then
begin
UpdateExtents(FColWidths, ColCount, DefaultColWidth);
UpdateExtents(FTabStops, ColCount, Integer(True));
end;
with
if FColWidths <> nil then
UpdateExtents(FColWidths, ColCount, DefaultColWidth);
if FTabStops <> nil then
UpdateExtents(FTabStops, ColCount, Integer(True));
A workaround would be to
explicitly set ColWidth[0] so that the array pointed to by FColWidths exists;
one must also ensure that this is done after any setting of DefaultColumnWidth
as this will clear out the ColWidths array.
Bug #407; last modified: 24-Jul-98| 1.02 | 2.01 | 3.0 | 3.01 | 3.02 | 4.0 | 4.01 | 4.02 |
| Exists | Exists | Exists | Exists | Exists | Fixed | Fixed | Fixed |
procedure TForm1.FormCreate(Sender: TObject);
begin
{ set up the form to use the full screen width and height }
Left := 0;
Top := 0;
Width := Screen.Width;
Height := Screen.Height;
with StringGrid1 do
begin
{ position the StringGrid }
Left := 0;
Top := 100; { leave somewhere to click to activate OnFormClick event }
Width := Self.ClientWidth;
Height := Self.ClientHeight - Top;
{ set to demonstrate Colwidths, RowHeights, and TabStops bugs }
ColWidths[ColCount - 1] := 2 * DefaultColWidth;
RowHeights[RowCount - 1] := 2 * DefaultRowHeight;
TabStops[ColCount - 1] := False
end
end;
procedure TForm1.FormClick(Sender: TObject);
begin
with StringGrid1 do
begin
ColCount := ColCount + 1; { incorrectly changes ColWidths & TabStops }
RowCount := RowCount + 1 { incorrectly changes RowHeights }
end;
FormShow(Sender)
end;
procedure TForm1.FormShow(Sender: TObject);
var
I: Integer;
begin
{ show TabStops value for each column }
with StringGrid1 do for I := 0 to ColCount - 1 do
Cells[I, 0] := Format('%d', [Ord(TabStops[I])]);
end;
Windows 3.1/Windows for WorkGroups 3.11 - both with Win32s
I := Index;should be
I := Index + 1;to take account of the Extents array being offset by 1 to allow for the zeroth element being used to store the size.
A workaround would be:
Before increasing the number of rows (columns), save the height (width, tab
stop) of the last row (column) and, afterwards, if that height (width, tabstop)
differs from the default, set the height (width, tabstop) to the saved
value(s).