NetBeans IDE中的“打开项目...”对话框(见下图)中有一个很好的功能,它根据文件夹中的项目类型使用文件夹符号的自定义图标。
例如,如果文件夹包含pom.xml文件,则会显示Maven项目符号。
也许Windows标准对话框或shell视图控件中还有一个扩展点,可用于覆盖默认文件夹图标。
到目前为止,我所知道的所有解决方案都需要进行全系统的更改,但是还有一个解决方案可以在没有系统修改的情况下工作,仅适用于当前的应用程序吗?
更新:您建议将哪个VCL组件作为自定义对话框的起点,我可以使用TShellTreeView或TcxShellTreeView吗?
答案 0 :(得分:2)
从'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
是分配给“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;
如代码中所述,不应将其用于工作设计;可以使用某种与“图像索引”和“系统图像列表索引”匹配的查找,而不是具有大量未使用图像的图像列表。
答案 1 :(得分:1)
IShellIconOverlay和IShellIconOverlayIdentifier接口用于构建覆盖图标外壳扩展,这些扩展是系统范围的,不是每个应用程序,在delphi中,两个接口都存在于ShlObj单元中。
查看此链接以获取示例
<强>更新强>
我认为在您的问题中发布了Netbeans IDE对话框,使用自定义图标和标准控件绘制自己的对话框。您可以使用标准vcl控件获得相同的效果来构建自己的对话框。