タスクバー上のボタンやウィンドウのタイトルバーを点滅させるには?[C#、VB] - @IT

 

.NET TIPS

タスクバー上のボタンやウィンドウのタイトルバーを点滅させるには?[C#、VB]

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

 Windowsのタスクバー上のボタンやウィンドウのタイトルバー(=ウィンドウ・キャプション)には、ユーザーに注目してもらうために点滅する機能がある。次の画像はタスクバー・ボタンとタイトルバーが(オレンジ色に)点滅している例だ。

 アプリケーションをこのように点滅させたい場合には、Win32 APIのFlashWindowEx関数を使えばよい。

FlashWindowEx関数の宣言

 FlashWindowEx関数を呼び出すには、まず次の宣言を追加する。Win32 APIの呼び出し方については「TIPS:Win32 APIやDLL関数を呼び出すには?」を参照してほしい。

[DllImport("user32.dll")]
static extern Int32 FlashWindowEx(ref FLASHWINFO pwfi);

[StructLayout(LayoutKind.Sequential)]


public struct FLASHWINFO
{
  public UInt32 cbSize;    // FLASHWINFO構造体のサイズ
  public IntPtr hwnd;      // 点滅対象のウィンドウ・ハンドル
  public UInt32 dwFlags;   // 以下の「FLASHW_XXX」のいずれか
  public UInt32 uCount;    // 点滅する回数
  public UInt32 dwTimeout; // 点滅する間隔(ミリ秒単位)
}

// 点滅を止める


public const UInt32 FLASHW_STOP = 0;
// タイトルバーを点滅させる
public const UInt32 FLASHW_CAPTION = 1;
// タスクバー・ボタンを点滅させる
public const UInt32 FLASHW_TRAY = 2;
// タスクバー・ボタンとタイトルバーを点滅させる
public const UInt32 FLASHW_ALL = 3;
// FLASHW_STOPが指定されるまでずっと点滅させる
public const UInt32 FLASHW_TIMER = 4;
// ウィンドウが最前面に来るまでずっと点滅させる
public const UInt32 FLASHW_TIMERNOFG = 12;
Private Declare Function FlashWindowEx Lib "User32" (ByRef FWInfo As FLASHWINFO) As Int32

Private Structure FLASHWINFO


  Dim cbSize As Int32    ' FLASHWINFO構造体のサイズ
  Dim hwnd As IntPtr     ' 点滅対象のウィンドウ・ハンドル
  Dim dwFlags As Int32   ' 以下の「FLASHW_XXX」のいずれか
  Dim uCount As Int32    ' 点滅する回数
  Dim dwTimeout As Int32 ' 点滅する間隔(ミリ秒単位)
End Structure

' 点滅を止める


Private Const FLASHW_STOP As Int32 = 0
' タイトルバーを点滅させる
Private Const FLASHW_CAPTION As Int32 = &H1
' タスクバー・ボタンを点滅させる
Private Const FLASHW_TRAY As Int32 = &H2
' タスクバー・ボタンとタイトルバーを点滅させる
Private Const FLASHW_ALL As Int32 = &H3
' FLASHW_STOPが指定されるまでずっと点滅させる
Private Const FLASHW_TIMER As Int32 = &H4
' ウィンドウが最前面に来るまでずっと点滅させる
Private Const FLASHW_TIMERNOFG As Int32 = &HC
Win32APIのFlashWindowEx関数の宣言(上:C#、下:VB)

 上記のAPIの宣言からも分かるように、FlashWindowEx関数はパラメータにFLASHWINFO構造体を受け取る。このため、FLASHWINFO構造体も併せて定義する必要がある。この構造体の詳細についてはコード中のコメントを参考にしてほしい。

 dwTimeoutメンバについてだけ、説明を補足しておこう。これに「0」を指定した場合、点滅する間隔はWindowsで設定された「カーソルの点滅速度」の秒数が使われる。「カーソルの点滅速度」は、[コントロール パネル]から[キーボード]を開き、表示される[キーボードのプロパティ]ダイアログの[速度]タブ内で変更できる。

タスクバー・ボタンとタイトルバーを点滅させるサンプル・コード

 次のサンプル・コードは、Windowsアプリケーションのフォーム上に配置したボタンをクリックしたときに(=Clickイベントのイベント・ハンドラが呼び出される)、「devenv」というプロセス名のアプリケーションのタスクバー・ボタンとタイトルバーの両方を5回点滅させる例である。

using System.Runtime.InteropServices;
……中略……

private void button1_Click(object sender, EventArgs e)


{
  FLASHWINFO fInfo = new FLASHWINFO();
  fInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(fInfo));
  fInfo.hwnd = GetMainWindowHandle("devenv");
  fInfo.dwFlags = FLASHW_ALL;
  fInfo.uCount = 5;         // 点滅する回数
  fInfo.dwTimeout = 0;

  FlashWindowEx(ref fInfo);


}
imports System.Runtime.InteropServices
……中略……

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

  Dim fInfo As New FLASHWINFO()


  fInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(fInfo))
  fInfo.hwnd = GetMainWindowHandle("devenv")
  fInfo.dwFlags = FLASHW_ALL
  fInfo.uCount = 5         ' 点滅する回数
  fInfo.dwTimeout = 0

  FlashWindowEx( fInfo)

End Sub

タスクバー・ボタンとタイトルバーを5回点滅させるサンプル・コード(上:C#、下:VB)
Marshal.SizeOfメソッドは型のサイズをバイト数(=int型/Integer型の数値)で返す(MarshalはSystem.Runtime.InteropServices名前空間のクラスで、SizeOfはMarshalクラスの静的メソッド)。

 上記のコード内容のほとんどは、これまでの説明だけで理解できるので、詳しい説明は割愛する。

 ただしGetMainWindowHandleメソッドはまだ説明していない。このメソッドはこのサンプル・プログラム内で独自に作成したもので、パラメータに指定されたプロセス名のアプリケーションのメイン・ウィンドウのウィンドウ・ハンドル(IntPtr型)を戻り値で返す。ここでは、GetMainWindowHandleメソッドで取得した「devenv」アプリケーションのメイン・ウィンドウ・ハンドルをFLASHWINFO構造体のhwndメンバに設定している。

 GetMainWindowHandleメソッドの説明についても、本TIPSの趣旨ではないため割愛する。詳しくは、「TIPS:プロセス情報を名前を基に取得するには?」を参考にしてほしい。以下に、GetMainWindowHandleメソッドのコード内容を示しておく。

// 指定したプロセス名のメイン・ウィンドウ・ハンドルを取得する
public IntPtr GetMainWindowHandle(string processName)
{
  Process curProcess = Process.GetCurrentProcess();
  Process[] allProcesses = Process.GetProcessesByName(processName);

  foreach (Process checkProcess in allProcesses)


  {
    if (oneProcess.MainWindowHandle != IntPtr.Zero)
    {
      return oneProcess.MainWindowHandle;
    }
  }

  // 指定したプロセス名のアプリケーションが見つからない!


  return IntPtr.Zero;
}
'指定したプロセス名のメイン・ウィンドウ・ハンドルを取得する
Public Function GetMainWindowHandle(ByVal processName As String) As IntPtr

  Dim curProcess As Process =  Process.GetCurrentProcess()


  Dim allProcesses() As Process =  _
    Process.GetProcessesByName(processName)

  For Each oneProcess As Process In allProcesses


    If oneProcess.MainWindowHandle <> IntPtr.Zero Then
      Return oneProcess.MainWindowHandle
    End If
  Next

  ' 指定したプロセス名のアプリケーションが見つからない!


  Return IntPtr.Zero
End Function
>
メイン・ウィンドウ・ハンドルを取得するGetMainWindowHandleメソッドのコード内容(上:C#、下:VB)
指定したプロセス名のウィンドウが複数ある場合には、最初に見つかったウィンドウを1つしか返さないので注意してほしい。

 以上のサンプル・コードを実行すると、冒頭の画面のように、タスクバー・ボタンやタイトルバーが5回点滅する。End of Article




TechTargetジャパン

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用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える

Insider.NET 記事ランキング

本日 月間