В Windows 7 X64 статусбар некорректно отображает текст для панелей, начиная с 11-й

Обобщение:
(1) Скорее всего, это ошибка. Однако я не могу точно сказать, связано ли это больше с 64-битной ОС, или с VCL, или с MFC-оболочкой. Ознакомьтесь с приведенными ниже ответами и комментариями экспертов Delphi.
(2) Обходной путь для меня:
a. Ситуация такова, что у меня есть six ключ-значение pairs для отображения в строке состояния. Значения будут изменены во время выполнения.
б. Кажется, я не могу set text использовать более 10 панелей.
c. В этом отношении я буду использовать six вызовы set text для значений и two вызовы set text для последних двух ключей. Таким образом, мне не нужно превышать лимит 10.
d. Чтобы set text заработало, мне нужно предоставить другой текст, который уже есть.
e. Таким образом, пример кода можно описать как:

// Designtime
stat1.Panels[0].Text := 'Key1'
stat1.Panels[2].Text := 'Key2'
stat1.Panels[4].Text := 'Key3'
stat1.Panels[6].Text := 'Key4'
stat1.Panels[8].Text := 'Key5__'
stat1.Panels[10].Text := 'Key6__'


// runtime
stat1.Panels[1].Text := 'Value1'
stat1.Panels[3].Text := 'Value2'
stat1.Panels[5].Text := 'Value3'
stat1.Panels[6].Text := 'Value4'
stat1.Panels[9].Text := 'Value5'
stat1.Panels[11].Text := 'Value6'    

stat1.Panels[8].Text := 'Key5'
stat1.Panels[10].Text := 'Key6'

==================================================================

В моей Windows 7 X64 статусбар не показывает правильно текст для панелей, начиная с 11-го числа.

(1) Создайте пустой проект приложения VCL without, сохранив его, если я установлю текст для 11-й панели состояния во время разработки, текст вообще не будет отображаться во время выполнения. (Смотрите прикрепленные картинки.)

(2) Если я сохраню его и снова открою, текст также не будет отображаться во время разработки.

(3) Если я установлю текст во время выполнения, текст будет отображаться только тогда, когда новый текст отличается от старого. Скажем, текст для 11-й панели установлен на 'try' во время разработки:

Self.stat1.Panels[10].Text := 'try';         // 'try' is not shown   
self.stat1.Panels[10].Text := 'try_';        // 'try_' is shown

(4) Такое поведение происходит только в моей Windows 7 X64, но не в моей Windows XP.

(5) Я думаю, что такое же поведение характерно для всех версий Delphi.

(6) Похоже, что поведение больше связано с версией Windows, чем с Delphi. Я имею в виду, что одно и то же приложение-образец будет демонстрировать описанное выше поведение в Windows 7, но не в Windows XP.

(7) Образец файла dfm выгружается, как показано ниже:

    object Form3: TForm3
      Left = 0
      Top = 0
      Caption = 'Form3'
      ClientHeight = 202
      ClientWidth = 731
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = []
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
      object stat1: TStatusBar
        Left = 0
        Top = 183
        Width = 731
        Height = 19
        Panels = <
          item
            Text = '0'
            Width = 50
          end
          item
            Text = '1'
            Width = 50
          end
          item
            Text = '2'
            Width = 50
          end
          item
            Text = '3'
            Width = 50
          end
          item
            Text = '4'
            Width = 50
          end
          item
            Text = '5'
            Width = 50
          end
          item
            Text = '6'
            Width = 50
          end
          item
            Text = '7'
            Width = 50
          end
          item
            Text = '8'
            Width = 50
          end
          item
            Text = '9'
            Width = 50
          end
          item
            Text = '10'
            Width = 50
          end
          item
            Text = '11'
            Width = 50
          end>
        ExplicitLeft = 248
        ExplicitTop = 152
        ExplicitWidth = 0
      end
      object btn1: TButton
        Left = 152
        Top = 40
        Width = 433
        Height = 89
        Caption = 'btn1'
        TabOrder = 1
        OnClick = btn1Click
      end
    end

(8) Примеры изображений:
Designtime
rumtime

Может ли кто-нибудь помочь прокомментировать возможную причину? Любое предложение приветствуется!


person SOUser    schedule 16.03.2011    source источник
comment
@Warren: Большое спасибо за ваше время! Я отредактировал свой вопрос, чтобы быть более ясным. Не могли бы вы взглянуть?   -  person SOUser    schedule 16.03.2011
comment
У вас установлен Service Pack 1?   -  person Warren P    schedule 16.03.2011
comment
@Warren: я еще не установил SP1.   -  person SOUser    schedule 16.03.2011
comment
@Xichen Li, какая версия Delphi?   -  person Jeroen Wiert Pluimers    schedule 16.03.2011
comment
@Jeroen: Как пытались Уоррен и Дэвид, я думаю, это применимо ко всем версиям.   -  person SOUser    schedule 16.03.2011
comment
Я использую Win7 x64 SP1 FWIW   -  person David Heffernan    schedule 16.03.2011
comment
С какой стати вам нужно столько панелей в строке состояния?   -  person Leonardo Herrera    schedule 16.03.2011
comment
@Xichen, возможно, это исправлено или введено в какой-то комбинации Delphi / Windows.   -  person Jeroen Wiert Pluimers    schedule 16.03.2011
comment
Я попытался воспроизвести с помощью оболочки MFC в Visual C++, но мой MFC-fu был слишком слабым.   -  person Warren P    schedule 16.03.2011
comment
Эта проблема не проявляется, когда вы просто используете оболочки MFC. Так что в исходниках VCL может быть обходной путь.   -  person Warren P    schedule 16.03.2011
comment
@Leonardo: Спасибо за ваше время. У меня есть шесть пар key_value для отображения.   -  person SOUser    schedule 17.03.2011


Ответы (3)


Я хотел сказать: «У меня это работает, на Windows 7, 64-разрядная версия, с delphi XE». На самом деле, это сработало, первый раз, когда я бросил его на форму, все отлично сработало. И я подумал, что ты делаешь что-то не так. Потом меня осенило, после второго раза я снова открыл форму.

Теперь всегда не получается.

Я думаю, вам следует начать с нового пустого проекта, как это сделал я, и сделать только одну вещь. Это уберет все остальные вещи, которые вы сделали из кода, которые вас сбивают с толку.

Я называю это тестом «новый файл». Если вы не можете воспроизвести что-то в новом приложении, содержащем только код или элементы управления, в которых вы не уверены, не утруждайте себя просьбой сделать это за вас.

введите здесь описание изображения

Вот моя первая попытка, она сработала:

Во второй раз, когда я снова открыл форму, она потерпела неудачу во время разработки, так же, как и для Дэвида Х.

Сбросьте ширину панелей в памятку вроде этой:

procedure TForm3.DumpWidths;
var
 t:Integer;
begin
 for t := 0 to StatusBar1.Panels.Count-1 do begin
   Memo1.Lines.Add( '#'+IntToStr(t)+
   ' width '+
   IntToStr(StatusBar1.Panels.Items[t].Width));
 end;

end;

Строка состояния VCL оборачивает элемент управления MS Common, в котором либо есть ошибка, либо VCL неправильно оборачивает его. Поскольку в XP этого не происходит, я думаю, вы обнаружили новую ошибку MS Common Controls в Win7.

person Warren P    schedule 16.03.2011
comment
@Warren: я использую новый пустой проект :) - person SOUser; 16.03.2011
comment
@Warren: If you can't reproduce something in a new application, that contains only the code or controls you are unsure about, don't bother asking anybody else to do it for you. Я всегда это помню. - person SOUser; 16.03.2011
comment
@Warren: Вы имеете в виду, что на вашей машине текст отображается только во время выполнения? Странно, но на моей машине текст действительно отображается только во время разработки. :D - person SOUser; 16.03.2011
comment
Это также воспроизводится в Win7/64bit, на Delphi 7 VCL. Я серьезно сомневаюсь, что это ошибка VCL. Это должно быть регрессией в библиотеке общих элементов управления MS. С таким дерьмом, плавающим в библиотеке, я бы вырвал это и использовал строку состояния, не относящуюся к COMMON-элементам управления. - person Warren P; 16.03.2011
comment
@Warren: Большое спасибо за ваше предложение! Не могли бы вы порекомендовать один non-COMMON-controls status bar? - person SOUser; 16.03.2011
comment
Я использую Toolbar2000+spTBX, другие используют Developer Express или TMS. - person Warren P; 16.03.2011
comment
В вашем случае (12+ фрагментов текста) я бы просто использовал TPaintBox. :-) - person Warren P; 16.03.2011
comment
@Warren: Большое спасибо, что поделились своим опытом! Кроме того, спасибо за ваше предложение. - person SOUser; 17.03.2011

Во время разработки он не отображается дальше 10-го:

введите здесь описание изображения

Но во время выполнения это выглядит так:

введите здесь описание изображения

Все свойства задаются в файле .dfm.

Что касается того, почему это так, я понятия не имею. Но поскольку он ведет себя нормально во время выполнения, я не думаю, что это вызовет какие-либо серьезные проблемы.


По просьбе Уоррена, вот мой .dfm:

object Form3: TForm3
  Left = 0
  Top = 0
  Caption = 'Form3'
  ClientHeight = 105
  ClientWidth = 635
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object StatusBar1: TStatusBar
    Left = 0
    Top = 86
    Width = 635
    Height = 19
    Panels = <
      item
        Text = '1'
        Width = 50
      end
      item
        Text = '2'
        Width = 50
      end
      item
        Text = '3'
        Width = 50
      end
      item
        Text = '4'
        Width = 50
      end
      item
        Text = '5'
        Width = 50
      end
      item
        Text = '6'
        Width = 50
      end
      item
        Text = '7'
        Width = 50
      end
      item
        Text = '8'
        Width = 50
      end
      item
        Text = '9'
        Width = 50
      end
      item
        Text = '10'
        Width = 50
      end
      item
        Text = '11'
        Width = 50
      end
      item
        Text = '12'
        Width = 50
      end
      item
        Text = '13'
        Width = 50
      end>
  end
end
person David Heffernan    schedule 16.03.2011
comment
Можете ли вы сбросить свой DFM в виде текста и добавить? - person Warren P; 16.03.2011
comment
@David: Большое спасибо за ваше время! Боже мой, в вашей машине все наоборот! На моей машине текст не отображается во время выполнения. :D - person SOUser; 16.03.2011
comment
Я думаю, что если мы воспроизведем его втроем, разумный ответ будет таков: это ошибка в библиотеке MS Common Controls. Интересно, почему он начинает лажать, только после моей второй попытки - person Warren P; 16.03.2011
comment
@David: В вашей системе нет проблем. Однако Xichen видит такое же поведение во время выполнения. Вызывает у меня плохое предчувствие. - person Warren P; 16.03.2011
comment
@Warren Мне никогда не приходило в голову, что поведение может отличаться в разных системах. Странный! - person David Heffernan; 16.03.2011
comment
Что еще более странно, так это то, что приложения winforms MS Visual Studio 2008 НЕ ПОЗВОЛЯЮТ ДОБАВИТЬ более 10 панелей в строку состояния. Возможно, у них есть записка, которую мы не получили? О, подожди. Они позволяют вам. Вам просто нужно изменить текст, чтобы сделать его меньше. - person Warren P; 16.03.2011
comment
@David, @Warrent: после того, как я сохраню проект и снова открою его, текст после 10-й панели исчезнет как во время разработки, так и во время выполнения. (Я отредактировал свой вопрос, чтобы отразить это) - person SOUser; 16.03.2011
comment
Это проблема в 64-битной ОС. Не работает на WinXP x64 и на Win7 x64. Скомпилировано с помощью Delphi 2006 и 2010. - person DiGi; 16.03.2011
comment
Нет, извините :( Даже кастомная краска сломана. - person DiGi; 16.03.2011
comment
Воспроизведено здесь, Win 7 64 бит, не отображается в дизайнере, но нормально отображается во время выполнения. Изменение значения BiDiMode приводит к (временной) корректировке отображения в дизайнере, возможно, стоит попробовать это во время выполнения? Не могу проверить здесь, так как он работает нормально во время выполнения. - person HMcG; 16.03.2011
comment
Я помню, что изменения версии MS Common Controls между Win 95, 98 и 2000 доставляли мне много лет веселья. С момента выпуска XP все в MS Common Controls было стабильным, пока я не увидел это. - person Warren P; 16.03.2011
comment
@DiGi: Спасибо за ваше время! @HMcG: Большое спасибо за ваше предложение! @Warren: Большое спасибо, что поделились своим опытом! - person SOUser; 17.03.2011

Я обнаружил аналогичную проблему для панелей ownerdraw. Событие DrawPanel не вызывается на панелях с индексом > 6 в Win 7/64bit. Я обнаружил, что Windows не отправляет сообщение WM_DRAWITEM на эти панели. Решение, которое сработало в моем случае, — установить стиль WS_EX_COMPOSITED в строку состояния.

procedure TForm1.FormCreate(Sender: TObject);
var
  SBHandle: THandle;
begin
  ...
  if CheckWin32Version(5, 1) then
  begin
    SBHandle:= StatusBar.Handle;
    SetWindowLong(SBHandle, GWL_EXSTYLE, GetWindowLong(SBHandle, GWL_EXSTYLE) or WS_EX_COMPOSITED);
  end;
  ...
end;
person Eugene    schedule 17.03.2011
comment
Очень хорошая информация. Кто-нибудь еще читает, кто знает о каких-либо ошибках в других MS Common Controls? - person Warren P; 17.03.2011