Исходя из 'TCustomTreeView', TShellTreeView
поддерживает изображения из коробки. ImageList
может быть присвоено его свойству Images
, а в его событии OnGetImageIndex
может быть указан индекс изображения в списке для соответствующего узла.
procedure TForm1.ShellTreeView1GetImageIndex(Sender: TObject; Node: TTreeNode);
begin
if TShellFolder(Node.Data).DisplayName = 'RAD Studio' then
Node.ImageIndex := 2;
end;
Недостатком является то, что все узлы должны будут использовать изображения в списке изображений, то есть не будет изображений из списка системных изображений. Приведенный ниже пример демонстрирует, как системные образы могут быть получены для узлов, которые не будут настроены. Он использует пользовательский образ для папки 'RAD Studio' в личной папке и использует системные образы для всех других узлов. ImageList1
содержит наши пользовательские изображения, ImageList2
- это то, что назначено свойству 'Images' в ShellTreeView.
type
TForm1 = class(TForm)
[...]
private
FShellImageList: THandle;
[...]
uses
shellapi, shellctrls, commctrl;
procedure TForm1.FormCreate(Sender: TObject);
var
FileInfo: TSHFileInfo;
ImageWidth, ImageHeight: Integer;
begin
ShellTreeView1.Root := 'rfPersonal';
FShellImageList := SHGetFileInfo('C:\', 0, FileInfo, SizeOf(FileInfo),
SHGFI_SYSICONINDEX or SHGFI_SMALLICON); //'//(pop SO formatting)
ImageList_GetIconSize(FShellImageList, ImageWidth, ImageHeight);
ImageList2.Width := ImageWidth;
ImageList2.Height := ImageHeight;
// Arbitrary count hopefully sufficient enough to be able to hold
// system images. Note that this is a proof of concept, not to be
// intended to be a working design.
ImageList_SetImageCount(ImageList2.Handle, 255);
// Make sure the width/height of ImageList1 is the same.
// Set its size, populate, stretchdraw do whatever necessary..
end;
function GetShellImage(PIDL: PItemIDList; Open: Boolean): Integer;
var
FileInfo: TSHFileInfo;
Flags: Integer;
begin
Flags := SHGFI_PIDL or SHGFI_SYSICONINDEX or SHGFI_SMALLICON;
if Open then Flags := Flags or SHGFI_OPENICON;
SHGetFileInfo(PChar(PIDL), 0, FileInfo, SizeOf(FileInfo), Flags);
Result := FileInfo.iIcon;
end;
procedure TForm1.ShellTreeView1GetImageIndex(Sender: TObject; Node: TTreeNode);
var
ImageIndex, SelectedIndex: Integer;
Icon: TIcon;
begin
if TShellFolder(Node.Data).DisplayName = 'RAD Studio' then begin
Icon := TIcon.Create;
try
ImageList1.GetIcon(0, Icon);
ImageIndex := ImageList_AddIcon(ImageList2.Handle, Icon.Handle);
ImageList1.GetIcon(1, Icon);
SelectedIndex := ImageList_AddIcon(ImageList2.Handle, Icon.Handle);
finally
Icon.Free;
end;
end else begin
ImageIndex := GetShellImage(TShellFolder(Node.Data).AbsoluteID, False);
SelectedIndex := GetShellImage(TShellFolder(Node.Data).AbsoluteID, True);
ImageList_ReplaceIcon(ImageList2.Handle, ImageIndex,
ImageList_GetIcon(FShellImageList, ImageIndex, 0));
ImageList_ReplaceIcon(ImageList2.Handle, SelectedIndex,
ImageList_GetIcon(FShellImageList, SelectedIndex, 0));
end;
Node.ImageIndex := ImageIndex;
Node.SelectedIndex := SelectedIndex;
end;
Как прокомментировано в коде, это не следует принимать за работающий дизайн; Вместо списка изображений, имеющего много неиспользуемых изображений, можно использовать какой-то вид поиска, который соответствует «индексу изображения» и «системному индексу списка изображений».