Peter Kiers
asked on
Auto size the panels of the statusbar
Hello everybody,
Is it possible to auto size the statusbar panels?
So that the width of the panel sadjust to the text in the panel.
This is what i made when the user resizes the form
now i need help with the auto size the panels.
procedure TMainForm.StatusBar2Resize (Sender: TObject);
begin
with StatusBar2 do
Panels[0].Width := Width - Panels[1].Width -
Panels[2].Width - Panels[3].Width - Panels[4].Width -
Panels[5].Width - Panels[6].Width
end;
(*------------------------ ---------- ---------- ---*)
procedure TMainForm.StatusBar1Resize (Sender: TObject);
begin
with StatusBar1 do
Panels[0].Width := Width - Panels[1].Width -
Panels[2].Width - Panels[3].Width - Panels[4].Width;
end;
(*------------------------ ---------- ---------- ---*)
Kind Regards,
Peter Kiers
Is it possible to auto size the statusbar panels?
So that the width of the panel sadjust to the text in the panel.
This is what i made when the user resizes the form
now i need help with the auto size the panels.
procedure TMainForm.StatusBar2Resize
begin
with StatusBar2 do
Panels[0].Width := Width - Panels[1].Width -
Panels[2].Width - Panels[3].Width - Panels[4].Width -
Panels[5].Width - Panels[6].Width
end;
(*------------------------
procedure TMainForm.StatusBar1Resize
begin
with StatusBar1 do
Panels[0].Width := Width - Panels[1].Width -
Panels[2].Width - Panels[3].Width - Panels[4].Width;
end;
(*------------------------
Kind Regards,
Peter Kiers
ASKER
After running it i get:
[Error] Main.pas(3029): Undeclared identifier: 'SB_GETBORDERS'
[Error] Main.pas(3029): Undeclared identifier: 'SB_GETBORDERS'
Seems like the AutoSizeStatusbarPanel(sb: TStatusBar; idx:Integer);
procedure wants a status bar control and the index of the panel to autosize. Also, include the CommCtrl unit in your uses clause to fix the reference error
Regards,
Russell
procedure wants a status bar control and the index of the panel to autosize. Also, include the CommCtrl unit in your uses clause to fix the reference error
Regards,
Russell
ASKER
Oke, i have this:
procedure TMainForm.AutoSizeStatusba rPanel(Sta tusbar1: TStatusBar;
idx: Integer);
var
s : string;
borders : array[0..2] of Integer;
begin
// don't deal with simple panels
if Statusbar2.SimplePanel
// don't resize the last panel
or (idx >= Statusbar1.Panels.Count-1) then
Exit;
// get the borders of the statusbar
// border[0] = width of the horizontal border
// border[1] = width of the vertical border
// border[2] = width of the border between rectangles
SendMessage(Statusbar2.Han dle, SB_GETBORDERS, 0, Integer(@borders));
s := Statusbar2.Panels[idx].Tex t;
// calculate the width of the Panel
Statusbar1.Panels[idx].Wid th := TrueFontWidth(Statusbar2.F ont, s) +
borders[2]*2 +2; // vertical border * 2 + 2 extra Pixels
end;
Now my application execute, but the procedure doesn't work?
Peter
procedure TMainForm.AutoSizeStatusba
idx: Integer);
var
s : string;
borders : array[0..2] of Integer;
begin
// don't deal with simple panels
if Statusbar2.SimplePanel
// don't resize the last panel
or (idx >= Statusbar1.Panels.Count-1)
Exit;
// get the borders of the statusbar
// border[0] = width of the horizontal border
// border[1] = width of the vertical border
// border[2] = width of the border between rectangles
SendMessage(Statusbar2.Han
s := Statusbar2.Panels[idx].Tex
// calculate the width of the Panel
Statusbar1.Panels[idx].Wid
borders[2]*2 +2; // vertical border * 2 + 2 extra Pixels
end;
Now my application execute, but the procedure doesn't work?
Peter
ASKER
And I have this message:
[Hint] Main.pas(372): Private symbol 'AutoSizeStatusbarPanel' declared but never used
[Hint] Main.pas(372): Private symbol 'AutoSizeStatusbarPanel' declared but never used
Um, not sure why you are mixing statusbar2 and statusbar1 in the same calls?. Perhaps this will clarify it a little bit. Example form code first, dfm follows
Russell
--
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
CommCtrl, StdCtrls, ComCtrls;
type
TForm1 = class(TForm)
StatusBar1: TStatusBar;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function TrueFontWidth(fnt: TFont; const text:string): Integer;
procedure AutoSizeStatusbarPanel(sb:
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure AutoSizeStatusbarPanel(sb:
var
s : string;
borders : array[0..2] of Integer;
begin
// don't deal with simple panels
if sb.SimplePanel
// don't resize the last panel
or (idx >= sb.Panels.Count-1) then
Exit;
// get the borders of the statusbar
// border[0] = width of the horizontal border
// border[1] = width of the vertical border
// border[2] = width of the border between rectangles
SendMessage(sb.Handle, SB_GETBORDERS, 0, Integer(@borders));
s := sb.Panels[idx].Text;
// calculate the width of the Panel
sb.Panels[idx].Width := TrueFontWidth(sb.Font, s) +
borders[2]*2 +2; // vertical border * 2 + 2 extra Pixels
end;
function TrueFontWidth(fnt: TFont; const text:string): Integer;
var
dc: hdc;
tsize : Windows.TSize;
begin
dc := GetDC(0);
SelectObject(DC, fnt.Handle);
GetTextExtentPoint32(dc, PChar(text), Length(text), tsize);
ReleaseDC(0, DC);
Result := tsize.cx;
end;
procedure TForm1.Button1Click(Sender
var dwIndex: Integer;
begin
for dwIndex:=0 to Pred(StatusBar1.Panels.Cou
AutoSizeStatusbarPanel(Sta
end;
end.
--- dfm ---
object Form1: TForm1
Left = 216
Top = 120
Width = 535
Height = 197
Caption = 'Form1'
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 = 144
Width = 527
Height = 19
Panels = <
item
Text = 'Hello world this is a test'
Width = 50
end
item
Text = '100'
Width = 50
end
item
Text = 'Some other very long text'
Width = 50
end
item
Text = 'Delphi'
Width = 50
end>
SimplePanel = False
end
object Button1: TButton
Left = 16
Top = 12
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 1
OnClick = Button1Click
end
end
ASKER
Hi,
Thank you for the example, your example works fine.
But not in my application, and I think the problem is
that i dont have to autosize all the panels.
I have 7 panels (0 to 6) and I want only panel 1,3 and 5
to autosize.
Peter
Thank you for the example, your example works fine.
But not in my application, and I think the problem is
that i dont have to autosize all the panels.
I have 7 panels (0 to 6) and I want only panel 1,3 and 5
to autosize.
Peter
???? Then use
AutoSizeStatusbarPanel(Sta tusBar1, 1);
AutoSizeStatusbarPanel(Sta tusBar1, 3);
AutoSizeStatusbarPanel(Sta tusBar1, 5);
My code was a demo of usage only. If you want to autosize only 1 panel, then pass the owning statusbar and the panel index. If you want to do it for 3 panels, then call the function 3 times. if you need to do it for another status bar, then pass that status bar in.
AutoSizeStatusbarPanel(Sta tusBar2, 1);
If you are having trouble then please post the code you have.
Russell
AutoSizeStatusbarPanel(Sta
AutoSizeStatusbarPanel(Sta
AutoSizeStatusbarPanel(Sta
My code was a demo of usage only. If you want to autosize only 1 panel, then pass the owning statusbar and the panel index. If you want to do it for 3 panels, then call the function 3 times. if you need to do it for another status bar, then pass that status bar in.
AutoSizeStatusbarPanel(Sta
If you are having trouble then please post the code you have.
Russell
ASKER
I try and I try, but no luck sofar...
procedure TMainForm.FormCreate(Sende r: TObject);
var
dwIndex: Integer;
begin
AutoSizeStatusbarPanel(Sta tusBar2, 1);
AutoSizeStatusbarPanel(Sta tusBar2, 3);
AutoSizeStatusbarPanel(Sta tusBar2, 5);
end;
(*------------------------ ---------- ---------- ---*)
procedure TMainForm.AutoSizeStatusba rPanel(sb: TStatusBar; idx: Integer);
var
s : string;
borders : array[0..2] of Integer;
begin
// don't deal with simple panels
if sb.SimplePanel
// don't resize the last panel
or (idx >= sb.Panels.Count-1) then
Exit;
// get the borders of the statusbar
// border[0] = width of the horizontal border
// border[1] = width of the vertical border
// border[2] = width of the border between rectangles
SendMessage(sb.Handle, SB_GETBORDERS, 0, Integer(@borders));
s := sb.Panels[idx].Text;
// calculate the width of the Panel
sb.Panels[idx].Width := TrueFontWidth(sb.Font, s) +
borders[2]*2 +2; // vertical border * 2 + 2 extra Pixels
end;
(*------------------------ ---------- ---------- ---*)
function TMainForm.TrueFontWidth(fn t: TFont; const text: string): Integer;
var
dc: hdc;
tsize : Windows.TSize;
begin
dc := GetDC(0);
SelectObject(DC, fnt.Handle);
GetTextExtentPoint32(dc, PChar(text), Length(text), tsize);
ReleaseDC(0, DC);
Result := tsize.cx;
end;
(*------------------------ ---------- ---------- ---*)
procedure TMainForm.StatusBar2Resize (Sender: TObject);
begin
with StatusBar2 do
Panels[0].Width := Width - Panels[1].Width -
Panels[2].Width - Panels[3].Width - Panels[4].Width -
Panels[5].Width - Panels[6].Width;
end;
(*------------------------ ---------- ---------- ---*)
Peter
procedure TMainForm.FormCreate(Sende
var
dwIndex: Integer;
begin
AutoSizeStatusbarPanel(Sta
AutoSizeStatusbarPanel(Sta
AutoSizeStatusbarPanel(Sta
end;
(*------------------------
procedure TMainForm.AutoSizeStatusba
var
s : string;
borders : array[0..2] of Integer;
begin
// don't deal with simple panels
if sb.SimplePanel
// don't resize the last panel
or (idx >= sb.Panels.Count-1) then
Exit;
// get the borders of the statusbar
// border[0] = width of the horizontal border
// border[1] = width of the vertical border
// border[2] = width of the border between rectangles
SendMessage(sb.Handle, SB_GETBORDERS, 0, Integer(@borders));
s := sb.Panels[idx].Text;
// calculate the width of the Panel
sb.Panels[idx].Width := TrueFontWidth(sb.Font, s) +
borders[2]*2 +2; // vertical border * 2 + 2 extra Pixels
end;
(*------------------------
function TMainForm.TrueFontWidth(fn
var
dc: hdc;
tsize : Windows.TSize;
begin
dc := GetDC(0);
SelectObject(DC, fnt.Handle);
GetTextExtentPoint32(dc, PChar(text), Length(text), tsize);
ReleaseDC(0, DC);
Result := tsize.cx;
end;
(*------------------------
procedure TMainForm.StatusBar2Resize
begin
with StatusBar2 do
Panels[0].Width := Width - Panels[1].Width -
Panels[2].Width - Panels[3].Width - Panels[4].Width -
Panels[5].Width - Panels[6].Width;
end;
(*------------------------
Peter
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
It works perfectly.
Thank you.
500 point comming your way...
Bye.
P.
Thank you.
500 point comming your way...
Bye.
P.
And thank you Peter..
Russell
ASKER
procedure AutoSizeStatusbarPanel(sb:
var
s : string;
borders : array[0..2] of Integer;
begin
// don't deal with simple panels
if sb.SimplePanel
// don't resize the last panel
or (idx >= sb.Panels.Count-1) then
Exit;
// get the borders of the statusbar
// border[0] = width of the horizontal border
// border[1] = width of the vertical border
// border[2] = width of the border between rectangles
SendMessage(sb.Handle, SB_GETBORDERS, 0, Integer(@borders));
s := sb.Panels[idx].Text;
// calculate the width of the Panel
sb.Panels[idx].Width := TrueFontWidth(sb.Font, s) +
borders[2]*2 +2; // vertical border * 2 + 2 extra Pixels
end;
function TrueFontWidth(fnt: TFont; const text:string): Integer;
var
dc: hdc;
tsize : Windows.TSize;
begin
dc := GetDC(0);
SelectObject(DC, fnt.Handle);
GetTextExtentPoint32(dc, PChar(text), Length(text), tsize);
ReleaseDC(0, DC);
Result := tsize.cx;
end;
But I have no idea what the procedure
and the function means!
P.