TToolbar会在一段时间后停止显示按钮标题

时间:2017-06-19 14:08:42

标签: windows delphi toolbar delphi-2010 vcl

任何想法为什么带有TToolButtons的TToolbar会在一段时间后停止显示按钮标题?在整个应用程序中自动创建的表单上的所有工具栏都会发生这种情况。即使出现此问题,动态创建的表单上的工具栏也能正常工作。

我只在一台Windows 7笔记本上看到过这种情况。发生这种情况时不会出现错误,我无法在命令中重现问题。唯一的解决方案是重新启动应用程序。

TToolbar.ShowCaptions始终为True且永不更改。这也可以在下面的图像中看到,因为当ShowCaptions为False时,图标是垂直对齐的。

Toolbar with missing captions

之前在Windows 8 PC上发生过类似的问题。但是这次字幕被其他文字取代了。

Toolbar with weird captions

编辑:

我能够通过调用TImageList.Change在5-10k次之间重现该问题。我只有Delphi 2010,所以我不能说这是Delphi还是Windows问题。

单位:

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.

形式:

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

2 个答案:

答案 0 :(得分:4)

鉴于问题中的再现,我认为问题是VCL工具栏代码会删除所有按钮,然后在修改图像列表时重新创建它们。

我正在查看Delphi 6代码,因为我没有立即提供Delphi 2010,但代码没有实质性改变。相关代码位于TToolBar.CreateButtons。接近这个方法的底部我们有:

for I := 0 to InternalButtonCount - 1 do Perform(TB_DELETEBUTTON, 0, 0);
UpdateButtons;

循环删除所有按钮,然后UpdateButtons将其添加回来。看起来潜在的控制并不喜欢被这样对待。我们可以改为删除任何多余的按钮,而不是删除所有按钮。

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

在您的示例代码和实际应用程序中,您不会更改按钮的数量,因此此版本甚至不会进入循环。

通过此更改,您的程序可以正常运行。

您可以通过执行以下操作在应用程序中应用此更改:

  1. 从安装目录的源文件夹中获取ComCtrls.pas的副本,并将其保存在项目树中。
  2. 将复制的ComCtrls单元添加到项目中。
  3. 进行上述修改。

答案 1 :(得分:4)

它似乎是Delphi 2010中的一个错误,在function TToolBar.UpdateItem()末尾的ComCtrls单元中。该功能从第21476行开始。

在Delphi XE4中(可能已经修复过,我无法检查)以下注释和代码(Delphi 2010中缺少的)在函数末尾出现

  // 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;

将Delphi 2010 ComCtrls.pas的副本复制到projects文件夹并添加上述代码,解决了测试所带来的问题。