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复制 但它无法显示完整的项目。
答案 0 :(得分:3)
您可以在注册表中查看所有已注册的小程序
这描述了如何注册它们:http://msdn.microsoft.com/en-us/library/windows/desktop/bb757044.aspx
同样,您可以扫描注册表以检查已注册的applet及其运行方法。
但是在64位窗口上会出现32位应用程序无法加载的64位小程序,因此提取图标可能会很麻烦。我不知道你是否可以用64位DLL上的AsResourceLibrary标志调用LoadLibraryEx
来进行图标提取。
另一种方法是使用Windows资源管理器命名空间。获取一些Shell
组件套件,提供开放虚拟路径,如My Computer
和My Documents
,而不是c:\
等。控制面板有一个特殊的GUID(我不记得。)Microsoft TweakUI
工具可以使用该GUID在任何文件夹中创建控制面板。您可以使用一些Shell UI将Control Panel
特殊虚拟文件夹打开为ListView
种类,然后获取枚举项目并提取相应的图片并将其重新排列为菜单。然后执行可能是双击该shell列表视图中的项目。
答案 1 :(得分:2)
控制面板小程序是位于系统文件夹中的CPL文件
EG:C:\ Windows \ system32
我的建议是列出这些文件,然后提取图标并获取其文件名
如果您遇到问题,请在此处发布,以便我们提供帮助
CPL文件只是DLL文件,它们可以包含多个小程序
谷歌搜索后,我找到了这个教程:
答案 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文件夹,我不确定我是否发现了如何访问这些文件夹)的呈现方式。我没有方便的数据,但如果能够进一步讨论,我可以复制一两个例子。