Как получить список элементов панели управления, а затем выполнить его?

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 отсюда
Но он не может отображать полные элементы.

4 ответа

Решение

В твоей помощи я решил проблему! Особая благодарность Дэвиду Хеффернану

1.Получить элементы панели управления. Я использую оболочку Windows для получения элементов панели управления, файлы 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);

Наконец, еще раз спасибо Дэвиду Хеффернану. помогите мне много

Вы можете проверить реестр для всех зарегистрированных апплетов.
Здесь описано, как их зарегистрировать: http://msdn.microsoft.com/en-us/library/windows/desktop/bb757044.aspx
Точно так же вы можете сканировать реестр, чтобы проверить уже зарегистрированные апплеты и методы их запуска.

Однако в 64-битных окнах могут быть 64-битные апплеты, которые 32-битное приложение не сможет загрузить, поэтому извлечение значка может быть проблематичным. Я не знаю, можете ли вы позвонить LoadLibraryEx с флагом AsResourceLibrary над 64-битными DLL для простого извлечения иконок.


Другим подходом было бы использование пространств имен проводника Windows. Получить немного Shell набор компонентов, который обеспечивает открытие виртуальных путей, таких как My Computer а также My Documents скорее, чем c:\ и тому подобное. Панель управления имеет специальный GUID (что я не помню, право. Но Microsoft TweakUI инструмент может создать панель управления в любой папке, используя этот GUID). Вы можете, вероятно, использовать какой-то интерфейс Shell, чтобы открыть Control Panel специальная виртуальная папка в виде ListView, затем получите, затем перечислите пункты и извлеките соответствующие изображения и перегруппируйте их как меню. Тогда выполнение, вероятно, будет выполнено в виде двойного щелчка по элементу в этом списке оболочки.

Апплеты панели управления - это файлы CPL, которые находятся в вашей системной папке.

Например: C:\Windows\system32

Я предлагаю перечислить эти файлы, а затем извлечь значки и получить их имя файла

Если у вас возникли проблемы с кодом, разместите его здесь, чтобы мы могли помочь

CPL-файлы - это просто DLL-файлы, они могут содержать несколько апплетов.

После поиска в Google я нашел этот урок:

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

По предложению Ариоха

Ссылка: http://www.geoffchappell.com/studies/windows/shell/shell32/classes/controlpanel.htm

Другие "два или три метода", о которых я думал, подробно описаны здесь:

раздел [MMCPL] файла CONTROL.INI, в настоящее время сопоставленный с разделом реестра HKEY_CURRENT_USER\Control Panel\MMCPL;

раздел реестра HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ Панель управления \CPL;

Также подробно описаны списки "не загружать":

Подходящий модуль CPL отклоняется, если его имя файла отображается в виде значения в одном из следующих разделов реестра:

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

Как было сказано, задача этого проекта заключается в том, чтобы охватить все правильные места и получить данные правильным образом, чтобы иметь возможность действовать в соответствии с ними. Это из-за того, что представлены некоторые из "более новых" элементов панели управления дизайном (и папки там, которые появляются там, я не совсем уверен, что я обнаружил, как получить к ним доступ). У меня нет под рукой данных, но я могу скопировать один или два примера, если это будет способствовать обсуждению.

Другие вопросы по тегам