## 2011. április 23., szombat

### Align cells in a TStringGrid (2)

Problem/Question/Abstract:

I need to right-align text in certain cells of a TStringGrid. How can I do that?

Solve 1:

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
dx: integer;
Text: string;
begin
if aCol in [1..2] then {If column is 1 or 2, then right-align text}
with StringGrid1.Canvas do
begin
FillRect(Rect);
Text := StringGrid1.cells[aCol, aRow];
dx := TextWidth(Text) + 2;
TextOut(Rect.Right - dx, Rect.Top, Text);
end;
end;

Solve 2:

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
const
CharOffset = 3;
var
fLeft: Integer;
begin
{Right justify column 3}
if (ACol = 3) then
begin
with TStringGrid(Sender) do
begin
Canvas.FillRect(Rect);
fLeft := Rect.Right - Canvas.TextWidth(Cells[ACol, ARow]);
Canvas.TextOut(fleft - CharOffset, Rect.Top + CharOffset, Cells[ACol, ARow]);
end;
end;
end;

Solve 3:

The following code aligns the strings of the first column in a TStringGrid to the right:

procedure DrawTheText(ACanvas: TCanvas; ARect: TRect;
AValue: string; AAlign: TAlignment);
var
horzOffset: integer;
options: integer;
vertOffset: integer;
begin
{Note: The Handle property of TCanvas is the handle of its DC.}
with ACanvas do
begin
vertOffset := ARect.Top + (((ARect.Bottom - ARect.Top) -
TextExtent(AValue).CY) div 2);
horzOffset := TextExtent('Mi').CX div 4;
{Yields rougly the width of an "average" character}
options := ETO_CLIPPED or ETO_OPAQUE;
case AAlign of
taLeftJustify:
begin
SetTextAlign(Handle, TA_LEFT or TA_TOP or TA_NOUPDATECP);
ExtTextOut(Handle, ARect.Left + horzOffset, vertOffset, options,
@ARect, PChar(AValue), Length(AValue), nil);
end;
taRightJustify:
begin
SetTextAlign(Handle, TA_RIGHT or TA_TOP or TA_NOUPDATECP);
ExtTextOut(Handle, ARect.Right - horzOffset, vertOffset, options,
@ARect, PChar(AValue), Length(AValue), nil);
end;
taCenter:
begin
horzOffset := ((ARect.Right - ARect.Left) - TextExtent(AValue).CX) div 2;
SetTextAlign(Handle, TA_LEFT or TA_TOP or TA_NOUPDATECP);
ExtTextOut(Handle, ARect.Left + horzOffset, vertOffset, options,
@ARect, PChar(AValue), Length(AValue), nil);
end;
end;
end;
end;

procedure TFrmAlignText.StringGridDrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
var
align: TAlignment;
theText: string;
thisRect: TRect;
begin
{Assumes that DefaultDrawing := true}
theText := IntToStr(Col) + ':' + IntToStr(Row);
align := taLeftJustify;
{Select background color}
if gdSelected in State then
StringGrid.Canvas.Brush.Color := clHighlight
else if gdFixed in State then
StringGrid.Canvas.Brush.Color := clBtnFace
else
StringGrid.Canvas.Brush.Color := clWindow;
{Determine font/text attributes}
StringGrid.Canvas.Font.Color := clBlack;
StringGrid.Canvas.Font.Style := StringGrid.Canvas.Font.Style - [fsBold];
if Col = 1 then
begin
align := taRightJustify;
StringGrid.Canvas.Font.Style := StringGrid.Canvas.Font.Style + [fsBold];
StringGrid.Canvas.Font.Color := clRed;
StringGrid.Canvas.Font.Name := 'Courier New';
end
else if Col = 2 then
begin
align := taCenter;
StringGrid.Canvas.Font.Style := StringGrid.Canvas.Font.Style + [fsBold]
end
else if (Row = 0) and (Col = 0) then
begin
StringGrid.Canvas.Draw(Rect.Left + 2, Rect.Top + 2, Image.Picture.Graphic);
end;
if not ((Row = 0) and (Col = 0)) then
DrawTheText(StringGrid.Canvas, Rect, theText, align);
{Draw focus rectangle}
if gdFocused in State then
StringGrid.Canvas.DrawFocusRect(Rect);
if gdFixed in State then
Frame3D(StringGrid.Canvas, Rect, clWindow, clHighlight, 1);
end;