Search code examples
delphipopupmenucontrol-panel

How do I get a list of control-panel items and then execute one?


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.


Solution

  • 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.