Почему нельзя получить название панели управления?

Я использую 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 показным. Почему нельзя получить название панели управления?

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;
Другие вопросы по тегам