如何获取控制面板项目列表然后执行一个?

时间:2012-10-24 08:09:49

标签: delphi popupmenu control-panel

1。如何获取控制面板列表,包括其名称和图标,以便创建一个菜单,如“开始”菜单所示?

control panel fly-out from the Start menu

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复制 但它无法显示完整的项目。

4 个答案:

答案 0 :(得分:3)

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

但是在64位窗口上会出现32位应用程序无法加载的64位小程序,因此提取图标可能会很麻烦。我不知道你是否可以用64位DLL上的AsResourceLibrary标志调用LoadLibraryEx来进行图标提取。


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

答案 1 :(得分:2)

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

EG:C:\ Windows \ system32

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

如果您遇到问题,请在此处发布,以便我们提供帮助

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

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

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

答案 2 :(得分:2)

在你的帮助下,我解决了这个问题!特别感谢David Heffernan

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。帮助我很多。

答案 3 :(得分:0)

遵循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模块的文件名显示为值,则会被拒绝   在以下任一注册表项中:

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

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