Место хранения желто-синего значка щита


Где в Windows хранится этот значок Желто-Синий Значок Безопасности Windows? Мне нужно использовать его в эмуляции TaskDialog для XP, и мне трудно его отследить.

Это не в shell32.dll, проводник.exe, ieframe.dll или wmploc.dll (поскольку они содержат много иконок, обычно используемых в Windows).

Править: Для уточнения я эмулируюопределенный тип диалога в XP. Иконы (скорее всего) там нет. Поэтому я хочу извлечь его из библиотеки, которая содержит его в Windows 7. Я расширяя существующую реализацию этой эмуляции и хотите предоставить полный набор функций.

4 9

4 ответа:

Я хотел указать на это прямо.

Предполагается, что вы поместите щит на элементы пользовательского интерфейса, которые вызовут повышение: MSDN: Шаг 4: измените свой пользовательский интерфейс для совместимости с UAC.

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

Microsoft предоставляет несколько поддерживаемые (и, следовательно, гарантированные) способы, которыми вы можете получить значок щита во время выполнения:

  • Добавить значок щита в пользовательский интерфейс?:

    • Извлеките маленькую иконку

      SHSTOCKICONINFO sii;
      sii.cbSize = sizeof(sii);
      SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICON | SHGSI_SMALLICON, &sii);
      hiconShield  = sii.hIcon;
      
    • Извлеките большой значок

      SHSTOCKICONINFO sii;
      sii.cbSize = sizeof(sii);
      SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICON | SHGSI_LARGEICON, &sii);
      hiconShield  = sii.hIcon;
      
    • Извлеките иконку нестандартного размера

      SHSTOCKICONINFO sii;
      sii.cbSize = sizeof(sii);
      SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICONLOCATION, &sii);
      hiconShield  = ExtractIconEx(sii. ...);
      
  • Добавить значок щита к кнопке

    Button_SetElevationRequiredState(hwndButton, TRUE);
    

В статье забыли упомянуть LoadIcon:

hIconShield = LoadIcon(0, IDI_SHIELD);

Хотя LoadIcon был "заменен" на LoadImage:

hIconShield = LoadImage(0, IDI_SHIELD, IMAGE_ICON, desiredWith, desiredHeight, LR_SHARED); //passing LR_SHARED causes size to be ignored. And you must pass LR_SHARED

Загрузка нужного размера-избегая общих изображений

Чтобы избежать загрузки "общей" версии значка, вы должны загрузить значок непосредственно из файла.

Мы все знаем, что щит существует в user32.dll как идентификатор ресурса 106:

| Icon             | Standard Icon ID  | Real Resource ID |
|------------------|-------------------|------------------|
| IDI_APPLICATION  | 32512             | 100              |
| IDI_QUESTION     | 32514             | 102              |
| IDI_WINLOGO      | 32517             | 105              |
| IDI_WARNING      | 32515             | 101              |
| IDI_ERROR        | 32513             | 103              |
| IDI_INFORMATION  | 32516             | 104              |
| IDI_SHIELD       | 32518             | 106              |
Это было недокументированное заклинание.

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

TSHStockIconInfo sii;
ZeroMemory(@sii, SizeOf(sii));
sii.cbSize := SizeOf(sii);
SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICONLOCATION, {var}sii);

В результате чего:

  • sii.szPath : C:\WINDOWS\System32\imageres.dll
  • sii.iIcon : -78

Вы можете загрузить это изображение для нужного вам размера, используя LoadImage:

HMODULE hmod := LoadLibrary(sii.szPath);
Integer nIconIndex := Abs(sii.iIcon); //-78 --> 78
ico = LoadImage(hmod, MAKEINTRESOURCE(nIconIndex), IMAGE_ICON, 256, 256, 0);

Еще один немного более простой способ-использовать SHDefExtractIcon:

HICON GetStockIcon(DWORD StockIconID, Integer IconSize)
{
    HRESULT hr;

    TSHStockIconInfo sii;
    ZeroMemory(@sii, SizeOf(sii));
    sii.cbSize := SizeOf(sii);
    hr = SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICONLOCATION, {var}sii);
    OleCheck(hr);

    HICON ico;
    hr = SHDefExtractIcon(sii.szPath, sii.iIcon, 0, ref ico, null, IconSize);
    OleCheck(hr);

    return ico;
}

Он выполняет загрузку за вас и обрабатывает отрицательный индекс значка (и тайный смысл, который имеет):

HICON shieldIcon = GetStockIcon(SIID_SHIELD, 256);

Лично я затем использую WIC, чтобы обернуть это в IWICBitmap:

IWICBitmap GetStockWicBitmap(DWORD StockIconID, Integer IconSize)
{
   HICON ico = GetStockIcon(StockIconID, IconSize);

   IWICBitmap bitmap;
   IWICImagingFactory factory = new WICImagingFactory();
   HRESULT hr = factory.CreateBitmapFromHICON(ico, out bitmap);
   OleCheck(hr);

   return bitmap;
}

И так:

IWICBitmap bmp = GetStockWicBitmap(SIID_SHIELD, 256);
Теперь, когда у вас есть растровое изображение, во время выполнения, делайте с ним все, что хотите.

Малые и большие

Проблема с ExtractIconEx заключается в том, что вы снова застряли с двумя размерами оболочки:

  • "маленький" (то есть GetSystemMetrics(SM_CXSMICON))
  • "Большой" (то есть GetSystemMetrics(SM_CXICON))

Загрузка иконки-это то, что является довольно темным искусством в Windows :

  • LoadIcon
  • LoadImage
  • LoadImage(..., LR_SHARED)
  • ExtractIcon
  • ExtractIconEx
  • IExtractImage
  • SHDefExtractIcon
  • SHGetFileInfo(..., SHGFI_ICON, ...);
  • SHGetFileInfo(..., SHGFI_SYSICONINDEX,...);
  • SHGetFileInfo(..., SHGFI_ICONLOCATION,...);
  • IThumbnailProvider

Доступные иконки через SHGetStockIconInfo

Microsoft предоставляет удобную страницу, которая дает пример и описание всех иконок акций.

И значок экрана 256px (начиная с Windows 10):

Введите описание изображения здесь

Значок щита находится в файле C:\Windows\System32\imageres.dll (по крайней мере, в моей копии английской 32-разрядной Windows 7). Там есть несколько версий значка щита, включая синюю и желтую версию, которую вы имеете выше (значок 78).

Значки, извлеченные из Windows 7 x64 SP1 русский:

16x16 значок щита:

24x24 значок щита:

32x32 значок щита:

Вы задаете неправильный вопрос. Не имеет значения, где этот значок хранится в любой версии windows. Если Microsoft не говорит вам, то вы не должны использовать его - он может отсутствовать в windows 8 (или что-то после 7).

Если вы так сильно хотите иконку, в этом вопросе есть достойное графическое представление ее выше. Вы можете сделать alt-prt scrn, а затем использовать ваше любимое графическое приложение, чтобы превратить его в значок и добавить его в свое приложение. Это может быть нелегально, хотя (помните, IANAL)