2010. július 29., csütörtök
Create columns of equal width in a TStringGrid
Problem/Question/Abstract:
How to create columns of equal width in a TStringGrid
Answer:
The main problem we encounter, it’s that width of any object is translated to screen pixels, thus - integer value. While we try to divide the TStringGrid columns to fit the grid client area, we might get a non-integer value and a fractional remainder. Therefore, in order to compensate for the insufficient gap we got (if the total columns width is less than the grid client area) or to compensate the exceeding gap (if the total columns width exceed the grid client area), we need to adjust one or more of the columns width.
procedure WidthEqually(AGrid: TStringGrid);
var
I, GrdWidth: Integer;
FinalWidth: Double;
GoOn: Boolean;
begin
with AGrid do
begin
{Avoiding StringGrid to be repainted }
Perform(WM_SETREDRAW, 0, 0);
if FAutoWidth then
FAutoWidth := False;
try
GrdWidth := Width;
{Taking into consideration our vertical scrollbar width, if any ...}
if IsScrollBar(AGrid, WS_VSCROLL) then
Dec(GrdWidth, GetSystemMetrics(SM_CXVSCROLL));
{Here we subtract additional pixels for our GridLines width}
FinalWidth := (GrdWidth / ColCount) - (ColCount * GridLineWidth);
{The first sizing session}
for I := 0 to ColCount - 1 do
begin
Application.ProcessMessages;
ColWidths[I] := Trunc(FinalWidth);
end;
{Now we need to check where we ended. Either we are right on spot,
meaning columns could be divided equally to fit our FinalWidth.
If so, we should not have any horizontal scrollbar
or a gap between our last columns to the grid edge.}
GoOn := True;
{If we exceeded our FinalWidth, we start reducing widths starting
from our last columns.}
if IsScrollBar(AGrid, WS_HSCROLL) then
begin
while GoOn do
begin
Application.ProcessMessages;
for I := ColCount - 1 downto 0 do
begin
Application.ProcessMessages;
ColWidths[I] := ColWidths[I] - 1;
{We are Ok now, time to leave...}
if not IsScrollBar(AGrid, WS_HSCROLL) then
begin
GoOn := False;
Break;
end;
end;
end;
end
else
begin
{If we still have a gap, we increase our ColWidths}
while GoOn do
begin
Application.ProcessMessages;
for I := ColCount - 1 downto 0 do
begin
Application.ProcessMessages;
ColWidths[I] := ColWidths[I] + 1;
{We are Ok now, time to leave...}
if IsScrollBar(AGrid, WS_HSCROLL) then
begin
{We resize this column back. We don't want any horizontal scrollbar.}
ColWidths[I] := ColWidths[I] - 1;
GoOn := False;
Break;
end;
end;
end;
end;
finally
{Unlocking our grid and repainting}
Perform(WM_SETREDRAW, 1, 0);
Repaint;
end;
end;
end;
function IsScrollBar(AGrid: TStringGrid; nFlag: Cardinal): Boolean;
begin
Result := (GetWindowLong(AGrid.Handle, GWL_STYLE) and nFlag) <> 0;
end;
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése