2017-06-19 196 views
5

任何想法TToolButtons的TToolbar會在一段時間後停止顯示按鈕標題?這發生在整個應用程序中自動創建的表單上的所有工具欄。即使出現這個問題,動態創建的表單上的工具欄也可以正常工作TToolbar在一段時間後停止顯示按鈕標題

我只看到這種情況發生在一個Windows 7的筆記本電腦。發生這種情況時不會產生錯誤,並且我無法在命令中重現問題。唯一的解決方案是重新啓動應用程序。

TToolbar.ShowCaptions始終是真實的,從來沒有改變。這在下面的圖片中也是可見的,因爲當ShowCaptions爲False時圖標是垂直對齊的。

Toolbar with missing captions

類似的問題發生之前在Windows 8 PC上。但是這次的標題被替換爲其他文字。

Toolbar with weird captions

編輯:

我能夠5-10K倍之間調用TImageList.Change重現該問題。我只有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 
+1

聞起來像某種資源泄漏。嘗試監視GDI對象計數。 –

+0

最有可能的是,標題在運行時改變。你可以在一個工具按鈕的'FCaption'屬性上定義一個斷點,或者在'SetCaption'方法中定義一個斷點。 –

+0

@RenéHoffmann字幕永遠不會改變。即使他們是,這應該不會影響整個應用程序。 – mwore

回答

4

它似乎是德爾福2010年的錯誤,在ComCtrls單元末尾function TToolBar.UpdateItem()。該函數在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; 

以德爾福的副本2010 ComCtrls.pas到項目文件夾,並添加上面的代碼,治癒您的測試產生的問題。

+1

在我的答案中展示的解決方案的好處之一是,它避免了首先氾濫的字符串池。通過這裏描述的解決方案(很好地發現了btw),您可以看到進程專用字節在「ToolButton1Click」循環執行時穩步增加。我的解決方案沒有發生。這不是一個重要的數字,但我認爲這樣做是非常有意義的,以避免無故毀壞和重新創建這些按鈕。此外,如果可能的話,避免窗口娛樂必須是一個好策略。我個人會應用這兩個答案的變化。 –

+0

答案的時間應該不重要。接受你爲什麼覺得是最好的答案。 –

4

鑑於問題的再現,我覺得現在的問題是,VCL工具欄的代碼刪除所有的按鈕,然後重新創建這些每當圖像列表被修改。

我期待在Delphi 6的代碼,因爲我沒有德爾福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. 進行上述修改。
+0

經過多次測試後,此解決方案會導致其他問題。在運行時更改按鈕標題會隱藏所有按鈕的標題。 – mwore

+0

不在我的測試中,它不.......我不知道你是否可以給我足夠的細節來重現 –

+0

使用測試應用程序從問題和修補ComCtrls。用ToolButton1.Caption替換ToolButton1Click:='Button''。點擊我所獲得的圖標,任何按鈕上都沒有標題。 – mwore