I'm trying to work out how to set ScrollWidth
on a TListBox
to control the horizontal scroll bar. Here's my first attempt:
program ListBoxSizing;
uses
Math, Forms, StdCtrls;
var
Form: TForm;
ListBox: TListBox;
procedure BuildForm;
begin
//Form.Font.Size := 9;
Form.ClientWidth := 200;
Form.ClientHeight := 100;
ListBox := TListBox.Create(Form);
ListBox.Parent := Form;
ListBox.SetBounds(0, 0, Form.ClientWidth, Form.ClientHeight);
ListBox.Items.Add('ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ');
end;
procedure SetScrollWidth;
var
i, MaxWidth: Integer;
begin
MaxWidth := -1;
for i := 0 to ListBox.Items.Count-1 do
MaxWidth := Max(MaxWidth, ListBox.Canvas.TextWidth(ListBox.Items[i]));
if MaxWidth<>-1 then
ListBox.ScrollWidth := MaxWidth;
end;
begin
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm, Form);
BuildForm;
SetScrollWidth;
Application.Run;
end.
This is how the result looks with the horizontal scroll bar moved as far right as possible:
Notice how the last part of the final character has been chopped off.
Now, if we uncomment the line that changes the form's font size, it looks like this:
Now, it seems that the change to font size hasn't been accounted for in the subsequent calls to TextWidth
.
So, my question is, what code do I need to use to be able to set ScrollWidth
accurately, based on the current contents of the list box.
procedure SetScrollWidth;
var
I, MaxWidth: Integer;
begin
MaxWidth := -1;
// assign control's font to canvas
ListBox.Canvas.Font := ListBox.Font;
for I := 0 to ListBox.Items.Count - 1 do
MaxWidth := Max(MaxWidth, ListBox.Canvas.TextWidth(ListBox.Items[I]));
// consider non-client area
if MaxWidth <> -1 then
ListBox.ScrollWidth := MaxWidth + ListBox.Width - ListBox.ClientWidth;
end;
program Project2;
uses
Math, Forms, StdCtrls,Windows,Graphics;
var
Form: TForm;
ListBox: TListBox;
procedure BuildForm;
begin
//Form.Font.Size := 9;
Form.ClientWidth := 200;
Form.ClientHeight := 100;
ListBox := TListBox.Create(Form);
ListBox.Parent := Form;
Listbox.Font.Size := 40;
ListBox.SetBounds(0, 0, Form.ClientWidth, Form.ClientHeight);
ListBox.Items.Add('ABCDEFGXXXXXXXXXXXXOXOXYQASEOOWW');
ListBox.Items.Add('ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ');
ListBox.Items.Add('ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ111111111111111111111111111111111111111O');
end;
function GetRealFontWidth(fnt: TFont; const text:string): Integer;
var
dc: hdc;
tsize : Windows.TSize;
oldObj : Cardinal;
begin
dc := GetDC(0);
oldObj := SelectObject(DC, fnt.Handle);
GetTextExtentPoint32(dc, PChar(text), Length(text), tsize);
SelectObject(DC, oldObj);
ReleaseDC(0, DC);
Result := tsize.cx;
end;
procedure SetScrollWidth;
var
i, MaxWidth: Integer;
begin
MaxWidth := -1;
for i := 0 to ListBox.Items.Count-1 do
MaxWidth := Max(MaxWidth, GetRealFontWidth (ListBox.Font,ListBox.Items[i]));
if MaxWidth<>-1 then
ListBox.ScrollWidth := MaxWidth + 4;
end;
begin
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm, Form);
BuildForm;
SetScrollWidth;
Application.Run;
end.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With