.NET TIPS

ボタンにUACの盾アイコンを表示するには?[C#、VB]

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

 Windows Vista以降のWindows OSでは、UAC(ユーザー・アカウント制御)という権限モデルが採用されている。この権限モデル下では、管理者権限が必要なアプリケーションやタスクを実行する際には、ユーザーに権限を昇格してもらう必要がある。

 例えばボタンをクリックした後の処理で、このような権限の昇格が必要な場合には、そのボタンに盾(シールド)アイコンを表示することが一般的である。次の画面はその例である。

コントロール・パネル[日付と時刻]の[日付と時刻の変更]ボタンに表示された盾アイコン

 このような盾アイコンをボタンに表示するには、Win32 APIのSendMessage関数を呼び出して、そのボタンにメッセージを送ればよい(Win32 APIの呼び出し方法は、「TIPS:Win32 APIやDLL関数を呼び出すには?」を参考にされたい)。今回の使用例におけるSendMessage関数の各パラメータの指定内容は下記のとおり。

SendMessage関数
・第1パラメータ(HWND):ボタンのウィンドウ・ハンドル。
・第2パラメータ(UINT):盾アイコンの設定を意味するBCM_SETSHIELD(16進数で「160C」)。
・第3パラメータ(WPARAM):今回の場合は「0」。
・第4パラメータ(LPARAM):有効にする場合は「1」、無効にする場合は「0」。

 ウィンドウ・ハンドル(HWND)は、マネージ・コードではHandleRef構造体(System.Runtime.InteropServices名前空間)のオブジェクトとして表現できる。つまりSendMessage関数の第1パラメータに対しては、HandleRef構造体のコンストラクタを呼び出してインスタンスを生成すればよい。今回の使用例におけるHandleRef構造体コンストラクタの各パラメータの指定内容は下記のとおり。

HandleRef構造体のコンストラクタ
・第1パラメータ(Object):ボタン・オブジェクト。
・第2パラメータ(IntPtr):ボタンのハンドル。

 また、WPARAMとLPARAMは、マネージ・コードではIntPtr構造体(System名前空間)のオブジェクトとして表現できる。つまりSendMessage関数の第3、第4パラメータに対しては、IntPtr構造体のコンストラクタを呼び出してインスタンスを生成すればよい。今回の使用例におけるIntPtr構造体コンストラクタの各パラメータの指定内容は下記のとおり。

IntPtr構造体コンストラクタ
・第1パラメータ(Int32):「0」もしくは「1」。

 次のコードは、以上を踏まえて実装した、ボタンに盾アイコンを表示するサンプル・コードである。

using System.Runtime.InteropServices;

public Form1()
{
  ……省略……

  // ボタンの外観を「System」にする必要がある
  button1.FlatStyle = FlatStyle.System;

  // 第1パラメータ:ボタンのウィンドウ・ハンドル
  HandleRef hwnd = new HandleRef(button1, button1.Handle);

  // 第2パラメータ:盾アイコンを設定するフラグ
  uint BCM_SETSHIELD = 0x0000160C;

  // SendMessage関数の呼び出し
  SendMessage(hwnd, BCM_SETSHIELD, new IntPtr(0), new IntPtr(1));
}

[DllImport("user32.dll")]
private static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
Imports System.Runtime.InteropServices

Public Sub New()

  ……省略……

  ' ボタンのスタイルを「System」にする必要がある
  Button1.FlatStyle = FlatStyle.System

  ' 第1パラメータ:ボタンのウィンドウ・ハンドル
  Dim hwnd As New HandleRef(Button1, Button1.Handle)

  ' 第2パラメータ:盾アイコンを設定するフラグ
  Dim BCM_SETSHIELD As UInt32 = &H160C

  ' SendMessage関数の呼び出し
  SendMessage(hwnd, BCM_SETSHIELD, New IntPtr(0), New IntPtr(1))

End Sub

<DllImport("user32.dll")> _
Private Shared Function SendMessage( _
  ByVal hWnd As HandleRef, _
  ByVal Msg As UInt32, _
  ByVal wParam As IntPtr, _
  ByVal lParam As IntPtr) As IntPtr
End Function
ボタンに盾アイコンを表示するサンプル・コード (上:C#、下:VB)

 注意点として、盾アイコンを表示するにはシステム・ボタンを使う必要がある。具体的には、上記のコードのように、ButtonコントロールのFlatStyleプロパティ(=ボタンの外観を決めるプロパティ)に「FlatStyle.System」を設定する必要がある。

 上記のコードにより、次の画面のように、ボタンに盾アイコンが表示されるようになる。

ボタンに盾アイコンが表示される例

 当然ながら、盾アイコンを表示したからといっても、ボタンをクリックしたときのイベント・ハンドラで自動的に権限の昇格が行われるわけではない。権限の昇格は、独自に実装する必要がある。その実装方法は、「TIPS:管理者としてほかのアプリケーションを実行するには?」を参考にしてほしい。

●SystemIcons.Shieldプロパティについて

 ボタン上のテキストにアイコンを表示するだけであれば、「TIPS:Windowsフォームのボタンでテキストの前に画像を表示するには?」で紹介している方法でも可能だ。SystemIconsクラス(System.Drawing名前空間)には、盾アイコンのIconクラス(System.Drawing名前空間)のオブジェクトを取得できるShieldプロパティ(静的プロパティ)も用意されている。

 そのIconオブジェクトをボタンの前に設定したのが、次の画面である。

Win32 APIの盾アイコン(上)とSystemIcons.Shieldプロパティの盾アイコン(下)

 上の画面は、Windows 7上で実行した例。見て分かるように、Win32 APIの盾アイコン(上)とSystemIcons.Shieldプロパティの盾アイコン(下)は画像内容が異なる。Windows 7で標準的に使われているのはWin32 APIの盾アイコン画像になるので、Win32 APIを使う方が無難であろう。End of Article

カテゴリ:クラス・ライブラリ 処理対象:Windows環境
カテゴリ:クラス・ライブラリ 処理対象:UAC
カテゴリ:クラス・ライブラリ 処理対象:Win32 API
使用ライブラリ:DllImport属性(System.Runtime.InteropServices名前空間)
使用ライブラリ:HandleRef構造体(System.Runtime.InteropServices名前空間)
使用ライブラリ:IntPtr構造体(System名前空間)
使用ライブラリ:SystemIconsクラス(System.Drawing名前空間)
使用ライブラリ:Iconクラス(System.Drawing名前空間)
関連TIPS:Win32 APIやDLL関数を呼び出すには?
関連TIPS:管理者としてほかのアプリケーションを実行するには?
関連TIPS:Windowsフォームのボタンでテキストの前に画像を表示するには?

この記事と関連性の高い別の.NET TIPS
UACの盾アイコンを取得するには?
ファイルに関連付けられたアイコンを取得するには?
実行ファイルからアプリケーションのアイコンを取得するには?
Win32 APIやDLL関数に構造体を渡すには?
タスクバーにアイコンを表示させないようにするには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム 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 記事ランキング

本日 月間