Any idea why TToolbar with TToolButtons would stop displaying button captions after a while? This happens to all toolbars on auto-created forms across the whole application. Toolbars on dynamically created forms work fine even after this problem.
I have only seen this happen on one Windows 7 notebook. No errors are raised when this happens and I can't reproduce the problem on command. The only solution is restarting the application.
TToolbar.ShowCaptions is always True and never changed. This is also visible on the image below because icons are vertically aligned when ShowCaptions is False.
A similar problem happened before on a Windows 8 PC. However this time captions were replaced with other text.
EDIT:
I was able to reproduce the problem by calling TImageList.Change between 5-10k times. I only have Delphi 2010, so I can't say if this is a Delphi or Windows issue.
Unit:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ImgList, ComCtrls, ToolWin, StdCtrls, Gauges;
type
TImageListHelper = class helper for TImageList
public
procedure DoChange;
end;
TForm1 = class(TForm)
ToolBar1: TToolBar;
ToolButton1: TToolButton;
ToolButton2: TToolButton;
ToolButton3: TToolButton;
ToolButton4: TToolButton;
ToolButton5: TToolButton;
ToolButton6: TToolButton;
ToolButton7: TToolButton;
ToolButton8: TToolButton;
ToolButton9: TToolButton;
ToolButton10: TToolButton;
ImageList1: TImageList;
ProgressBar1: TProgressBar;
procedure ToolButton1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ToolButton1Click(Sender: TObject);
begin
repeat
ImageList1.DoChange;
ProgressBar1.StepIt;
Self.Update;
until ProgressBar1.Position >= ProgressBar1.Max;
end;
procedure TImageListHelper.DoChange;
begin
Self.Change;
end;
end.
Form:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 66
ClientWidth = 711
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
PixelsPerInch = 96
TextHeight = 13
object ToolBar1: TToolBar
Left = 0
Top = 0
Width = 711
Height = 41
ButtonHeight = 36
ButtonWidth = 71
Caption = 'ToolBar1'
Images = ImageList1
ShowCaptions = True
TabOrder = 0
ExplicitWidth = 885
object ToolButton1: TToolButton
Left = 0
Top = 0
Caption = 'ToolButton1'
ImageIndex = 0
OnClick = ToolButton1Click
end
object ToolButton2: TToolButton
Left = 71
Top = 0
Caption = 'ToolButton2'
ImageIndex = 0
end
object ToolButton3: TToolButton
Left = 142
Top = 0
Caption = 'ToolButton3'
ImageIndex = 0
end
object ToolButton4: TToolButton
Left = 213
Top = 0
Caption = 'ToolButton4'
ImageIndex = 0
end
object ToolButton5: TToolButton
Left = 284
Top = 0
Caption = 'ToolButton5'
ImageIndex = 0
end
object ToolButton6: TToolButton
Left = 355
Top = 0
Caption = 'ToolButton6'
ImageIndex = 0
end
object ToolButton7: TToolButton
Left = 426
Top = 0
Caption = 'ToolButton7'
ImageIndex = 0
end
object ToolButton8: TToolButton
Left = 497
Top = 0
Caption = 'ToolButton8'
ImageIndex = 0
end
object ToolButton9: TToolButton
Left = 568
Top = 0
Caption = 'ToolButton9'
ImageIndex = 0
end
object ToolButton10: TToolButton
Left = 639
Top = 0
Caption = 'ToolButton10'
ImageIndex = 0
end
end
object ProgressBar1: TProgressBar
Left = 0
Top = 49
Width = 711
Height = 17
Align = alBottom
Max = 10000
Step = 1
TabOrder = 1
ExplicitTop = 48
end
object ImageList1: TImageList
Left = 8
Top = 16
Bitmap = {
494C010101000500040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
0000000000003600000028000000400000001000000001002000000000000010
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF000000FF000000000000000000000000000000000000000000000000000000
FF000000FF000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF000000FF000000000000000000000000000000000000000000000000000000
FF000000FF000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000FF000000FF0000000000000000000000FF000000FF000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000FF000000FF0000000000000000000000FF000000FF000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000FF000000FF0000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000FF000000FF0000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000FF000000FF0000000000000000000000FF000000FF000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000FF000000FF0000000000000000000000FF000000FF000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF000000FF000000000000000000000000000000000000000000000000000000
FF000000FF000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
FF000000FF000000000000000000000000000000000000000000000000000000
FF000000FF000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000424D3E000000000000003E000000
2800000040000000100000000100010000000000800000000000000000000000
000000000000000000000000FFFFFF00FFFF000000000000FFFF000000000000
FFFF000000000000E7E7000000000000E7E7000000000000F99F000000000000
F99F000000000000FE7F000000000000FE7F000000000000F99F000000000000
F99F000000000000E7E7000000000000E7E7000000000000FFFF000000000000
FFFF000000000000FFFF00000000000000000000000000000000000000000000
000000000000}
end
end
It appears to be a bug in Delphi 2010, in ComCtrls unit at the end of function TToolBar.UpdateItem()
. The function starts at line 21476.
In Delphi XE4 (it might have been fixed earlier, I can't check) the following comment and code (which is missing from Delphi 2010) appears at the end of the function:
// If more than 2^16 strings are TB_ADDSTRING-ed to the tool bar's string
// pool, the Windows API assumes iString is a pointer to a null terminated
// string, not an index in the string pool. Therefore we have to recreate
// the toolbar to reset the string pool so the strings display propperly.
if Button.iString >= 65536 then
RecreateWnd;
Taking a copy of Delphi 2010 ComCtrls.pas to the projects folder and adding the above code, cured the problem that your test creates.
Given the reproduction in the question, I think that the problem is that the VCL toolbar code removes all the buttons and then recreates them whenever the image list is modified.
I'm looking at Delphi 6 code because I don't have Delphi 2010 immediately to hand, but the code has not materially changed. The pertinent code is in TToolBar.CreateButtons
. Towards the bottom of this method we have:
for I := 0 to InternalButtonCount - 1 do Perform(TB_DELETEBUTTON, 0, 0);
UpdateButtons;
The loop removes all the buttons, and then UpdateButtons
adds them back. It seems that the underlying control does not appreciate being treated this way. Instead of removing all the buttons we can instead just remove any excess buttons.
var
Count: Integer;
....
Count := InternalButtonCount;
while Count>FButtons.Count do
begin
Perform(TB_DELETEBUTTON, Count-1, 0);
dec(Count);
end;
UpdateButtons;
In your example code, and in the real application, you aren't changing the number of buttons so this version does not even enter the loop.
With this change, your program runs correctly.
You can apply this change in your application by doing the following:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With