14

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.

Oliver Salzburg
  • 21,652
  • 20
  • 93
  • 138
  • This is the UAC indicator, is it not? I wouldn't think it'd be present in XP, only Vista and 7. – Michael Petrotta May 09 '10 at 19:47
  • 2
    That icon is used by the OS for things the user can trust - why do you want to show it? – Stewart May 09 '10 at 19:47
  • 3
    @Stewart The icon not reserved for the OS, applications are supposed to use it too (http://msdn.microsoft.com/en-us/library/bb756990.aspx#BKMK_UXImplementation) – Ian Boyd Mar 05 '12 at 00:45
  • 1
    From the [Windows 7 license terms](http://download.microsoft.com/Documents/UseTerms/Windows%207_Professional_English_7bb89e9f-20ea-4555-892f-394539ec1090.pdf): "While the software is running, you may use but not share its icons, images, sounds, and media." Consult a lawyer before proceeding. – Raymond Chen Mar 05 '12 at 02:07
  • @IanBoyd: Thank you for pointing that out! I've been poking around with MAKEINTRESOURCE from system DLLs for years in the back of my mind realizing there must be a proper way to do this, that respects themes and such ;) – Andon M. Coleman Oct 03 '16 at 18:33

4 Answers4

15

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.

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

enter image description here

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
  • Quick question: does "actual, current, guaranteed to change in the future, path and index" refer to "future" as in, while the application is running, or "future" as in, future version of Windows? – jonspaceharper May 07 '18 at 08:44
  • 1
    Future as in future versions of Windows. It's part of the API contract, and Microsoft takes backwards compatibility very seriously. – Ian Boyd May 07 '18 at 14:40
11

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

Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
1

Icons extracted from Windows 7 x64 SP1 English:

16x16 shield icon:

24x24 shield icon:

32x32 shield icon:

izogfif
  • 6,000
  • 2
  • 35
  • 25
0

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)

Stewart
  • 3,978
  • 17
  • 20
  • As I said in my question, I am trying to emulate TaskDialogs (which use this icon) in a Windows version that has neither. The image in my original post is, in fact, a screenshot. So it has no alpha channel (which I require to emulate the feature). Post-XP, I use the official API, so I don't really care how the icon looks in future versions. – Oliver Salzburg May 09 '10 at 19:58