其他磁盘分区目录和文件是可以正常列举的,但对控制面板这个虚拟目录却不能正常列举,经过多种方式检查均找不出问题原因,现在将问题源码发出来,希望有人能够找出问题的原因和给出解决方案。
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, ActiveX, ShellAPI, ShlObj, ComObj,
  Vcl.StdCtrls;

procedure EnumControlPanelItems();
var
  controlPIDL, parentPIDL, pidlChild2: PItemIDList;
  shellFolder1, shellFolder2: IShellFolder;
  enumIDL1, enumIDL2: IEnumIDList;
  pidlSub1, pidlSub2: PItemIDList;
  dwFetched: DWORD;
  dName: String; // 对象显示名称
begin
  CoInitialize(nil);
  try
    // 获取控制面板PIDL
    SHGetSpecialFolderLocation(0, CSIDL_CONTROLS, controlPIDL);
    outputdebugstring(pwidechar('controlPIDL:' + inttostr(ILGetSize(controlPIDL))));

    // 绑定“控制面板”文件夹shellFolder1
    SHBindToParent(controlPIDL, IShellFolder, Pointer(shellFolder1), parentPIDL);
    // 获取控制面板枚举对象enumIDL1
    shellFolder1.EnumObjects(Application.Handle, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or SHCONTF_SHAREABLE, enumIDL1);
    // 这里可以正确列举控制面板第一级功能模块
    while enumIDL1.Next(1, pidlSub1, dwFetched) = S_OK do
    begin
      // 获取显示名
      dName := GetDisplayName(shellFolder1, pidlSub1);
      outputdebugstring(pwidechar(dName));

      // 错误原因可能是下面2个方法上,1:BindToObject,2:EnumObjects,可能是参数传递有问题

      // 绑定到第二级下级文件夹的 IShellFolder 接口
      shellFolder1.BindToObject(pidlSub1, nil, IID_IShellFolder, Pointer(shellFolder2));
      // OLECheck((SHBindToObject(shellFolder1, pidlSub1, nil, IID_IShellFolder, Pointer(shellFolder2))));

      // 获取第二级下级枚举对象enumIDL2
      shellFolder2.EnumObjects(Application.Handle, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or SHCONTF_SHAREABLE, enumIDL2);
      // 是这里不能正确列举第二级下级子项目,大多返回S_FALSE,很多子项都不能列举出来
      while enumIDL2.Next(1, pidlSub2, dwFetched) = S_OK do
      begin
        dName := GetDisplayName(shellFolder2, pidlSub2);
        outputdebugstring(pwidechar('      ' + dName + inttostr(ILGetSize(pidlSub2))));
        CoTaskMemFree(pidlSub2);
      end;

      CoTaskMemFree(pidlSub1);
    end;
    // 释放PIDL
    CoTaskMemFree(parentPIDL);
    CoTaskMemFree(controlPIDL);
  finally
    CoUninitialize;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  EnumControlPanelItems;
end;

下面给出执行源码输出结果
Debug Output: 系统和安全 Process Project1.exe (23360)
Debug Output: 网络和 Internet Process Project1.exe (23360)
Debug Output: 硬件和声音 Process Project1.exe (23360)
Debug Output: 程序 Process Project1.exe (23360)
Debug Output: 用户帐户 Process Project1.exe (23360)
Debug Output:       邮件176 Process Project1.exe (23360)
Debug Output: 外观和个性化 Process Project1.exe (23360)
Debug Output: 时钟和区域 Process Project1.exe (23360)
Debug Output: 轻松使用 Process Project1.exe (23360)
Debug Output: 所有控制面板项 Process Project1.exe (23360)
Debug Output:       Flash Player174 Process Project1.exe (23360)
Debug Output:       邮件176 Process Project1.exe (23360)
Debug Output:       360强力卸载156 Process Project1.exe (23360)
Debug Output:       128 Process Project1.exe (23360)
Debug Output: