DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

画面上のすべてのウィンドウとそのタイトルを列挙する

ここでは、画面上のすべてのウィンドウと、そのタイトルバーに表示されているテキスト(タイトル、キャプション)を列挙する方法を紹介します。

Process.MainWindowTitleを調べる方法

グラフィカルインターフェイスがあるプロセスを探す」で紹介した方法をそのまま使います。つまり、Process.GetProcessesメソッドで得られるすべてのプロセスから、メインウィンドウを持っているものを探すという方法です。この方法ではプロセスのメインウィンドウしか探せませんので、同じプロセスが複数のウィンドウを表示している場合は、その内1つしか取得できません。

下の例では、Process.MainWindowTitleプロパティが空でないプロセスのみを列挙しています。Process.MainWindowHandleプロパティがIntPtr.Zeroでないプロセスを列挙した場合は、表示されていないウィンドウも列挙されます。

VB.NET
コードを隠すコードを選択
'全てのプロセスを列挙する
Dim p As System.Diagnostics.Process
For Each p In System.Diagnostics.Process.GetProcesses()
    'メインウィンドウのタイトルがある時だけ列挙する
    If p.MainWindowTitle.Length <> 0 Then
        Console.WriteLine("プロセス名:" & p.ProcessName)
        Console.WriteLine("タイトル名:" & p.MainWindowTitle)
    End If
Next
C#
コードを隠すコードを選択
//全てのプロセスを列挙する
foreach (System.Diagnostics.Process p in
    System.Diagnostics.Process.GetProcesses())
{
    //メインウィンドウのタイトルがある時だけ列挙する
    if (p.MainWindowTitle.Length != 0)
    {
        Console.WriteLine("プロセス名:" + p.ProcessName);
        Console.WriteLine("タイトル名:" + p.MainWindowTitle);
    }
}

Win32 APIのEnumWindowsを使用する方法

Win32 APIのEnumWindowsを使うと、画面上のすべてのトップレベルウィンドウ(親を持たないウィンドウ)を列挙できます。ウィンドウのタイトルは、GetWindowTextで取得できます。

補足:子ウィンドウを列挙するには、EnumChildWindowsを使います。

以下にEnumWindowsを使用した例(コンソールアプリケーション)を示します。この例では、ウィンドウのタイトルが空でないものだけを列挙し、ウィンドウが属しているクラスの名前も取得しています。

VB.NET
コードを隠すコードを選択
Imports System.Runtime.InteropServices
Imports System.Text

Public Class Program
    ''' <summary>
    ''' エントリポイント
    ''' </summary>
    Public Shared Sub Main()
        'ウィンドウを列挙する
        EnumWindows(New EnumWindowsDelegate(AddressOf EnumWindowCallBack), _
                    IntPtr.Zero)

        Console.ReadLine()
    End Sub

    Public Delegate Function EnumWindowsDelegate(hWnd As IntPtr, _
        lparam As IntPtr) As Boolean

    <DllImport("user32.dll")> _
    Public Shared Function EnumWindows(lpEnumFunc As EnumWindowsDelegate, _
        lparam As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Private Shared Function GetWindowText(hWnd As IntPtr, _
        lpString As StringBuilder, nMaxCount As Integer) As Integer
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Private Shared Function GetWindowTextLength(hWnd As IntPtr) As Integer
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Private Shared Function GetClassName(hWnd As IntPtr, _
        lpClassName As StringBuilder, nMaxCount As Integer) As Integer
    End Function

    Private Shared Function EnumWindowCallBack(hWnd As IntPtr, _
            lparam As IntPtr) As Boolean
        'ウィンドウのタイトルの長さを取得する
        Dim textLen As Integer = GetWindowTextLength(hWnd)
        If 0 < textLen Then
            'ウィンドウのタイトルを取得する
            Dim tsb As New StringBuilder(textLen + 1)
            GetWindowText(hWnd, tsb, tsb.Capacity)

            'ウィンドウのクラス名を取得する
            Dim csb As New StringBuilder(256)
            GetClassName(hWnd, csb, csb.Capacity)

            '結果を表示する
            Console.WriteLine("クラス名:" & csb.ToString())
            Console.WriteLine("タイトル:" & tsb.ToString())
        End If

        'すべてのウィンドウを列挙する
        Return True
    End Function
End Class
C#
コードを隠すコードを選択
using System;
using System.Runtime.InteropServices;
using System.Text;

public class Program
{
    /// <summary>
    /// エントリポイント
    /// </summary>
    public static void Main()
    {
        //ウィンドウを列挙する
        EnumWindows(new EnumWindowsDelegate(EnumWindowCallBack), IntPtr.Zero);

        Console.ReadLine();
    }

    public delegate bool EnumWindowsDelegate(IntPtr hWnd, IntPtr lparam);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public extern static bool EnumWindows(EnumWindowsDelegate lpEnumFunc,
        IntPtr lparam);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int GetWindowText(IntPtr hWnd,
        StringBuilder lpString, int nMaxCount);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int GetWindowTextLength(IntPtr hWnd);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int GetClassName(IntPtr hWnd,
        StringBuilder lpClassName, int nMaxCount);

    private static bool EnumWindowCallBack(IntPtr hWnd, IntPtr lparam)
    {
        //ウィンドウのタイトルの長さを取得する
        int textLen = GetWindowTextLength(hWnd);
        if (0 < textLen)
        {
            //ウィンドウのタイトルを取得する
            StringBuilder tsb = new StringBuilder(textLen + 1);
            GetWindowText(hWnd, tsb, tsb.Capacity);

            //ウィンドウのクラス名を取得する
            StringBuilder csb = new StringBuilder(256);
            GetClassName(hWnd, csb, csb.Capacity);

            //結果を表示する
            Console.WriteLine("クラス名:" + csb.ToString());
            Console.WriteLine("タイトル:" + tsb.ToString());
        }

        //すべてのウィンドウを列挙する
        return true;
    }
}

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • .NET Tipsをご利用いただく際は、注意事項をお守りください。