2012-10-31 27 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