の特定の列にチェックボックスを描画する必要があるTListViewので、この質問How can I setup TListView with CheckBoxes in only certain columns?をチェックし、受け入れられた回答で、この別の質問How to set a Checkbox TStringGrid in Delphi?で説明されている方法を使用することを提案します。これで、ListViewで動作するようにそのコードを移植します。
procedure TForm15.ListView1CustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
const
PADDING = 4;
var
h : HTHEME;
s : TSize;
r : TRect;
Rect : TRect;
i : Integer;
Dx : Integer;
begin
if (SubItem=1) then
begin
DefaultDraw:=True;
Rect :=Item.DisplayRect(drBounds);
Dx:=0;
for i := 0 to SubItem do
Inc(Dx,Sender.Column[i].Width);
Rect.Left :=Rect.Left+Dx;
Rect.Right :=Rect.Left+Sender.Column[SubItem+1].Width;
FillRect(Sender.Canvas.Handle, Rect, GetStockObject(WHITE_BRUSH));
s.cx := GetSystemMetrics(SM_CXMENUCHECK);
s.cy := GetSystemMetrics(SM_CYMENUCHECK);
if UseThemes then
begin
h := OpenThemeData(Sender.Handle, 'BUTTON');
if h <> 0 then
try
GetThemePartSize(h, Sender.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, Sender.Canvas.Handle, BP_CHECKBOX, IfThen(CompareText(Item.SubItems[1],'True')=0, 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(Sender.Canvas.Handle, r, DFC_BUTTON, IfThen(CompareText(Item.SubItems[1],'True')=0, DFCS_CHECKED, DFCS_BUTTONCHECK));
end;
//r := Classes.Rect(r.Right + PADDING, Rect.Top, Rect.Right, Rect.Bottom);
// DrawText(Sender.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
else
DefaultDraw:=False;
end;
しかし、私はチェックボックスを描画しようとして無残に失敗します:(、誰かがリストビューにチェックボックスを描画するために正しい方向に私を向けることができますか(コードはリストビューにチェックボックスを描画しません)。
リストビューはvsReportモードで、3つの列があり、3番目の列にチェックボックスを入れたいと思います。どちらがサードパーティコンポーネントを使用するかを提案しないでください。TlistViewコントロールを使用したいのですが。
更新1:値を設定するsertac推奨のおかげでDefaultDraw、チェックボックスが表示されますが、別の列はひどく見えます。

UPDATE 2、Andreasの提案に従って、リストビューは見栄えが良くなりましたが、ブラックボックスが表示されています。

procedure TForm15.ListView1CustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
var
h : HTHEME;
s : TSize;
r : TRect;
Rect : TRect;
i : Integer;
Dx : Integer;
begin
if (SubItem=2) then
begin
DefaultDraw:=False;
Rect :=Item.DisplayRect(drBounds);
Dx:=0;
for i := 0 to SubItem-1 do
Inc(Dx,Sender.Column[i].Width);
Rect.Left :=Rect.Left+Dx;
Rect.Right :=Rect.Left+Sender.Column[SubItem].Width;
FillRect(Sender.Canvas.Handle, Rect, GetStockObject(WHITE_BRUSH));
s.cx := GetSystemMetrics(SM_CXMENUCHECK);
s.cy := GetSystemMetrics(SM_CYMENUCHECK);
Dx := (Sender.Column[SubItem].Width-GetSystemMetrics(SM_CXMENUCHECK)) div 2;
if UseThemes then
begin
h := OpenThemeData(Sender.Handle, 'BUTTON');
if h <> 0 then
try
GetThemePartSize(h, Sender.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 + Dx;
r.Right := r.Left + s.cx;
DrawThemeBackground(h, Sender.Canvas.Handle, BP_CHECKBOX, IfThen(CompareText(Item.SubItems[SubItem-1],'True')=0, 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 + Dx;
r.Right := r.Left + s.cx;
DrawFrameControl(Sender.Canvas.Handle, r, DFC_BUTTON, IfThen(CompareText(Item.SubItems[SubItem-1],'True')=0, DFCS_CHECKED, DFCS_BUTTONCHECK));
end;
end;
end;
