【VBA×WindowsAPI】FlashWindowEx関数の使い方

FlashWindowEx関数

FlashWindowEx関数は指定したウィンドウをフラッシュ(点滅)させるための関数です。

 
ここでいうフラッシュとは、対象のウィンドウに対してアクティブ状態の描画と非アクティブの描画状態を繰り返すことで疑似的な点滅を行うことを意味しています。このとき、ウィンドウのアクティブ状態は切り替わらず、あくまでも描画状態が切り替わるだけの処理が行われます。また、設定によりウィンドウの点滅だけでなく、タスクバーのアイコンを通知表示(オレンジ色)にすることも可能です。

Windows APIには同じく指定のウィンドウをフラッシュするためのFlashWindow関数が存在しますが、FlashWindowEx関数はこの関数の上位互換の存在でフラッシュの回数や速度、終了のタイミングなどの細かい設定を行うことが可能になっています。

フラッシュは主にフォーカスされていないウィンドウを点滅させユーザの注意を引きつけさせるために利用されます。VBAでのFlashWindowEx関数の使いどころとしては、ユーザに気付いてほしいが目立ちにくいUserFormをフラッシュさせたり、バックグラウンドで回していたマクロの処理が完了した際にタスクバーのアイコンを通知状態にさせたりなどがあります。

使用方法

FlashWindowEx関数を使用するにはあらかじめ関数の宣言しておく必要があります。
※宣言をしないと関数は使えずにエラーとなるので書き忘れに注意しましょう。

使用しているWindowsが32bitか64bitかによって宣言時に書く文言が違います。
環境に合わせて以下のいずれかをコードの一番初め(Option Explicitの次の行あたり)に書いておくことで、そのモジュール内で各関数を使うことができるようになります。

 icon-code  64bit  

Declare PtrSafe Function FlashWindowEx Lib “user32.dll" (pfwi As FLASHWINFO) As Long

icon-code  32bit  

Declare Function FlashWindowEx Lib “user32.dll" (pfwi As FLASHWINFO) As Long

この関数の引数としてFLASHWINFOという型をユーザー定義型(構造体)で定義しておく必要があります。構造体はTypeステートメントを使って下記のように定義します。

'64bit環境
Type FLASHWINFO
    cbSize      As LongPtr
    hWnd        As LongPtr
    dwFlags     As Long
    uCount      As Long
    dwTimeout   As LongPtr
End Type

'32bit環境
Type FLASHWINFO
    cbSize      As Long
    hWnd        As Long
    dwFlags     As Long
    uCount      As Long
    dwTimeout   As Long
End Type

 
上記内容をまとめて64bit/32bitの両環境に対応させる場合は下記コードをモジュールの最上部に書いておきましょう。この構文を書いておくことで自動的に使うことのできる方の構文が使用されます。
VBE上では使えない方の構文が赤色で表示される場合がありますが、実行に影響はありません。

#If VBA7 Then
    Declare PtrSafe Function FlashWindowEx Lib "user32.dll" (pfwi As FLASHWINFO) As Long
    Type FLASHWINFO
        cbSize      As LongPtr
        hWnd        As LongPtr
        dwFlags     As Long
        uCount      As Long
        dwTimeout   As LongPtr
    End Type
    
#Else
    Declare Function FlashWindowEx Lib "user32.dll" (pfwi As FLASHWINFO) As Long
    Type FLASHWINFO
        cbSize      As Long
        hWnd        As Long
        dwFlags     As Long
        uCount      As Long
        dwTimeout   As Long
    End Type

#End If

 
各関数の宣言文は「Private/Public」を付けて各関数の有効範囲を指定することもできます。

Private Declare PtrSafe Function~ :モジュール内でのみ呼び出し有効
Public Declare PtrSafe Function~ :モジュール外で呼び出し有効

 

構文

FlashWindowEx関数の構文は下記のように書きます。

icon-code FlashWindowEx関数 

lRet = FlashWindowEx(pfwi)

引数

 pfwi    (FLASHWINFO構造体) 

フラッシュの設定がされたFLASHWINFO構造体を入力します。
FLASHWINFO構造体の要素は下記の通りです。下記の5つの要素の値を設定した構造体を引数として入力することで、設定した情報をもとに任意のウィンドウをフラッシュさせることができます。

cbSize            :構造体のサイズ
hWnd             :フラッシュするウィンドウのハンドル
dwFlags         :フラッシュ状態フラグ
uCount          :フラッシュ回数
dwTimeout    :フラッシュ速度(ミリ秒単位)

 

 cbSize 
構造体のサイズを入力します。
VBAでは構造体の変数を用意した時点で構造体のサイズの取得が可能です。
下記のようにLen関数で変数サイズを取得し、そのまま入力するだけで設定は完了です。

Dim tFlashInfo As FLASHWINFO
tFlashInfo.cbSize = Len(tFlashInfo)

 hWnd 
フラッシュさせたいウィンドウのハンドルを入力します。
ウィンドウハンドルを取得するための関数としてFindWindow関数FindWindowEx関数GetActiveWindow関数など様々なものがあります。環境によって引数の型が変わるので注意が必要です。


 dwFlags 
フラッシュの状態を表すフラグ(定数値)を入力します。
フラッシュの状態を表すフラグとして下表の6つの定数値が用意されています。

意味
FLASHW_ALL = &H3 ウィンドウキャプションとタスクバーをフラッシュ
FLASHW_CAPTION = &H1 ウィンドウキャプションをフラッシュ
FLASHW_TRAY = &H2 タスクバーをフラッシュ
FLASHW_STOP = 0 フラッシュを停止
FLASHW_TIMER = &H4 FLASHW_STOPフラグが設定されるまでフラッシュ
FLASHW_TIMERNOFG= &HC ウィンドウが最前面になるまでフラッシュ

このうち「FLASHW_TIMER」および「FLASHW_TIMERNOFG」は「FLASHW_ALL」「FLASHW_CAPTION 」「FLASHW_TRAY」のいずれかと併用して設定する必要があります。フラグを複数設定する場合は「Or」を使って下記のように書くことで設定が可能です。

Dim tFlashInfo As FLASHWINFO

'ウィンドウキャプションをフラッシュ
tFlashInfo.dwFlags = FLASHW_CAPTION

'ウィンドウが最前面になるまでウィンドウキャプションをフラッシュ
tFlashInfo.dwFlags = FLASHW_CAPTION Or FLASHW_TIMERNOFG

 uCount 
フラッシュする回数を入力します。
dwFlagsにフラッシュに回数指定のない「FLASHW_TIMER」「FLASHW_TIMERNOFG」が入力される場合、この値は「0」にする必要があります。フラッシュに回数指定のないフラグが入力されていたとしても、この値に0以外の数値が入力されているとその回数が優先されます。


 dwTimeout 
フラッシュの速度をミリ秒単位で入力します。(1000ミリ秒=1秒)
この値に「0」を入力するとWindows既定の速度が設定されます。
 

戻り値

 lRet    (Long型) 

戻り値は本関数を呼び出す前の、ウィンドウの状態が返されます。
この関数を呼び出す前にウィンドウがアクティブになっている場合は「0以外」の値が、この関数を呼び出す前にウィンドウがアクティブになっていない場合は「0」が返されます。

サンプルコード

以下はFlashWindowEx関数FindWindow関数を使って、メモ帳ウィンドウ(複数ある場合はより前面にあるウィンドウ)をフラッシュするサンプルコードです。メモ帳ウィンドウを1つ以上開いた状態で下記コードを実行すると、該当のウィンドウが300ミリ秒の間隔で10回点滅し、タスクバーのアイコンを通知状態(オレンジ表示)にすることができます。フラッシュの設定を変更したい場合は、下記コードのtFlashInfo構造体の要素の値を変更するだけです。

Private Declare PtrSafe Function FlashWindowEx Lib "user32.dll" (pfwi As FLASHWINFO) As Long
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr

Private Type FLASHWINFO
    cbSize      As LongPtr  '構造体サイズ
    hWnd        As LongPtr  'フラッシュするウィンドウのハンドル
    dwFlags     As Long     'フラッシュ状態フラグ
    uCount      As Long     'フラッシュ回数
    dwTimeout   As LongPtr  'フラッシュ速度(ミリ秒単位)
End Type

Const FLASHW_ALL        As Long = &H3 'ウィンドウキャプションとタスクバーをフラッシュ
Const FLASHW_CAPTION    As Long = &H1 'ウィンドウキャプションをフラッシュ
Const FLASHW_TRAY       As Long = &H2 'タスクバーをフラッシュ
Const FLASHW_STOP       As Long = 0   'フラッシュを停止
Const FLASHW_TIMER      As Long = &H4 'FLASHW_STOPフラグが設定されるまでフラッシュ
Const FLASHW_TIMERNOFG  As Long = &HC 'ウィンドウが最前面になるまでフラッシュ

Sub main()

    Dim tFlashInfo As FLASHWINFO
    Dim hWndFlash As LongPtr
    Dim lRet As Long
 
    'フラッシュするウィンドウのハンドルを取得
    hWndFlash = FindWindow("Notepad", vbNullString)
    
    'フラッシュ設定
    With tFlashInfo
        .cbSize = Len(tFlashInfo)
        .hWnd = hWndFlash
        .dwFlags = FLASHW_ALL
        .uCount = 10
        .dwTimeout = 300
    End With
    
    '指定の設定でウィンドウをフラッシュする
    lRet = FlashWindowEx(tFlashInfo)
    
End Sub

 

 icon-share-square  VBA×WindowsAPIまとめページ

その他のWindowsAPI関数は下記ページにまとまっているので合わせて参照下さい。

 icon-share-square  参考

Microsoft公式:FlashWindowEx 関数 (winuser.h) – Win32 apps
                      FLASHWINFO 構造体 (winuser.h) – Win32

Excel,VBA,Windows API