Discussion:
A question on a DrawCell proc (from Alan Loyd?)
(too old to reply)
Stark
2010-06-14 09:45:30 UTC
Permalink
I needed to center the text in some cells and align it to left on others. In
internet I found the routine below that does something different, but useful
anyway to me. I tried it and found a funny thing that confuses me: in the
procedure definition that is automatically produced would be ".. Rect:
TRect; " , but is changed to ".. ARect: TRect; ".
In the code, both Rect and ARect is used, and this is the only way the
routine works. In fact I tried initially to use "Rect" instead, but can't
compile correctly.
What's the secret behind this ?

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
ARect: TRect; State: TGridDrawState);
var
TextHt : integer; // height of word-broken text
WidthRect : TRect; // dummy for height calculation
begin
with StringGrid1, Stringgrid1.Canvas do
begin
if (gdFixed in State) then
Brush.Color := clInactiveBorder
else
if (gdSelected in State) then
begin
Brush.Color := clHighLight;
Brush.Color := clWindow;
Font.Color := clWindow;
end
else
Brush.Color := clWindow;
Canvas.FillRect(ARect);
if (gdFocused in State) then
DrawFocusRect(ARect);
InflateRect(ARect, -2, -2); // reduce cell rect for text margins in cell
{calculate height of word-broken text}
WidthRect := Rect(0, 0, ColWidths[ACol] - 4, 0);
TextHt := DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
-1, WidthRect, DT_CENTER or DT_WORDBREAK or
DT_CALCRECT);
if TextHt > RowHeights[ARow] - 4 then
RowHeights[ARow] := TextHt + 4;
if TextHt > TextHeight('X') + 2 then // + 2 for text leading
{multi-lines}
DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
-1, ARect, DT_CENTER or DT_WORDBREAK)
else
{only one line - so centre vertically}
DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
-1, ARect, DT_CENTER or DT_SINGLELINE or DT_VCENTER);
end;
end;
Chris.Cheney
2010-06-14 11:01:36 UTC
Permalink
Post by Stark
I needed to center the text in some cells and align it to left on
others. In internet I found the routine below that does something
different, but useful anyway to me. I tried it and found a funny thing
that confuses me: in the procedure definition that is automatically
TRect; ". In the code, both Rect and ARect is used, and this is the
only way the routine works. In fact I tried initially to use "Rect"
instead, but can't compile correctly.
What's the secret behind this ?
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
ARect: TRect; State: TGridDrawState);
var
TextHt : integer; // height of word-broken text
WidthRect : TRect; // dummy for height calculation
begin
with StringGrid1, Stringgrid1.Canvas do
begin
if (gdFixed in State) then
Brush.Color := clInactiveBorder
else
if (gdSelected in State) then
begin
Brush.Color := clHighLight;
Brush.Color := clWindow;
Font.Color := clWindow;
end
else
Brush.Color := clWindow;
Canvas.FillRect(ARect);
if (gdFocused in State) then
DrawFocusRect(ARect);
InflateRect(ARect, -2, -2); // reduce cell rect for text margins
in cell {calculate height of word-broken text}
WidthRect := Rect(0, 0, ColWidths[ACol] - 4, 0);
Here Rect(...) is a function yielding a TRect value. The Rect parameter
of StringGrid1DrawCell was changed to ARect so as not to conflict with
this function.
Post by Stark
TextHt := DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
-1, WidthRect, DT_CENTER or DT_WORDBREAK or
DT_CALCRECT);
if TextHt > RowHeights[ARow] - 4 then
RowHeights[ARow] := TextHt + 4;
if TextHt > TextHeight('X') + 2 then // + 2 for text leading
{multi-lines}
DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
-1, ARect, DT_CENTER or DT_WORDBREAK)
else
{only one line - so centre vertically}
DrawText(Canvas.Handle, PChar(Cells[ACol, ARow]),
-1, ARect, DT_CENTER or DT_SINGLELINE or DT_VCENTER);
end;
end;
a***@aol.com
2010-06-14 16:10:18 UTC
Permalink
On 14 June, 12:01, "Chris.Cheney" <***@tesco.net>
wrote:
<snip>
The Rect parameter
Post by Chris.Cheney
of StringGrid1DrawCell was changed to ARect so as not to conflict with
this function.
More than that, Delphi 3 uses Row & Col in the event handler's
parameters. This conflicts with the Row & Col properties of the
TStringGrid itself. They change to ARow & ACol in later Delphi's event
handlers. Using Delphi 3 I considered this should be carried across to
the Rect parameter as well, changing it to ARect.

Putting 'A' before names is a well-used technique where confusion may
arise between parameters of a function & properties of an object.
Scope _should_ prevent such confusion in execution, but using 'A'
prefix also makes for clearer code (an obsession with me <g>).

Alan Lloyd

Loading...