TStatusPanel = class(TCollectionItem) ... property Text: string read FText write SetText; ... end;Text属性是string类型应该是能存4G的长度的.下面是测试代码: var arr: array[0..299] of Char; I: Integer; J: Char; begin J := '0'; for I := 0 to 299 do begin arr[I] := J; J := Char(Ord(J) + 1); if j = ':' then j := '0'; //从0到9循环 end; form1.StatusBar1.Panels.Items[0].Text := arr; ShowMessage(form1.StatusBar1.Panels.Items[0].Text); end;我看到的效果: showmessage显示出来的,是足够300个字符的.说明:form1.StatusBar1.Panels.Items[0].Text这个值没问题. 但是,状态栏确实没显示完,可能是vcl内部代码限制了范围.你研究下paint之类的过程代码看看.
不会吧记得 string默认不是 shortstring 啊
可是paint方法都不在statusbar控件里出现 无奈中...
看来statusbar的Tpanle有个FText 设置是string类型啊 奇怪了
procedure WMPaint(var Message: TWMPaint); message WM_PAINT; 是TCustomStatusBar的这个过程,响应wm_paint消息的.他里面调用了UpdatePanels(False, True); 第一个参数是false,所以,UpdatePanels里面,最终有作用的是靠近下面的: for I := 0 to Count - 1 do UpdatePanel(I, UpdateText);继续跟踪UpdatePanel: S := Text; //这里将Panels[Index]的text属性赋给了string变量S if UseRightToLeftAlignment then DoRightToLeftAlignment(S, Alignment, UseRightToLeftAlignment) else case Alignment of taCenter: Insert(#9, S, 1); taRightJustify: Insert(#9#9, S, 1); end; //给当前状态栏窗口发个SB_SETTEXT消息,设置文字,S的地址作为消息的LParam参数传入 SendMessage(Handle, SB_SETTEXT, Index or Flags, Integer(PChar(S))); 但是,TCustomStatusBar类中没有看到SB_SETTEXT的消息响应函数.....线索到这里,断了.TCustomStatusBar的CreateParams过程: InitCommonControl(ICC_BAR_CLASSES); //常量定义:ICC_BAR_CLASSES = $00000004; // toolbar, statusbar, trackbar, tooltips inherited CreateParams(Params); CreateSubClass(Params, STATUSCLASSNAME); //STATUSCLASSNAME = 'msctls_statusbar32';也就是说,这个状态栏窗口在创建的时候,delphi给它的style加了一些东西, windows系统会根据这些东西去产生特殊的窗口.估计里面就包括了:SB_SETTEXT的消息响应过程. 不知道怎么跟了....,也许只能查查MSDN.
procedure TCustomStatusBar.UpdatePanel(Index: Integer; Repaint: Boolean); var Flags: Integer; S: string; PanelRect: TRect; begin if HandleAllocated then with Panels[Index] do begin if not Repaint then begin FUpdateNeeded := True; SendMessage(Handle, SB_GETRECT, Index, Integer(@PanelRect)); InvalidateRect(Handle, @PanelRect, True); Exit; end else if not FUpdateNeeded then Exit; FUpdateNeeded := False; Flags := 0; case Bevel of pbNone: Flags := SBT_NOBORDERS; pbRaised: Flags := SBT_POPOUT; end; if UseRightToLeftReading then Flags := Flags or SBT_RTLREADING; if Style = psOwnerDraw then Flags := Flags or SBT_OWNERDRAW; S := Text; if UseRightToLeftAlignment then DoRightToLeftAlignment(S, Alignment, UseRightToLeftAlignment) else case Alignment of taCenter: Insert(#9, S, 1); taRightJustify: Insert(#9#9, S, 1); end; SendMessage(Handle, SB_SETTEXT, Index or Flags, Integer(PChar(S))); end; end;procedure TCustomStatusBar.UpdatePanels(UpdateRects, UpdateText: Boolean); const MaxPanelCount = 128; var I, Count, PanelPos: Integer; PanelEdges: array[0..MaxPanelCount - 1] of Integer; begin if HandleAllocated then begin Count := Panels.Count; if UpdateRects then begin if Count > MaxPanelCount then Count := MaxPanelCount; if Count = 0 then begin PanelEdges[0] := -1; SendMessage(Handle, SB_SETPARTS, 1, Integer(@PanelEdges)); SendMessage(Handle, SB_SETTEXT, 0, Integer(PChar(''))); end else begin PanelPos := 0; for I := 0 to Count - 2 do begin Inc(PanelPos, Panels[I].Width); PanelEdges[I] := PanelPos; end; PanelEdges[Count - 1] := -1; SendMessage(Handle, SB_SETPARTS, Count, Integer(@PanelEdges)); end; end; for I := 0 to Count - 1 do UpdatePanel(I, UpdateText); end; end;
The SB_SETTEXT message sets the text in the specified part of a status window. SB_SETTEXT wParam = (WPARAM) iPart | uType; lParam = (LPARAM) (LPSTR) szText; ParametersiPartZero-based index of the part to set. If this value is 255, the status window is assumed to be a simple window having only one part.uTypeType of drawing operation. This parameter can be one of the following values:Value Meaning 0 The text is drawn with a border to appear lower than the plane of the window. SBT_NOBORDERS The text is drawn without borders. SBT_OWNERDRAW The text is drawn by the parent window. SBT_POPOUT The text is drawn with a border to appear higher than the plane of the window. SBT_RTLREADING Displays text using right-to-left reading order on Hebrew or Arabic systems. szTextPointer to a null-terminated string that specifies the text to set. If uType is SBT_OWNERDRAW, this parameter represents 32 bits of data. The parent window must interpret the data and draw the text when it receives the WM_DRAWITEM message.
...
property Text: string read FText write SetText;
...
end;Text属性是string类型应该是能存4G的长度的.下面是测试代码:
var
arr: array[0..299] of Char;
I: Integer;
J: Char;
begin
J := '0';
for I := 0 to 299 do
begin
arr[I] := J;
J := Char(Ord(J) + 1);
if j = ':' then j := '0'; //从0到9循环
end;
form1.StatusBar1.Panels.Items[0].Text := arr;
ShowMessage(form1.StatusBar1.Panels.Items[0].Text);
end;我看到的效果:
showmessage显示出来的,是足够300个字符的.说明:form1.StatusBar1.Panels.Items[0].Text这个值没问题.
但是,状态栏确实没显示完,可能是vcl内部代码限制了范围.你研究下paint之类的过程代码看看.
是TCustomStatusBar的这个过程,响应wm_paint消息的.他里面调用了UpdatePanels(False, True);
第一个参数是false,所以,UpdatePanels里面,最终有作用的是靠近下面的:
for I := 0 to Count - 1 do
UpdatePanel(I, UpdateText);继续跟踪UpdatePanel:
S := Text; //这里将Panels[Index]的text属性赋给了string变量S
if UseRightToLeftAlignment then
DoRightToLeftAlignment(S, Alignment, UseRightToLeftAlignment)
else
case Alignment of
taCenter: Insert(#9, S, 1);
taRightJustify: Insert(#9#9, S, 1);
end;
//给当前状态栏窗口发个SB_SETTEXT消息,设置文字,S的地址作为消息的LParam参数传入
SendMessage(Handle, SB_SETTEXT, Index or Flags, Integer(PChar(S))); 但是,TCustomStatusBar类中没有看到SB_SETTEXT的消息响应函数.....线索到这里,断了.TCustomStatusBar的CreateParams过程: InitCommonControl(ICC_BAR_CLASSES); //常量定义:ICC_BAR_CLASSES = $00000004; // toolbar, statusbar, trackbar, tooltips
inherited CreateParams(Params);
CreateSubClass(Params, STATUSCLASSNAME); //STATUSCLASSNAME = 'msctls_statusbar32';也就是说,这个状态栏窗口在创建的时候,delphi给它的style加了一些东西,
windows系统会根据这些东西去产生特殊的窗口.估计里面就包括了:SB_SETTEXT的消息响应过程.
不知道怎么跟了....,也许只能查查MSDN.
var
Flags: Integer;
S: string;
PanelRect: TRect;
begin
if HandleAllocated then
with Panels[Index] do
begin
if not Repaint then
begin
FUpdateNeeded := True;
SendMessage(Handle, SB_GETRECT, Index, Integer(@PanelRect));
InvalidateRect(Handle, @PanelRect, True);
Exit;
end
else if not FUpdateNeeded then Exit;
FUpdateNeeded := False;
Flags := 0;
case Bevel of
pbNone: Flags := SBT_NOBORDERS;
pbRaised: Flags := SBT_POPOUT;
end;
if UseRightToLeftReading then Flags := Flags or SBT_RTLREADING;
if Style = psOwnerDraw then Flags := Flags or SBT_OWNERDRAW;
S := Text;
if UseRightToLeftAlignment then
DoRightToLeftAlignment(S, Alignment, UseRightToLeftAlignment)
else
case Alignment of
taCenter: Insert(#9, S, 1);
taRightJustify: Insert(#9#9, S, 1);
end;
SendMessage(Handle, SB_SETTEXT, Index or Flags, Integer(PChar(S)));
end;
end;procedure TCustomStatusBar.UpdatePanels(UpdateRects, UpdateText: Boolean);
const
MaxPanelCount = 128;
var
I, Count, PanelPos: Integer;
PanelEdges: array[0..MaxPanelCount - 1] of Integer;
begin
if HandleAllocated then
begin
Count := Panels.Count;
if UpdateRects then
begin
if Count > MaxPanelCount then Count := MaxPanelCount;
if Count = 0 then
begin
PanelEdges[0] := -1;
SendMessage(Handle, SB_SETPARTS, 1, Integer(@PanelEdges));
SendMessage(Handle, SB_SETTEXT, 0, Integer(PChar('')));
end else
begin
PanelPos := 0;
for I := 0 to Count - 2 do
begin
Inc(PanelPos, Panels[I].Width);
PanelEdges[I] := PanelPos;
end;
PanelEdges[Count - 1] := -1;
SendMessage(Handle, SB_SETPARTS, Count, Integer(@PanelEdges));
end;
end;
for I := 0 to Count - 1 do
UpdatePanel(I, UpdateText);
end;
end;
wParam = (WPARAM) iPart | uType;
lParam = (LPARAM) (LPSTR) szText;
ParametersiPartZero-based index of the part to set. If this value is 255, the status window is assumed to be a simple window having only one part.uTypeType of drawing operation. This parameter can be one of the following values:Value Meaning
0 The text is drawn with a border to appear lower than the plane of the window.
SBT_NOBORDERS The text is drawn without borders.
SBT_OWNERDRAW The text is drawn by the parent window.
SBT_POPOUT The text is drawn with a border to appear higher than the plane of the window.
SBT_RTLREADING Displays text using right-to-left reading order on Hebrew or Arabic systems.
szTextPointer to a null-terminated string that specifies the text to set. If uType is SBT_OWNERDRAW, this parameter represents 32 bits of data. The parent window must interpret the data and draw the text when it receives the WM_DRAWITEM message.