#listview #delphi #pn& #vcl #vcl-styles
#listview #delphi #pn& #vcl #vcl-styles
Вопрос:
Я использую следующий код для рисования значков в подпункте ListView из списка изображений PNG в событии «CustomDrawSubItem». Когда я выбираю строку или изменяю цвет кисти строки в «CustomDrawItem», этот цвет выделения вырезается из ячейки подпункта. Как я могу это исправить, чтобы цвет «фона» заполнял прозрачную область?
Файл DPR
pro&ram Project1;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1},
Vcl.Themes,
Vcl.Styles;
{$R *.res}
be&in
Application.Initialize;
Application.MainFormOnTaskbar := True;
TStyleMana&er.TrySetStyle('Glow');
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Единица измерения 1
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messa&es, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialo&s, System.Ima&eList, Vcl.Im&List,
Vcl.ComCtrls, Winapi.CommCtrl, Pn&Ima&eList;
type
TForm1 = class(TForm)
ListView1: TListView;
Pn&Ima&eList1: TPn&Ima&eList;
procedure ListView1CustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Inte&er; State: TCustomDrawState; var DefaultDraw: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure DrawPicOnListViewSubItem(LV: TListView; Item: TListItem; SubItem: Lon∬ Im&ListHandle: THandle; IconIndex,Im&ListWidth: Word); inline;
Var R: TRect;
x: Lon∬
be&in
R := Item.DisplayRect(drBounds);
for x := 0 To SubItem - 1 Do
R.Left := R.Left LV.Columns[x].Width;
R.Top := R.Top 3;
If Item <&&t; nil then be&in
R.Left := R.Left (LV.Columns[SubItem].Width - Im&ListWidth) div 2;
R.Ri&ht := R.Left Im&ListWidth;
// Ensure that the items are drawn transparently
SetBkMode(LV.Canvas.Handle, TRANSPARENT);
ListView_SetTextBkColor(LV.Handle, CLR_NONE);
ListView_SetBKColor(LV.Handle, CLR_NONE);
Ima&eList_Draw(Im&ListHandle, IconIndex, LV.Canvas.Handle, R.Left - 2, R.Top, ILD_NORMAL);
end;
end;
procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Inte&er; State: TCustomDrawState; var DefaultDraw: Boolean);
be&in
if SubItem = 1 then be&in
DrawPicOnListViewSubItem(ListView1, Item, SubItem, Pn&Ima&eList1.Handle, 0, 16);
DefaultDraw := False;
end;
end;
end.
DFM-файл Form1
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHei&ht = 565
ClientWidth = 954
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Hei&ht = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHei&ht = 13
object ListView1: TListView
Left = 0
Top = 0
Width = 954
Hei&ht = 565
Ali&n = alClient
Columns = <
item
Width = 200
end
item
end
item
Width = 200
end
item
end
item
Width = 200
end&&t;
Items.ItemData = {
052F0000000100000000000000FFFFFFFFFFFFFFFF03000000FFFFFFFF000000
0000001890633600B8351F3D0000391F3DFFFFFFFFFFFF}
RowSelect = True
SmallIma&es = Pn&Ima&eList1
TabOrder = 0
ViewStyle = vsReport
OnCustomDrawSubItem = ListView1CustomDrawSubItem
end
object Pn&Ima&eList1: TPn&Ima&eList
Pn&Ima&es = <
item
Back&round = clWindow
Name = 'cross'
Pn&Ima&e.Data = {
89504E470D0A1A0A0000000D49484452000000100000001008060000001FF3FF
610000001974455874536F6674776172650041646F626520496D616765526561
647971C9653C000001CB4944415478DAAD933F4842411CC7BF8719D890363455
342946E349D1D09F2DA7245C8AA2A1A11A1A9C8CA0A684701197201A45A8A6A0
E951434343448A43E8524BA20922096543F6ECF5BB7BA73CCCCD1E1CC7BDDFF7
FBB97BBFEF3B661806BA79D8BF004E1903A3850DF0D314A1B1D700345D897A3A
D4C4B6CBE4B502A4606967879F45A369212480A600B2B6180AF18B785CD608A0
B5004926F6476A251CE6B95C0E1E8F07E7B19814AA4344E6D7D779B95C86CBE5
C24D32296ABED526206102FC448D04363779269381D7EBC555222184980C0478
A95482D3E9C4E3F5759A99606DCD0A10DFA42BC85C30C89F9F9EA4A156ABA158
28C0E170E0239F9766FA244D6CF907F04DA3A120236E377FAB54E4F96D361BDE
2B1569A6666A76D17D2BE050A5D0AB1AC6046070903774BD15D76BB59A365463
EBB4161BEEB603ECCA3C3E30C03B659E55906F15633B4046356D31DF9241CC1D
DEC9185B800315E38245784942D56D71DC487B4DC4B8DF048C12608A4E3044C2
0D129E90A048E67BF5234D76A8DD51EDA509608C0D93AECF07CC8C035B39E0E8
814E4BEFBE68FC88FE4E00B363C07616384E99B54FF2169A807EB38732089869
8ADF42CE867915E495E8517591789DBCEF5DDFC65FB962FBE11CAE7AA4000000
0049454E44AE426082}
end&&t;
Left = 248
Top = 112
Bitmap = {}
end
end
PNGIma&eList: https://&ithub.com/TurboPack/PNGComponents
Комментарии:
1. Я собирался протестировать вашу проблему, когда обнаружил, что ваш код не имеет ничего общего с
OnCustomDrawSubItem()
событием. Как именно вы называете это своим кодомDrawPicOnListViewSubItem()
? Что такоеdrBounds
, откуда берется его значение. Короче говоря, пожалуйста, предоставьте полный пример кода, включая соответствующие части.dfm
, чтобы создать надлежащий тест.2. Вы правы. Приведен полный пример.
Ответ №1:
Основная ошибка в вашем коде заключалась в том, что вы не нарисовали фон ( clHi&hLi&ht
цвет) для выбранной строки и для подпункта с изображением.
Кроме того, я удалил всю DrawPicOnListViewSubItem()
процедуру, поскольку смог сократить ее всего до нескольких строк. Я думаю, что был какой-то пробный код.
ListView1CustomDrawSubItem()
Процедура теперь выглядит следующим образом:
procedure TForm1.ListView1CustomDrawSubItem(Sender: TCustomListView;
Item: TListItem; SubItem: Inte&er; State: TCustomDrawState;
var DefaultDraw: Boolean);
var
R: TRect;
C: TCanvas;
be&in
ListView_GetSubItemRect(Sender.Handle, Item.Index, SubItem, LVIR_BOUNDS, @R);
C := Sender.Canvas;
if cdsSelected in State then
be&in
C.Brush.Color := clHi&hLi&ht;
C.FillRect(R);
end;
if SubItem = 1 then
be&in
Ima&eList_Draw(Pn&Ima&eList1.Handle, 0, C.Handle, R.Left (R.Width-Pn&Ima&eList1.Width) div 2, R.Top, ILD_TRANSPARENT);
DefaultDraw := False;
end;
end;
Комментарии:
1. Спасибо, это очень хорошо работает с моим базовым примером, но у него есть некоторые проблемы с OwnerData, из-за чего я на самом деле использую LV в основном приложении. Отредактировал вопрос и код.
2. @hikari Пожалуйста, не меняйте свой вопрос, как только получите ответы. Опубликуйте новый вопрос, если ваша фактическая проблема так сильно отличается от вашего первоначального вопроса. То, что вы сейчас запрашиваете, требует использования
StyleServices
и является другим вопросом. Пожалуйста, верните свой вопрос к тому, что было, когда я отвечал.3. Спасибо! @hikari Я размещаю следующий URL-адрес на случай, если вы не видели эту статью об использовании
StyleServices
дляOwnerDraw
listview. В настоящее время я работаю над этим (насколько позволяет время) и, возможно, смогу ответить на вопросы об этом в будущем.4. Спасибо, я также следил за этим блогом, в этой демонстрации есть очень полезный код для реализации того, что мне нужно, с некоторыми изменениями я смог адаптировать его к своему приложению.