【问题标题】:How do I get a list of control-panel items and then execute one?如何获取控制面板项目列表然后执行一个?
【发布时间】:2012-10-24 08:09:48
【问题描述】:

1。如何获取控制面板列表,包括它们的名称和图标,以便创建类似于“开始”菜单显示的菜单?

2。当我点击一个条目时,如何执行对应的控制面板?

顺便问一下,这种PopupMenu是用什么控件来做的?但它有右键单击事件。

更新:

我使用 PItemIDList 来获取一个文件夹:

var:
PIDL, TempPIDL: PItemIDList;
Path: array[0..MAX_PATH] of Char;
FI: SHFILEINFOW;
begin
SHGetSpecialFolderLocation(0, CSIDL_FAVORITES, PIDL);
SHGetPathFromIDList(PIDL , Path);
Memo1.Lines.Add(Path);
SHGetFileInfo(LPCTSTR(PIDL), 0, FI, SizeOf(FI), SHGFI_PIDL or SHGFI_DISPLAYNAME or SHGFI_ICON);
Memo1.Lines.Add(FI.szDisplayName);
Image1.Picture.Icon.Handle := FI.hIcon;

它显示正常,但是当我将 CSIDL_FAVORITE 更改为 CSIDL_CONTROLS 时,我总是得到错误。 这是获取控制面板项目的错误方法吗? 我还通过使用 CPL 使用另一种方法 复制自here
但它不能显示完整的项目。

【问题讨论】:

  • 我不明白这个问题。我想您是在问如何枚举控制面板中的所有项目,以及如何在菜单中显示它们。对吗?
  • 是的。对不起,英语不是我的强项

标签: delphi popupmenu control-panel


【解决方案1】:

您可以检查所有已注册小程序的注册表。
这描述了如何注册它们:http://msdn.microsoft.com/en-us/library/windows/desktop/bb757044.aspx
同样,您可以扫描注册表以检查已注册的小程序及其运行方法。

但是,在 64 位 Windows 上,您的 32 位应用程序将无法加载 64 位小程序,因此提取图标可能会很痛苦。我不知道您是否可以通过 64 位 DLL 调用带有 AsResourceLibrary 标志的 LoadLibraryEx 来仅提取图标。


另一种方法是使用 Windows 资源管理器命名空间。获取一些Shell 组件套件,它提供开放的虚拟路径,例如My ComputerMy Documents,而不是c:\ 等。控制面板有一个特殊的 GUID(我不记得了。但Microsoft TweakUI 工具可以使用该 GUID 在任何文件夹中创建控制面板)。您可能可以使用一些Shell UI将Control Panel特殊虚拟文件夹打开到ListView,然后枚举项目并提取相应的图片并将它们重新排列为菜单。然后执行可能会通过双击该 shell 列表视图中的项目来完成。

【讨论】:

  • LoadLibraryEx 和 LOAD_LIBRARY_AS_IMAGE_RESOURCE 适用于 64 位 dll
  • 我试过浏览FOLDERID_ControlPanel,但我不清楚如何获取控制面板项目的图标? IShellItemImageFacotory 总是返回 new document 图标; source code
  • 我决定试一试,以此作为对汇编程序的一种转移。无论如何,它的挑战似乎是找到将小程序呈现给控制面板的所有多种方式,然后扫描所有这些方式。这里提到了两个,然后我也知道还有两个或三个。很难全部抓住。
  • @Glenn1234 你可以回答并添加我们尚未列出的方法。备查。为什么不呢?
【解决方案2】:

控制面板小程序是位于系统文件夹中的 CPL 文件

EG : C:\Windows\system32

我的建议是列出这些文件,然后提取图标并获取它们的文件名

如果您对代码有问题,请在此处发布,以便我们提供帮助

CPL 文件只是 DLL 文件,它们可以包含多个小程序

在谷歌搜索后,我找到了这个教程:

http://delphi.about.com/od/kbwinshell/l/aa062403a.htm

【讨论】:

  • 它们可能位于 x86 上的三个文件夹中,而在 x64 上可能意味着甚至 4 个文件夹
  • @Arioch'这是为什么呢?它们与程序文件夹无关。
  • @opc0de \Windows,\Windows\System,\Windows\System32。在 Win64 上还会有 \Windows\SysWOW64。但正如你所记得的程序文件 - 是的,真的,你可以从任何文件夹注册小程序。这 4 个文件夹只是 Windows 在启动时搜索并隐式注册它们的地方。但是考虑像 Oracle Java 这样的程序 - 它完全将其 java.cpl 保留在 Program Files :-)
【解决方案3】:

在您的帮助下,我解决了这个问题!特别感谢大卫赫弗南

1.获取控制面板项我使用Windows Shell获取控制面板项,使用CPL文件获取不到完整项。

代码:

var
  psfDeskTop: IShellFolder;
  psfControl: IShellFolder;

  pidControl: PITEMIDLIST;
  pidChild: PITEMIDLIST;
  pidAbsolute: PItemIdList;

  pEnumList: IEnumIDList;
  celtFetched: ULONG;

  FileInfo: SHFILEINFOW;

begin

  OleCheck(SHGetDesktopFolder(psfDeskTop));
  OleCheck(SHGetSpecialFolderLocation(0, CSIDL_CONTROLS, pidControl));
  OleCheck(psfDeskTop.BindToObject(pidControl, nil, IID_IShellFolder, psfControl));
  OleCheck(psfControl.EnumObjects(0, SHCONTF_NONFOLDERS or SHCONTF_INCLUDEHIDDEN or SHCONTF_FOLDERS, pEnumList));

  while pEnumList.Next(1, pidChild, celtFetched) = 0 do
  begin

    pidAbsolute := ILCombine(pidControl, pidChild);
    SHGetFileInfo(LPCTSTR(pidAbsolute), 0, FileInfo, SizeOf(FileInfo), SHGFI_PIDL
      or SHGFI_DISPLAYNAME);
   // SHGetFileInfo can get name and icon 
   //Do something to save item name and icon

  end;

2。执行 必须使用ShellExecuteEx 来执行一个PIDL 项。

var 
ShExeInfo : SHELLEXECUTEINFO;

begin

ZeroMemory(@ShExeInfo, SizeOf(ShExeInfo));
    ShExeInfo.cbSize := SizeOf(ShExeInfo);
    ShExeInfo.lpVerb := 'Open';
    // control panel item's PIDL
    ShExeInfo.lpIDList := pidAbsolute;
    ShExeInfo.nShow := SW_SHOWNORMAL;
    ShExeInfo.fMask := SEE_MASK_IDLIST;
end

并使用

 ShellExecuteEx(@ShExeInfo);

最后再次感谢 David Heffernan。帮了我很多忙。

【讨论】:

    【解决方案4】:

    听从 Arioch 'The 的建议

    参考:http://www.geoffchappell.com/studies/windows/shell/shell32/classes/controlpanel.htm

    我想到的其他“二三法”在此详述:

    CONTROL.INI 文件的 [MMCPL] 部分,现在映射到 注册表项 HKEY_CURRENT_USER\Control Panel\MMCPL;

    注册表项 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Control Panel\CPLs;

    此外,还有详细的不加载列表:

    如果候选 CPL 模块的文件名显示为值,则该候选 CPL 模块将被拒绝 在以下任一注册表项中:

    HKEY_CURRENT_USER\Control Panel\don't load
    HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Control Panel\don't load
    

    如前所述,该项目的挑战是扫描所有适当的位置并以正确的方式获取数据以便能够对其采取行动。这是因为一些“较新”的设计控制面板项目(以及那里出现的 shell 文件夹,我不确定我是否发现了如何访问它们)是如何呈现的。我手头没有数据,但如果能进一步讨论,我可以复制一两个示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多