【Excel VBA】EnumWindows()によるウィンドウの列挙(コールバック関数とフォーム作成を試す)

VBA・Officeカテゴリを表すパンダのイラスト VBA・Office

【Excel VBA】EnumWindows()によるウィンドウの列挙(コールバック関数とフォーム作成を試す)

Excel VBAからWindows APIの EnumWindows() を利用して、現在起動しているすべてのトップレベルウィンドウのハンドルとタイトルを列挙する方法を解説します。

古いVB5用のサンプルコードやリンク切れとなった配布ファイルに頼らず、現在の64bit版を含むExcel環境でも安全に動作するコードと手順を再構成しました。

1. この記事で何ができるか

VBAの標準機能だけでは取得できない、Windows上の他アプリケーションのウィンドウ一覧(タイトルとウィンドウハンドル)を取得し、イミディエイトウィンドウに出力することができます。

2. 想定環境・前提条件

  • 動作確認環境: Microsoft Excel (32bit / 64bit 環境両対応)
  • OS: Windows 10 / 11
  • 前提知識: VBAの標準モジュール、ユーザーフォーム、および AddressOf 演算子の基本的な知識

3. 完全なコード

ウィンドウ列挙を行うためには、標準モジュールにAPIの宣言とコールバック関数を記述し、フォームや別の標準モジュールから呼び出します。

標準モジュール (例: Module1)

Option Explicit

' 64bitおよび32bit環境に対応したAPI宣言
#If VBA7 Then
    Declare PtrSafe Function EnumWindows Lib "user32" (ByVal lpEnumFunc As LongPtr, ByVal lParam As LongPtr) As Long
    Declare PtrSafe Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthW" (ByVal hwnd As LongPtr) As Long
    Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextW" (ByVal hwnd As LongPtr, ByVal lpString As LongPtr, ByVal nMaxCount As Long) As Long
    Declare PtrSafe Function IsWindowVisible Lib "user32" (ByVal hwnd As LongPtr) As Long
#Else
    Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
    Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
    Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
#End If

' コールバック関数(EnumWindowsから呼び出される)
#If VBA7 Then
Public Function EnumWindowsProc(ByVal hwnd As LongPtr, ByVal lParam As LongPtr) As Long
#Else
Public Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
#End If
    Dim lLength As Long
    Dim sTitle As String
    
    ' 表示されているウィンドウのみ対象とする場合
    If IsWindowVisible(hwnd) Then
        lLength = GetWindowTextLength(hwnd)
        If lLength > 0 Then
            sTitle = Space$(lLength + 1)
            #If VBA7 Then
                GetWindowText hwnd, StrPtr(sTitle), lLength + 1
            #Else
                GetWindowText hwnd, sTitle, lLength + 1
            #End If
            sTitle = Left$(sTitle, lLength)
            
            ' タイトルが存在する場合はイミディエイトウィンドウに出力
            If Trim$(sTitle) <> "" Then
                Debug.Print "HWnd: " & hwnd & " | Title: " & sTitle
            End If
        End If
    End If
    
    ' 列挙を継続するためには 1 (True) を返す
    EnumWindowsProc = 1
End Function

' 実行用プロシージャ
Public Sub StartEnumWindows()
    Debug.Print "--- ウィンドウ列挙開始 ---"
    ' AddressOf を用いてコールバック関数のアドレスを渡す
    EnumWindows AddressOf EnumWindowsProc, 0
    Debug.Print "--- ウィンドウ列挙終了 ---"
End Sub

4. 実行手順

  1. Excelを開き、Alt + F11 キーを押してVBE(Visual Basic Editor)を起動します。
  2. メニューの [挿入] > [標準モジュール] をクリックして新規モジュールを追加します。
  3. 上記のコードをすべて貼り付けます。
  4. VBE上で StartEnumWindows プロシージャ内にカーソルを置き、F5 キー(または上部の再生ボタン)を押して実行します。
  5. Ctrl + G キーを押してイミディエイトウィンドウを開き、出力されたウィンドウ一覧を確認します。

5. 期待される結果

イミディエイトウィンドウに以下のような形式で、現在起動しているウィンドウのハンドルとタイトルが表示されます。

--- ウィンドウ列挙開始 ---
HWnd: 131252 | Title: 予約語・関数名 - Microsoft Visual Basic for Applications
HWnd: 66324 | Title: 検索 - Google Chrome
--- ウィンドウ列挙終了 ---

6. トラブルシューティング・注意点

  • ポインタサイズの差異 (VBA7 / 64bit対応): 64bit版Excelを使用する場合、ウィンドウハンドル (HWND) は LongPtr 型として扱う必要があります。古い32bit専用コードをそのまま動かすとVBEが強制終了(クラッシュ)する原因になりますので、上記のように条件付きコンパイル(#If VBA7 Then)を使用してください。
  • 無限ループやクラッシュを防ぐ注意: コールバック関数内でエラーが発生するとExcel全体がフリーズ・強制終了するリスクがあります。デバッグ中はこまめにファイルを保存してください。

この記事の更新履歴

この記事は、生成AIを活用した自動レビュー・更新フローにより内容を見直し、必要な修正を反映しています。

2026年9月26日

  • 削除リンク切れとなっている古い外部ZIPファイルのダウンロードリンクを削除しました。
  • 追加EnumWindows関数とコールバック処理を用いたウィンドウ列挙の完全なVBAサンプルコードと実行手順を追加しました。

文書情報

記事タイトル
【Excel VBA】EnumWindows()によるウィンドウの列挙(コールバック関数とフォーム作成を試す)
作成日
更新日
Source URL
https://papanda925.com/?p=414

ライセンス: 本記事のうち、当サイトが権利を有する本文・自作図表は、特記なき限り CC BY 4.0 で利用できます。生成AIを活用して作成・編集した内容を含みます。コードについて、別途ライセンス表示またはリンク先GitHubリポジトリのライセンスがある場合は、その条件を優先します。引用・第三者資料・画像・商標等は本ライセンスの対象外です。 利用ポリシー

タイトルとURLをコピーしました