TToolbar stops displaying button headers after a while

Any idea why TToolbar with TToolButtons will stop displaying button headers after a while? This happens with all toolbars in automatically generated forms throughout the application. Toolbars on dynamically created forms work fine even after this problem.

I saw this on only one Windows 7 laptop. When this happens, no errors occur, and I cannot reproduce the problem by command. The only solution is to restart the application.

TToolbar.ShowCaptions is always True and never changed. This is also visible in the image below because the icons are vertically aligned when ShowCaptions are False.

Toolbar with missing headers

A similar problem arose on a Windows 8 PC. However, this time the signatures were replaced with different text.

Weird Header Toolbar

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 problem.

Section:

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. 

the 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 
+5
source share
2 answers

This seems to be a bug in Delphi 2010, in the ComCtrls module at the end of function TToolBar.UpdateItem() . The function starts at line 21476.

In Delphi XE4 (maybe this has been fixed earlier, I can’t check) the following comment and code (which is missing in Delphi 2010) appears at the end of the function :

  // If more than 2^16 strings are TB_ADDSTRING-ed to the tool bar 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; 

By taking a copy of Delphi 2010 ComCtrls.pas into the projects folder and adding the code above, cure the problem that your test creates.

+4
source

Given the reproduction in the question, I think the problem is that the VCL toolbar code removes all the buttons and then recreates them whenever the image list changes.

I am watching Delphi 6 code because I do not have Delphi 2010 right away, but the code has not changed significantly. The corresponding code is in TToolBar.CreateButtons . To 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 basic control does not evaluate how to handle this. Instead of deleting all the buttons, we can simply remove the extra buttons.

 var Count: Integer; .... Count := InternalButtonCount; while Count>FButtons.Count do begin Perform(TB_DELETEBUTTON, Count-1, 0); dec(Count); end; UpdateButtons; 

In your code example and in a real application, you do not change the number of buttons, so this version is not even included in the loop.

With this change, your program runs correctly.

You can apply this change in your application by following these steps:

  • Take a copy of ComCtrls.pas from the source folder of your installation directory and save it in your project tree.
  • Add this copied ComCtrls block to your project.
  • Make the changes described above.
+4
source

Source: https://habr.com/ru/post/1268988/


All Articles