In Windows 7 X64, statusBar does not show text for the panels starting from the 11th correctly
Summarization:
(1) This is very likely to be a bug. However, I cannot say for sure whether it is more related to 64bit OS, or VCL, or MFC wrapper. Please check the answers and comments below from Delphi experts. (2) Workaround for me: a. The situation is that I havesix
key-value pairs
to show in the status bar. The values will be changed in run time.
b. It seems I cannot set text
for more than 10
panels.
c. In this respect, I will use six
calls of set text
for the values, and use two
calls for set text
for the last two keys. Thus, I don't have to exceed the 10
limit.
d. In order to make set text
work, I need provide different text that it already has.
e. Sample code can thus be described as:
// 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'
==================================================================
In my Windows 7 X64, the statusBar does not show text for the panels starting from the 11th correctly.
(1)
New an empty VCL application project without
saving it, if I set the Text for the 11th status panel at design time, the text will not be shown at all at run time. (See the attached pictures.)
(2) If I save it and reopen it, the text will also not be shown in design time.
(3)
If I set the Text at run time, the text will be shown only when the new text is different from the old one. Say the Text for the 11th panel is set to 'try'
at design time:
Self.stat1.Panels[10].Text := 'try'; // 'try' is not shown
self.stat1.Panels[10].Text := 'try_'; // 'try_' is shown
(4) This behavior only happens on my Windows 7 X64, but not on my Windows XP.
(5) I would think the same behavior allpies to all Delphi versions.
(6) It seems the behavior is more related to Windows version than to Delphi. I mean, the same sample application will shown the above behavior on Windows 7 but not on Windows XP.
(7) A sample dfm file is dumped as below:
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) Sample pictures:
Could some one help to comment on the possible reason? Any suggestion is appreciated!
It doesn't show beyond the 10th in design-time:
But at run-time is looks like this:
All properties set in the .dfm file.
As to why it is like this I've no idea. But since it behaves fine at run-time I don't think will cause any serious problems.
As requested by Warren, here's my .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
I wanted to say "It works for me, on windows 7, 64 bit, with delphi XE." In fact, it did work, the first time I dropped it onto the form, it all worked great. And I thought, you're doing something wrong. Then it hit me, after the second time, I reopened the form.
Now it always fails.
I think you should start with a new blank project like I did, and do just the one thing. That takes all the other things you did out of the code, that are messing you up.
I call this the "file new" test. 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.
Here is my initial try, it worked:
Second time I reopened the form, it failed at designtime, the same way it failed for David H.
Dump the widths of the panels to a memo like this:
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;
The VCL Status Bar wraps an MS Common control, which either has a bug, or the VCL is wrapping it wrong. Since this doesn't happen on XP, I think you've found a new MS Common Controls bug in Win7.
I found a similar problem for ownerdraw panels. DrawPanel event is not called on panels with an index > 6 in Win 7/64bit. I found that windows does not send WM_DRAWITEM message to these panels. Solution that worked in my case is to set the WS_EX_COMPOSITED style to statusbar.
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;
精彩评论