A: I've got some code that calculates the width of a TDBGrid so that it will display all the fields, but no horizontal scrollbar. It takes into account the width of the vertical scrollbar (which changes based on the screen resolution) and the indicator. If you're not working with a DBGrid, perhaps something in here will be helpful for the other types of grids.
-------
function NewTextWidth(fntFont : TFont; const sString : OpenString) :
integer;
var
fntSave : TFont;
begin
result := 0;
fntSave := Application.MainForm.Font;
Application.MainForm.Font := fntFont;
try
result := Application.MainForm.Canvas.TextWidth(sString);
finally
Application.MainForm.Font := fntSave;
end;
end;
{ calculate the width of the grid needed to exactly display with no
}
{ horizontal scrollbar and with no extra space between the last
}
{ column and the vertical scrollbar. The grid's datasource must
be }
{ properly set and the datasource's dataset must be properly set,
}
{ though it need not be open. Note: this width includes
the width }
{ of the vertical scrollbar, which changes based on screen
}
{ resolution. These changes are compensated for.
}
function iCalcGridWidth
(
dbg : TDBGrid { the grid to meaure }
)
: integer; { the "exact" width }
const
cMEASURE_CHAR = '0';
iEXTRA_COL_PIX = 4;
iINDICATOR_WIDE = 11;
var
i, iColumns, iColWidth, iTitleWidth, iCharWidth : integer;
begin
iColumns := 0;
result := GetSystemMetrics(SM_CXVSCROLL);
iCharWidth := NewTextWidth(dbg.Font, cMEASURE_CHAR);
with dbg.dataSource.dataSet do
for i := 0 to FieldCount - 1 do with Fields[i] do
if visible then
begin
iColWidth := iCharWidth
* DisplayWidth;
if dgTitles in dbg.Options
then
begin
iTitleWidth
:= NewTextWidth(dbg.TitleFont, DisplayLabel);
if iColWidth
< iTitleWidth then iColWidth := iTitleWidth;
end;
inc(iColumns, 1);
inc(result, iColWidth +
iEXTRA_COL_PIX);
end;
if dgIndicator in dbg.Options then
begin
inc(iColumns, 1);
inc(result, iINDICATOR_WIDE);
end;
if dgColLines in dbg.Options
then inc(result, iColumns)
else inc(result, 1);
end;
-----
I had to use the function NewTextWidth, rather than the Grid's Canvas.TextWith
as the Canvas of the Grid may not initialized when you need to call iCalcGridWidth.