dessin d'une case à cocher dans un TListView
J'ai besoin de dessiner une case à cocher dans une colonne spécifique dans uneTListView
, j'ai donc vérifier cette question Comment puis-je configurer TListView avec des Cases à cocher dans seulement certaines colonnes?
et dans la accepté de répondre à suggérons d'utiliser la méthode décrite dans cette autre question Comment mettre une Case à cocher TStringGrid en Delphi?
, maintenant que le portage de code pour travailler avec une ListView je viens avec cela :
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;
mais j'échoue lamentablement échoué dans ma tentative de dessiner une case à cocher :(, quelqu'un peut me pointer dans la bonne direction pour dessiner la case à cocher dans la liste, (le code n'est pas de tirer la moindre case à cocher dans la liste).
La liste est en vsReport mode et a 3 colonnes, je veux mettre la case dans la troisième colonne. merci de ne pas proposer l'utilisation d'un troisième composant de partie, je veux utiliser le TlistView de contrôle.
Mise à JOUR de 1 : grâce à la sertac recomendattion réglage de la DefaultDraw
valeur maintenant les cases sont affichées, mais les autre colonnes semble moche.
Mise à JOUR 2 , à la suite de la Andreas suggestions de la liste maintenant, regardez mieux, mais toujours montré la boîte noire;
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;
Grâce Sertac maintenant, j'ai une avance.
Ma deuxième réponse résout tous les problèmes.
OriginalL'auteur Salvador | 2011-04-01
Vous devez vous connecter pour publier un commentaire.
Un moyen relativement simple de se débarrasser de ce bug est propriétaire de dessiner l'ensemble de l'objet. Ensemble
OwnerDraw := true
, retirez votreOnCustomDrawSubItem
routine, et ajouterExemple d'utilisation http://privat.rejbrand.se/listbugs.png
Le code ci-dessus besoins de plus de tests, mais c'est probablement dans la bonne direction. Maintenant, il est très tard, et je dois aller.
OriginalL'auteur Andreas Rejbrand
Tout d'abord, vous devez définir
DefaultDraw
àfalse
lors de l'élaboration de la colonne de cases à cocher ettrue
autrement, parce queDefaultDraw
signifie que la CLASSIFICATION de l'établissement, et non pas vous. Actuellement, vous faites le contraire.En outre, pour une raison étrange, le contrôle considère que le premier sous-élément à
SubItem = 1
, et le deuxième sous-élément àSubItem = 2
. Par conséquent, vous devez testerif SubItem = 2 then
à la place.[Bien sûr, cela implique des changements
]
Les rectangles noirs semblent être un bug quelque part dans l'union de la VCL et code Win32.
Non, je n'ai aucune idée. Il serait sans doute bien travailler pour propriétaire-dessiner l'ensemble de l'objet, mais qui ne devrait pas être nécessaire...
OriginalL'auteur Andreas Rejbrand
Sans complètement basculer à OwnerDraw, j'ai trouvé le suivant raisonnablement acceptable:
Utiliser le CustomDrawSubItem de routine de dessiner vos étiquettes à l'aide de "TextOut", par exemple:
ListView1.Toile.TextOut(2, y', 'Mon label');
Ce masque les boîtes noires, et vous pouvez voir vos étiquettes de texte. Toutefois, la sélection ne fonctionne pas sur le texte. Un petit prix à payer si, à mon avis.
OriginalL'auteur user2199822