Create columns of equal width in a TStringGrid (Views: 28)
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; |