Following on from this question and its very useful answer: I implemented a variation of Ken's answer in my big project where I had similar code appearing in many forms. But I noticed that I also had some forms with DrawColumnCell handlers as follows
procedure TEditDocket.DBGrid1DrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn;
State: TGridDrawState);
var
DrawRect: TRect;
begin
if column.Index = 3 then
begin
DrawRect:= Rect;
drawrect.left:= rect.left + 24;
InflateRect (DrawRect, -1, -1);
dbgrid1.Canvas.FillRect (Rect);
DrawFrameControl (dbgrid1.Canvas.Handle, DrawRect, DFC_BUTTON,
ISChecked[Column.Field.AsInteger]);
end
else dbgrid1.DefaultDrawColumnCell (Rect, DataCol, Column, State);
end;
How I could combine the above code with a general OnDrawColumnCell handler? Is it possible to define the general handler with an extra parameter (which would be the column index; if it were -1 then the above code would not execute)? How would I pass such a parameter to the handler?
Independently, I reached the following answer using the 'tag' property of the grid.
In the client form, I write
dbGrid1.OnDrawColumnCell:= dm.DBGrid1DrawColumnCell;
dbGrid1.tag:= 3; // column with checkbox
dbGrid2.OnDrawColumnCell:= dm.DBGrid1DrawColumnCell;
dbGrid2.tag:= $23; // both columns 2 and 3 are checkboxes
The default handler is now
procedure TDm.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
const
IsChecked : array[0..1] of Integer =
(DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED);
var
DrawRect: TRect;
tag: integer;
cols: set of byte;
begin
if sender is TDBGrid then
begin
tag:= TDBGrid (sender).tag;
if (THackDBGrid (sender).DataLink.ActiveRecord + 1 = THackDBGrid (sender).Row)
or (gdFocused in State) or (gdSelected in State) then
with TDBGrid (sender) do
begin
canvas.Brush.Color:= clMoneyGreen;
canvas.font.color:= clNavy;
end;
cols:= [];
while tag > 0 do
begin
cols:= cols + [tag mod 16];
tag:= tag div 16
end;
if column.Index in cols then
begin
DrawRect:= Rect;
drawrect.left:= rect.left + 24;
InflateRect (DrawRect, -1, -1);
TDBGrid (sender).Canvas.FillRect (Rect);
DrawFrameControl (TDBGrid (sender).Canvas.Handle, DrawRect, DFC_BUTTON,
ISChecked[Column.Field.AsInteger]);
end
else
begin
TDBGrid (sender).DefaultDrawColumnCell (Rect, DataCol, Column, State);
end;
end;
end;
This means that column 0 must never be a checkbox. Using a set allows up to four columns in the grid to be checkboxes.