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

GetActiveWindow関数

GetActiveWindow関数は現在アクティブなウィンドウへのハンドルを取得するための関数です。

ウィンドウハンドルとは、ウィンドウを識別するための特別な識別子です。
ウィンドウを開いたり閉じたり、移動させたり、サイズを変えたり、テキストを変更したりするなど、ウィンドウに対して行いたい様々な操作を指示する際に使用します。このウィンドウに対する操作もWindowAPIに用意されている何種類もの関数で行うことが可能です。

ウィンドウハンドルはC++では「HWND型」という型で扱いますが、中身としては長整数型の値であるためVBAではLongPtr型(32bitではLong型)を使用します。VBAでウィンドウハンドルを格納する変数はC++の型に合わせてhWndなどと記載することが多いです。

ウィンドウハンドルは、ウィンドウが作成されるときに自動的に割り当てられます。
そして、そのウィンドウが存在している間は一貫して有効ですが、ウィンドウが閉じられると無効になります。つまりハンドルを取得すると毎回値が違うウィンドウも存在するということです。

VBAにおいてはUserFormもウィンドウであるため、たとえばUserFormを最前面に移動させたり、サイズを変更できるようにしたり、半透明にしたりと様々な操作を行うことが可能になります。このとき、その操作の対象となるUserFormへのハンドルを取得するための関数がGetActiveWindow関数という訳です。この他にもFindWindow関数GetNextWindow関数GetParent関数といったウィンドウハンドルを取得するための関数は何種類も存在します。

GetActivewindow関数は処理が行われた"瞬間"にアクティブなウィンドウのハンドルを取得するのです。そのためマクロをVBE上で実行するとVBEのウィンドウハンドルが、Excelブック上から実行するとExcelのウィンドウハンドルが取得されます。(つまりVBAにおいてはあまり汎用性はない)

UserFormのウィンドウハンドルを取得したい場合、UserFormの「Initializeイベント」にGetActivewindow関数を記載してもUserFormが表示される前(アクティブになる前)に処理が流れてしまうためハンドルは取得できません。UserFormのウィンドウハンドルを取得するには「Initializeイベント」が流れてUserFormが画面に表示された後にGetActivewindow関数を実行する必要があります。

 

使用方法

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

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

 icon-code  64bit  

Declare PtrSafe Function GetActiveWindow Lib “user32" () As LongPtr

icon-code  32bit  

Declare Function GetActiveWindow Lib “user32" () As Long

上記のどちらを書けばいいかわからない場合は以下のコードをコピペして、モジュールの最上部に書いておきましょう。この構文を書いておくことで自動的に使うことのできる方の構文が使用されます。
VBE上では使えない方の構文が赤色で表示される場合がありますが、実行に影響はありません。

#If VBA7 Then
    Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
#Else
    Declare Function GetActiveWindow Lib "user32" () As Long
#End If

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

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

 
 

構文

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

icon-code GetActivewindow関数 

hwnd = GetActivewindow()

戻り値

  hwnd   (64bit:LongPtr型 / 32bit:Long型) 

戻り値は現在アクティブなウィンドウのハンドルです。
プログラム上でマルチスレッド(並行処理)をする場合は、関数が呼び出された側に関連付けられているアクティブウィンドウのハンドルを返しますが、VBAマクロにおいてはマルチスレッドの考えは基本的には不要です。アクティブウィンドウが存在しない場合はNULL値(0)が返されます。

ウィンドウハンドルは開発(実行)環境によって戻り値の型が変化するので注意が必要です。

 

サンプルコード

以下はGetActiveWindow関数GetWindowText関数を使って、アクティブウィンドウのキャプション名を取得するサンプルコードです。VBEから実行した場合はVBEのウィンドウのキャプションが、Excelブック上から実行した場合はそのExcelブックのキャプションがイミディエイトウィンドウに出力されます。

Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As LongPtr, ByVal lpString As String, ByVal cch As Long) As Long

Sub main()

    Dim hwnd As LongPtr
    Dim lRet As LongPtr
    Dim sBuf As String * 100
    Dim sCap As String
    
    'アクティブウィンドウのハンドルを取得
    hwnd = GetActiveWindow
    
    '取得したハンドルのクラス名を取得(固定長文字列)
    lRet = GetWindowText(hwnd, sBuf, Len(sBuf))
    
    '不要なバッファ分は削除
    sCap = Left(sBuf, InStr(sBuf, vbNullChar) - 1)
    
    '取得したクラス名をイミディエイトウィンドウに出力
    Debug.Print sCap
    
End Sub

 

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

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

 icon-share-square  参考

Microsoft公式:GetActiveWindow function (winuser.h) – Win32 apps

2023年7月16日Excel,VBA,Windows API