Вопрос

1. How can I get a list of control panels, including their names and icons, so I can create a menu like the one the Start menu shows?

control panel fly-out from the Start menu

2. When I click an entry, how do I execute the corresponding control panel?

By the way, what controls are used to do this kind of PopupMenu? But it has right click event.

update :

I use PItemIDList to get a Folder:

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;

it display normal , but when I change CSIDL_FAVORITE to CSIDL_CONTROLS , I always get error . this is a wrong way to get controls panel items ? I also use another method by use CPL copy from here
But it can not display complete Items.

Это было полезно?

Решение 3

In your help, I solved the problem! Special thanks to David Heffernan

1.Get control panel items I use Windows Shell to get control panel items , use CPL files not get complete items .

Code :

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. Execute must have to use ShellExecuteEx to execute a PIDL item.

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

and use

 ShellExecuteEx(@ShExeInfo);

Finally thanks to David Heffernan again. help me a lot.

Другие советы

You can check the registry for all registered applets.
This describes how to register them: http://msdn.microsoft.com/en-us/library/windows/desktop/bb757044.aspx
Similarly you may scan registry to check already registered applets and their run methods.

However on 64-bit windows there would be 64-bit applets that your 32-bit application would not be able to load, so extracting icon might be a pain. I don't know if you can call LoadLibraryEx with AsResourceLibrary flag over 64-bit DLLs for mere icon extraction though.


Another approach would be using Windows explorer namespaces. Get some Shell component suite that provides opening virtual paths like My Computer and My Documents rather than c:\ and such. Control Panel has a special GUID (that i do not remember right of. But Microsoft TweakUI tool can create Control Panel in any folder using that GUID). You can probably use some Shell UI to open Control Panel special virtual folder into kind of ListView , then get then enumerate items and extract correspondent pictures and re-arrange them as menu. Then executing would be probably done as double-click over item in that shell listview.

Control panel applets are CPL files that are located in your system folder

EG : C:\Windows\system32

My suggestion is to list those files and then extract icons and get their file name

If you have trouble with the code post it here so that we can help

CPL files are just DLL files they can contain multiple applets

After a google search I found this tutorial :

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

Following the suggestion of Arioch 'The

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

The other "two or three methods" I was thinking of are detailed there:

the [MMCPL] section of the CONTROL.INI file, nowadays mapped to the registry key HKEY_CURRENT_USER\Control Panel\MMCPL;

the registry key HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Control Panel\CPLs;

Also, detailed there as well are the don't load lists:

A candidate CPL module is rejected if its filename appears as a value in either of the following registry keys:

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

Like was said, the challenge of this project is sweeping all the proper locations and getting the data in the right way to be able to act on it. This is because of how a few of the "newer" design control panel items (and shell folders that appear there, I'm not really sure I discovered how to access those yet) are presented. I don't have the data handy, but I can copy an example or two in if it would further the discussion.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top