2012-10-31 22 views
1

我使用殼牌得到控制面板爲什麼無法獲取控制面板名稱?

代碼:

procedure TForm1.FormCreate(Sender: TObject); 
var 
    psfDeskTop: IShellFolder; 
    psfWork: IShellFolder; 
    pidworkDir: PITEMIDLIST; 
    pidChild: PITEMIDLIST; 
    pEnumList: IEnumIDList; 
    celtFetched: ULONG; 
    FileInfo: SHFILEINFOW; 

begin 

    Memo1.Clear; 
    SHGetDesktopFolder(psfDeskTop); 
    //control panel 
    SHGetSpecialFolderLocation(0, CSIDL_CONTROLS, pidworkDir); 
    psfDeskTop.BindToObject(pidworkDir, nil, IID_IShellFolder, psfWork); 
    psfWork.EnumObjects(0, SHCONTF_NONFOLDERS or SHCONTF_FOLDERS or SHCONTF_INCLUDEHIDDEN, pEnumList); 
    while pEnumList.Next(1, pidChild, celtFetched) = 0 do 
    begin 

    SHGetFileInfo(LPCTSTR(pidChild), 0, FileInfo, SizeOf(FileInfo), SHGFI_PIDL 
     or SHGFI_TYPENAME or SHGFI_DISPLAYNAME or SHGFI_USEFILEATTRIBUTES); 

    Memo1.Lines.Add(FileInfo.szDisplayName + ' +'); 

    end; 
end; 

不能得到FileInfo.szDisplayName,我只是用' +'使Memo1 dispaly。 爲什麼無法獲取控制面板名稱?

enter image description here

+0

那麼,第一步是添加錯誤檢查代碼。做到這一點,並以結果更新問題。 –

+0

@DavidHeffernan如何在代碼中添加錯誤檢查? – Hanlin

+0

閱讀每個API函數的文檔,並檢查文檔中描述的錯誤的返回值。在你檢查錯誤之前詢問這個問題是毫無意義的。 –

回答

1

我不是在外殼上的專家。事實上,我幾乎什麼都不知道。但通過閱讀文檔,我可以收集以下內容:

  1. SHGetFileInfo預計絕對PIDL。
  2. IEnumIDList枚舉相對PIDL。

因此,你的代碼必然會因此而失敗。也許還有其他的錯誤。我不知道。

無論如何,我認爲最簡單的方式來解決這個問題是使用IShellFolder.GetDisplayNameOf,以獲得您所需要的名字:

uses 
    ..., ShLwApi, ... 
.... 
var 
    StrRetName: TStrRet; 
    Name: PChar; 
.... 
while pEnumList.Next(1, pidChild, celtFetched) = 0 do 
begin 
    OleCheck(psfWork.GetDisplayNameOf(pidChild, SHGDN_NORMAL, StrRetName)); 
    OleCheck(StrRetToStr(@StrRetName, nil, Name)); 
    Memo1.Lines.Add(Name); 
    CoTaskMemFree(Name); 
    CoTaskMemFree(pidChild); 
end; 
+0

它的作品謝謝 – Hanlin