2010-08-19 91 views
2

NetBeans IDE中的「打開項目...」對話框中有一個很好的功能(請參閱下圖),該對話框使用文件夾符號的自定義圖標,具體取決於該文件夾中的項目類型。如何在「瀏覽文件夾」對話框中使用自定義圖標?

例如,如果一個文件夾包含一個pom.xml文件,將出現Maven項目符號。

也許有也是在Windows標準對話框或可用於覆蓋默認的文件夾圖標的殼視圖控制的擴展點。

所有的解決方案,我知道到目前爲止需要一個全系統的變化,但也有其不會對系統的修改和只對當前應用程序有效的解決方案?

alt text

更新:你會建議爲起點,自定義對話框,VCL組件,我可以使用TShellTreeView或TcxShellTreeView?

+0

TShellTreeView有一個'Images'屬性 - 可以分配一個ImageList,還有一個'OnGetImageIndex'屬性。 (不知道TcxShellTreeView)。 – 2010-08-20 20:18:08

+0

@Sertac:如果你發佈這個答案,我會接受它:) – mjn 2010-08-21 06:47:24

+0

完成。不知道這是否是問題的確切答案。 – 2010-08-21 16:58:56

回答

2

從「TCustomTreeView」降序,TShellTreeView對圖像開箱即用的支持。可以將ImageList分配給它的Images屬性,並在其OnGetImageIndex事件中爲相應節點提供列表中圖像的索引。

​​


這方面的一個缺點是,所有的節點將在圖像列表使用的圖片,那是不會有從系統圖像列表的圖像。以下示例演示瞭如何爲不會自定義的節點檢索系統映像。它爲個人文件夾中的'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

IShellIconOverlayIShellIconOverlayIdentifier接口用於構建覆蓋圖標外殼擴展,這些擴展是系統範圍不是每個應用程序,在Delphi中,兩個接口都存在於ShlObj單元中。

檢查這個環節爲例

UPDATE

我覺得至極張貼在你的問題在NetBeans IDE對話框,得出自己的對話框使用自定義圖標和標準控件。您可以使用標準的vcl控件獲得相同的效果,構建自己的對話框。

+0

該示例說我必須在註冊表中註冊圖標疊加處理程序 - 因此它看起來像疊加層只能用於具有這些接口的當前應用程序才能定義? – mjn 2010-08-19 07:05:39

+0

@mjustin,這些接口用於Windows外殼擴展,因此它們是系統範圍的。 – RRUZ 2010-08-19 07:10:22

相關問題