Место хранения желто-синего значка щита
Где в Windows хранится этот значок ? Мне нужно использовать его в эмуляции TaskDialog для XP, и мне трудно его отследить.
Это не в shell32.dll, проводник.exe, ieframe.dll или wmploc.dll (поскольку они содержат много иконок, обычно используемых в Windows).
Править: Для уточнения я эмулируюопределенный тип диалога в XP. Иконы (скорее всего) там нет. Поэтому я хочу извлечь его из библиотеки, которая содержит его в Windows 7. Я расширяя существующую реализацию этой эмуляции и хотите предоставить полный набор функций.
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)