desenhando uma caixa de seleção em um TListView
Eu preciso desenhar uma caixa de seleção em uma coluna específica em umTListView
, então eu verifico esta perguntaHow can I setup TListView with CheckBoxes in only certain columns?
e, na resposta aceita, sugira usar o método descrito nesta outra perguntaHow to set a Checkbox TStringGrid in Delphi?
, agora portando esse código para trabalhar com um ListView, eu venho com isso:
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;
mas falho miseravelmente na minha tentativa de desenhar uma caixa de seleção :(, alguém pode me apontar na direção certa para desenhar a caixa de seleção na lista de exibição (o código não desenha nenhuma caixa de seleção na lista de exibição
O listview está no modo vsReport e tinha 3 colunas, quero colocar a caixa de seleção na terceira coluna. por favor, não sugira que use um componente de terceiros, eu quero usar o controle TlistView.
UPDATE 1: graças à recomendação sertac configurando oDefaultDraw
value agora as caixas de seleção são mostradas, mas as outras colunas parecem horrívei
UPDATE 2, seguindo as sugestões de Andreas, a listview agora parece melhor, mas ainda mostra a caixa preta;
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;