Also wir haben das so gelöst:
Delphi-Quellcode:
function TextGroesse(
const Text :
string; Font : TFont =
nil) : TSize;
var
DC : hDC;
F : hFont;
R : TRect;
begin
F := 0;
DC := GetDC(0);
try
if Font <>
nil then
F := SelectObject(
DC, Font.Handle);
if not GetTextExtentPoint32(
DC, Text, Length(Text), Result)
then
begin
Result.cx := 0;
Result.cy := 0;
end;
finally
if F <> 0
then
SelectObject(
DC, F);
ReleaseDC(0,
DC);
end;
end;
procedure SetColumnWidth(DBGrid : TDBGrid);
var
i, j : integer;
iMaxRow : integer;
begin
with DBGrid
do
begin
// maximal || Zeilen durchsuchen
iMaxRow := Min(40, DataSource.DataSet.RecordCount);
try
DataSource.DataSet.DisableControls;
Visible := false;
// notwendig, da controls disabled!
DataSource.DataSet.First;
// mit Breite der Überschriften inizialisieren
for i := 0
to Columns.Count - 1
do
begin
Columns.Items[i].Width := TextGroesse(Columns[i].Title.Caption, Canvas.Font).cx + 10;
end;
// auf die größte Breite der ersten iMaxRow Zeilen stellen
for j := 0
to iMaxRow - 1
do
begin
for i := 0
to Columns.Count - 1
do
begin
Columns.Items[i].Width := Max(TextGroesse(Fields[i].Text, Canvas.Font).cx + 10, Columns.Items[i].Width);
end;
DataSource.DataSet.Next;
end;
DataSource.DataSet.First;
finally
DataSource.DataSet.EnableControls;
Visible := true;
end;
end;
end;
Leider mussten wir GetTextExtentPoint32 für die Textbreite verwenden, da Canvas.TextWidth manchmal einen fehlerhaften (zu kleinen) Wert liefert.
Bemerkungen:
1. Da wir z.T. sehr viele Datensätze haben können > 10 Mio. haben wir die Breitenberechnung auf 40 DS beschränkt.
2. An die Textbreite wird + 10 angehängt um einen kleinen Abstand zur Begrenzung zu haben.
3. Wir haben auf Bookmarks verzichtet, da die Berechnung der Breite nur beim inizialen Laden der Daten notwenig ist.
4. Besonders wichtig sind DisableControls und Visible := false, damit wird die Funktion um ein vielfaches schneller.
Gruß David