I want to put a TCheckBox
inside a TStringGrid
in Delphi in every cell of certain column. I'm using Delphi XE.
You should draw your own checkboxes, preferably using visual themes, if enabled. This is a simple sketch of how to do that:
const
Checked: array[1..4] of boolean = (false, true, false, true);
procedure TForm4.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
const
PADDING = 4;
var
h: HTHEME;
s: TSize;
r: TRect;
begin
if (ACol = 2) and (ARow >= 1) then
begin
FillRect(StringGrid1.Canvas.Handle, Rect, GetStockObject(WHITE_BRUSH));
s.cx := GetSystemMetrics(SM_CXMENUCHECK);
s.cy := GetSystemMetrics(SM_CYMENUCHECK);
if UseThemes then
begin
h := OpenThemeData(StringGrid1.Handle, 'BUTTON');
if h <> 0 then
try
GetThemePartSize(h,
StringGrid1.Canvas.Handle,
BP_CHECKBOX,
CBS_CHECKEDNORMAL,
nil,
TS_DRAW,
s);
r.Top := Rect.Top + (Rect.Bottom - Rect.Top - s.cy) div 2;
r.Bottom := r.Top + s.cy;
r.Left := Rect.Left + PADDING;
r.Right := r.Left + s.cx;
DrawThemeBackground(h,
StringGrid1.Canvas.Handle,
BP_CHECKBOX,
IfThen(Checked[ARow], CBS_CHECKEDNORMAL, CBS_UNCHECKEDNORMAL),
r,
nil);
finally
CloseThemeData(h);
end;
end
else
begin
r.Top := Rect.Top + (Rect.Bottom - Rect.Top - s.cy) div 2;
r.Bottom := r.Top + s.cy;
r.Left := Rect.Left + PADDING;
r.Right := r.Left + s.cx;
DrawFrameControl(StringGrid1.Canvas.Handle,
r,
DFC_BUTTON,
IfThen(Checked[ARow], DFCS_CHECKED, DFCS_BUTTONCHECK));
end;
r := Classes.Rect(r.Right + PADDING, Rect.Top, Rect.Right, Rect.Bottom);
DrawText(StringGrid1.Canvas.Handle,
StringGrid1.Cells[ACol, ARow],
length(StringGrid1.Cells[ACol, ARow]),
r,
DT_SINGLELINE or DT_VCENTER or DT_LEFT or DT_END_ELLIPSIS);
end;
end;
Of course, in a real scenario, the Checked
array is not a constant, and you might wish to save the s
metrics and h
theme handle between cell painting events. But the principle is here.
What is missing here is a function to alter the state of the checkboxes. You will probably want to toggle the state in an OnClick
handler. If you are really serious, you'll also wish to respond to the motion of the mouse, and display the mouse hover effect on the checkboxes if themes are available.
EDIT by bluish: To toggle checkbox state, this answer explains how you can use Invalidate
method.