Storage location of yellow-blue shield icon

房东的猫 提交于 2020-05-17 04:48:46

问题


Where, in Windows, is this Yellow-Blue Windows Security Icon icon stored? I need to use it in a TaskDialog emulation for XP and am having a hard time tracking it down.

It's not in shell32.dll, explorer.exe, ieframe.dll or wmploc.dll (as these contain a lot of icons commonly used in Windows).

Edit: For clarification, I am emulating a certain type of dialog in XP. The icon is (most likely) not present there. So I want to extract it from the library that holds it in Windows 7. I am extending an existing implementation of this emulation and want to provide a full feature set.


回答1:


I wanted to point it out explicitly.

You are supposed to put a shield on UI elements that will trigger an elevation: MSDN: Step 4: Redesign Your UI for UAC Compatibility.

Of course, you don't have to go spelunking around DLLs to extract images (although it certainly does make it easier at design time when you can design your design with a design time interface).

Microsoft provides a couple of supported (and therefore guaranteed) ways that you can get ahold of the shield icon at runtime:

  • Add a shield icon to the user interface?:

    • Extract a small icon

      SHSTOCKICONINFO sii;
      sii.cbSize = sizeof(sii);
      SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICON | SHGSI_SMALLICON, &sii);
      hiconShield  = sii.hIcon;
      
    • Extract a large icon

      SHSTOCKICONINFO sii;
      sii.cbSize = sizeof(sii);
      SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICON | SHGSI_LARGEICON, &sii);
      hiconShield  = sii.hIcon;
      
    • Extract an icon of custom size

      SHSTOCKICONINFO sii;
      sii.cbSize = sizeof(sii);
      SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICONLOCATION, &sii);
      hiconShield  = ExtractIconEx(sii. ...);
      
  • Add a Shield Icon to a Button

    Button_SetElevationRequiredState(hwndButton, TRUE);
    

The article forgot to mention LoadIcon:

hIconShield = LoadIcon(0, IDI_SHIELD);

Although LoadIcon has been "superseded" by 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

Loading the size you want - by avoiding shared images

In order to avoid loading a "shared" version of the icon, you have to load the icon directly out of the file.

We all know that the shield exists in user32.dll as resource id 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              |

That was undocumented spellunking.

SHGetStockIconInfo can give us the actual, current, guaranteed to change in the future, path and index:

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

resulting in:

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

You can load this image for the size you desire using LoadImage:

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

Another slightly easier way is to use 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;
}

It does the loading for you, and it handles the negative icon index (and the secret meaning that has):

HICON shieldIcon = GetStockIcon(SIID_SHIELD, 256);

Personally, i then use WIC to wrap that into a 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;
}

and so:

IWICBitmap bmp = GetStockWicBitmap(SIID_SHIELD, 256);

Now that you have the bitmap, at runtime, do with it what you want.

Small and Large

The problem with ExtractIconEx is that you're again stuck with the two shell sizes:

  • "small" (i.e. GetSystemMetrics(SM_CXSMICON))
  • "large" (i.e. GetSystemMetrics(SM_CXICON))

Loading icons is something that is quite a dark art in Windows:

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

Icons available through SHGetStockIconInfo

Microsoft gives a handy page that gives an example, and description, of all the stock icons.

  • SHSTOCKICONID (archive)

And the 256px shield icon (as of Windows 10):




回答2:


The shield icon is located in the file C:\Windows\System32\imageres.dll (at least, in my copy of English 32-bit Windows 7). There are several versions of the shield icon there, including the blue and yellow version you have above (icon 78).




回答3:


Icons extracted from Windows 7 x64 SP1 English:

16x16 shield icon:

24x24 shield icon:

32x32 shield icon:




回答4:


You are asking the wrong question. It doesn't matter where this icon is stored on any version of windows. If Microsoft don't tell you then you should not use it - it might not be there in windows 8 (or whatever comes after 7).

If you want the icon so bad, there is a decent graphical representation of it above in this question. You could do alt-prt scrn then use your favourite graphics app to turn it into an icon and add it to your app. This may not be legal though (remember, IANAL)



来源:https://stackoverflow.com/questions/61700399/shield-mfc-image-resource-for-cmfcbutton

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!