ここでは、画面上のすべてのウィンドウと、そのタイトルバーに表示されているテキスト(タイトル、キャプション)を列挙する方法を紹介します。
「グラフィカルインターフェイスがあるプロセスを探す」で紹介した方法をそのまま使います。つまり、Process.GetProcessesメソッドで得られるすべてのプロセスから、メインウィンドウを持っているものを探すという方法です。この方法ではプロセスのメインウィンドウしか探せませんので、同じプロセスが複数のウィンドウを表示している場合は、その内1つしか取得できません。
下の例では、Process.MainWindowTitleプロパティが空でないプロセスのみを列挙しています。Process.MainWindowHandleプロパティがIntPtr.Zeroでないプロセスを列挙した場合は、表示されていないウィンドウも列挙されます。
'全てのプロセスを列挙する 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
//全てのプロセスを列挙する 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を使うと、画面上のすべてのトップレベルウィンドウ(親を持たないウィンドウ)を列挙できます。ウィンドウのタイトルは、GetWindowTextで取得できます。
補足:子ウィンドウを列挙するには、EnumChildWindowsを使います。
以下にEnumWindowsを使用した例(コンソールアプリケーション)を示します。この例では、ウィンドウのタイトルが空でないものだけを列挙し、ウィンドウが属しているクラスの名前も取得しています。
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
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; } }
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。