为什么无法获得控制面板名称?

时间:2012-10-31 07:56:50

标签: delphi windows-shell controlpanel

我使用Shell获取控制面板

代码:

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。 为什么无法获得控制面板名称?

enter image description here

1 个答案:

答案 0 :(得分:1)

我不是shell的专家。事实上,我几乎什么都不知道。但通过阅读文档,我可以收集到以下内容:

  1. SHGetFileInfo需要一个绝对的PIDL。
  2. IEnumIDList枚举相对PIDL。
  3. 因此,您的代码必然会失败。也许还有其他错误。我不知道。

    无论如何,我认为解决问题的简单方法是使用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;