.NET TIPS

UACの盾アイコンを取得するには?[C#、VB]

デジタルアドバンテージ 一色 政彦
2010/04/08

 「TIPS:ボタンにUACの盾アイコンを表示するには?」では、Windows 7/VistaなどのOSで権限の昇格が必要な処理を実行するボタンに、盾(シールド)アイコンを表示する方法を紹介した。

 しかし、ボタン以外のコントロールなどでも、権限の昇格が必要となり、盾アイコンを表示したいという場合がある。そのような場合には、Windows OS(具体的には「C:\Windows\system32\imageres.dll」)から盾アイコンを取得して使用すればよい。本TIPSではその取得方法を紹介する。

●UACの盾アイコンをWindows OSから取得する方法

 Windowsシステムが定義するシェル・アイコンを取得するには、Win32 APIのSHGetStockIconInfo関数を使用する(Win32 APIの呼び出し方法は、「TIPS:Win32 APIやDLL関数を呼び出すには?」を参考にされたい)。SHGetStockIconInfo関数は、下記のような構文を持つ。

SHGetStockIconInfo関数

  • 第1パラメータ(SHSTOCKICONID):SHSTOCKICONID列挙体の1つの値。盾アイコンのIDは「SIID_SHIELD」で、16進数値で「4D」。
  • 第2パラメータ(UINT):1つ以上のフラグの組み合わせ。アイコンを意味するフラグは「SHGSI_ICON」で、16進数値で「100」。大きいアイコンを意味するフラグは「SHGSI_LARGEICON」で、16進数値で「0」(=つまりデフォルトでは大きいアイコンになる)。小さいアイコンを意味するフラグは「SHGSI_SMALLICON」で、16進数値で「1」。
  • 第3パラメータ(SHSTOCKICONINFO):シェル・アイコンの情報を格納するためのSHSTOCKICONINFO構造体(後述)へのポインタ。
  • 戻り値(HRESULT):成功時はS_OK(=0)を返す。それ以外はHRESULTエラー・コードを返す。

 第3パラメータに指定するSHSTOCKICONINFO構造体のメンバは次のようになっている。

SHSTOCKICONINFO構造体

  • 第1メンバ(DWORD):バイト単位での構造体サイズ。SHGetStockIconInfo関数を呼び出す前に設定する。
  • 第2メンバ(HICON):アイコン・ハンドルを受け取る。
  • 第3メンバ(DWORD):今回は使わない。SHGSI_SYSICONINDEXフラグを設定したときに、システム・アイコン・キャッシュ内画像のインデックス番号を受け取る。
  • 第4メンバ(int):今回は使わない。SHGSI_ICONLOCATIONフラグを設定したときに、第5メンバで受け取るパスのリソース内画像のインデックス番号を受け取る。
  • 第5メンバ(WCHAR):今回は使わない。SHGSI_ICONLOCATIONフラグを設定したときに、アイコンを含むリソースのパスを受け取る。

 次のコードは、以上で説明したSHGetStockIconInfo関数を使って、盾アイコンの大きいサイズと小さいサイズを取得して、それぞれ別のPictureBoxコントロールに貼り付けるWindowsフォームのサンプル・アプリケーションである。

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public Form1()
{
  ……省略……

  SHSTOCKICONINFO sii = new SHSTOCKICONINFO();
  sii.cbSize = Marshal.SizeOf(sii);
  SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICON, ref sii);
  if (sii.hIcon != IntPtr.Zero)
  {
    Icon shieldIcon = Icon.FromHandle(sii.hIcon);
    pictureBox1.Image = shieldIcon.ToBitmap();
  }

  SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICON | SHGSI_SMALLICON, ref sii);
  if (sii.hIcon != IntPtr.Zero)
  {
    Icon shieldIcon = Icon.FromHandle(sii.hIcon);
    pictureBox2.Image = shieldIcon.ToBitmap();
  }
}

const UInt32 SHGSI_ICON      = 0x000000100;
const UInt32 SHGSI_SMALLICON = 0x000000001;
const UInt32 SIID_SHIELD     = 0x00000004D;

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct SHSTOCKICONINFO
{
  public Int32 cbSize;
  public IntPtr hIcon;
  public Int32 iSysImageIndex;
  public Int32 iIcon;
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
  public string szPath;
}

[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
static extern void SHGetStockIconInfo(UInt32 siid, UInt32 uFlags, ref SHSTOCKICONINFO sii);
Imports System.Runtime.InteropServices

Sub New()

  ……省略……

  Dim sii As New SHSTOCKICONINFO()
  sii.cbSize = Marshal.SizeOf(sii)
  SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICON, sii)
  If sii.hIcon <> IntPtr.Zero Then
    Dim shieldIcon As Icon = Icon.FromHandle(sii.hIcon)
    PictureBox1.Image = shieldIcon.ToBitmap()
  End If

  SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICON Or SHGSI_SMALLICON, sii)
  If sii.hIcon <> IntPtr.Zero Then
    Dim shieldIcon As Icon = Icon.FromHandle(sii.hIcon)
    PictureBox2.Image = shieldIcon.ToBitmap()
  End If

End Sub

Const SHGSI_ICON As UInt32 = &H100
Const SHGSI_SMALLICON As UInt32 = &H1
Const SIID_SHIELD As UInt32 = &H4D

<StructLayoutAttribute(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Structure SHSTOCKICONINFO
  Public cbSize As Int32
  Public hIcon As IntPtr
  Public iSysImageIndex As Int32
  Public iIcon As Int32
  <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
  Public szPath As String
End Structure

<DllImport("shell32.dll", CharSet:=CharSet.Unicode)> _
Shared Sub SHGetStockIconInfo(ByVal siid As UInt32, ByVal uFlags As UInt32, ByRef sii As SHSTOCKICONINFO)
End Sub
UACの盾アイコンを取得して表示するサンプル・コード

 特に難しい部分はないので、コードの詳細に対する説明は割愛する。これを実行すると、次の画面のようになる。

UACの盾アイコンを取得して表示した例

 大きいアイコンは32×32のサイズ、小さいアイコンは16×16のサイズで取得できる。End of Article

カテゴリ:クラス・ライブラリ 処理対象:Windows環境
カテゴリ:クラス・ライブラリ 処理対象:UAC
カテゴリ:クラス・ライブラリ 処理対象:Win32 API
使用ライブラリ:DllImport属性(System.Runtime.InteropServices名前空間)
使用ライブラリ:IntPtr構造体(System名前空間)
使用ライブラリ:Iconクラス(System.Drawing名前空間)
関連TIPS:Win32 APIやDLL関数を呼び出すには?
関連TIPS:ボタンにUACの盾アイコンを表示するには?

この記事と関連性の高い別の.NET TIPS
ボタンにUACの盾アイコンを表示するには?
ファイルに関連付けられたアイコンを取得するには?
実行ファイルからアプリケーションのアイコンを取得するには?
タスクバーにアイコンを表示させないようにするには?
システムトレイ(タスクトレイ)にアイコンを表示するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間