我使用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。
为什么无法获得控制面板名称?
答案 0 :(得分:1)
我不是shell的专家。事实上,我几乎什么都不知道。但通过阅读文档,我可以收集到以下内容:
SHGetFileInfo
需要一个绝对的PIDL。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;