NonSoft

全てのウィンドウとコントロールの情報を
表示するサンプル(VB.NET)


 サンプル(ソース/コード)
<このサンプルの概要>
全てのウィンドウとコントロールの情報を表示するサンプルソースを作ってみました。
VB.NETのフォームにTreeViewを1つ追加してお試しください。
ステータスバー(msctls_statusbar32)の各パートの文字列を取得する関数はVB6版を参照ください。

VB6版はこちらです。
全てのウィンドウとコントロールの情報を表示するサンプル(VB6)

本サンプルのキーワードは以下のAPIです。
(1)EnumWindows
(2)EnumChildWindows
(3)GetClassName
(4)SendMessage

★標準モジュール(Module1.vb)
Module Module1
    ' APIの定義
    Private Const WM_GETTEXT = &HD
    Private Delegate Function D_EnumWindowsProc( _
        ByVal hWnd As Integer, ByVal lParam As Integer) As Integer
    Private Delegate Function D_EnumChildWindowsProc( _
        ByVal hWnd As Integer, ByVal lParam As Integer) As Integer
    Private Declare Function EnumWindows Lib "user32.dll" _
        (ByVal lpEnumFunc As D_EnumWindowsProc, ByVal lParam As Integer) As Integer
    Private Declare Function EnumChildWindows Lib "user32.dll" _
        (ByVal hwndParent As Integer, ByVal lpEnumFunc As D_EnumChildWindowsProc, _
         ByVal lParam As Integer) As Integer
    Private Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA" _
        (ByVal hWnd As Integer, ByVal lpClassName As Byte(), _
         ByVal nMaxCount As Integer) As Integer
    Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _
        (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, _
         ByVal lParam As Byte()) As Integer

    ' コントロール毎の情報を設定するコレクション
    Private colWindows As New Collection

    ' ウィンドウとコントロールを全て取得
    Public Function GetAllWindows() As Collection
        On Error Resume Next
        Dim i As Long
        Dim lngRet As Long

        ' コントロール毎の情報を設定するコレクション生成
        colWindows = New Collection
        GetAllWindows = colWindows

        ' トップレベルウィンドウを全て取得
        lngRet = EnumWindows(AddressOf EnumWindowsProc, 0)

        ' 親ウィンドウに属するコントロールを全て取得
        For i = 1 To colWindows.Count
            lngRet = EnumChildWindows( _
                colWindows.Item(i).Item(1)(0), AddressOf EnumChildWindowsProc, i)
        Next i
    End Function

    ' トップレベルウィンドウを全て取得
    Public Function EnumWindowsProc( _
        ByVal hWnd As Integer, ByVal lParam As Integer) As Integer
        On Error Resume Next
        Dim lngRet As Long
        Dim bytClass As Byte() = New Byte(255) {}
        Dim bytTitle As Byte() = New Byte(255) {}
        Dim strClass As String
        Dim strTitle As String

        ' クラス名取得
        lngRet = GetClassName(hWnd, bytClass, 255)
        strClass = StripNulls(bytClass)

        ' ウィンドウのタイトル取得
        lngRet = SendMessage(hWnd, WM_GETTEXT, 255, bytTitle)
        strTitle = StripNulls(bytTitle)

        ' 取得した情報を配列に設定
        Dim strDa(2) As Object
        strDa(0) = hWnd
        strDa(1) = strClass
        strDa(2) = strTitle

        ' 取得した情報をコレクションに設定
        Dim colDa As New Collection
        colDa.Add(strDa)

        ' トップレベルウィンドウ毎のコレクションに追加
        colWindows.Add(colDa)

        ' リターン
        EnumWindowsProc = 1
    End Function

    ' 指定された親ウィンドウに属するコントロールを全て取得
    Private Function EnumChildWindowsProc( _
        ByVal hWnd As Integer, ByVal lParam As Integer) As Integer
        On Error Resume Next
        Dim lngRet As Long
        Dim bytClass As Byte() = New Byte(255) {}
        Dim bytTitle As Byte() = New Byte(255) {}
        Dim strClass As String
        Dim strTitle As String

        ' クラス名取得
        lngRet = GetClassName(hWnd, bytClass, 255)
        strClass = StripNulls(bytClass)

        ' ウィンドウのタイトル取得
        lngRet = SendMessage(hWnd, WM_GETTEXT, 255, bytTitle)
        strTitle = StripNulls(bytTitle)

        ' 取得した情報を配列に設定
        Dim strDa(2) As Object
        strDa(0) = hWnd
        strDa(1) = strClass
        strDa(2) = strTitle

        ' コントロール毎のコレクションに追加
        colWindows.Item(lParam).Add(strDa)

        ' リターン
        EnumChildWindowsProc = 1
    End Function

    ' 文字列からNULL文字以降をカット
    Private Function StripNulls(ByVal bytOrg As Byte()) As String
        On Error Resume Next
        Dim strOrg As String = _
            System.Text.Encoding.GetEncoding("SHIFT-JIS").GetString(bytOrg)
        If (InStr(strOrg, Chr(0)) > 0) Then
            strOrg = Left(strOrg, InStr(strOrg, Chr(0)) - 1)
        End If
        StripNulls = strOrg
    End Function
End Module

★フォームモジュール(Form1.vb)
Public Class Form1
    Private Sub Form1_Load( _
        ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim i As Long
        Dim j As Long
        Dim bytClass As Byte()
        Dim bytTitle As Byte()
        Dim bytSpace As Byte()

        ' ウィンドウとコントロールの全ての情報を取得
        Dim colWindows As Collection
        colWindows = GetAllWindows()

        ' 親ウィンドウ毎のコレクションループ
        For i = 1 To colWindows.Count
            ' 子コントロール毎のコレクション取得
            Dim colChilds As Collection
            colChilds = colWindows.Item(i)

            'If colChilds.Count >= 1 Then       ' 全ての親ウィンドウを対象
            If colChilds.Count > 1 Then         ' 子コントロールを持つ物のみ対象
                ' 子コントロール毎のコレクションループ
                Dim treeNodeTop As TreeNode = Nothing
                For j = 1 To colChilds.Count
                    bytSpace = System.Text.Encoding.GetEncoding( _
                        "SHIFT-JIS").GetBytes(New String(" ", 50))

                    ' コレクションからクラス名取得
                    bytClass = System.Text.Encoding.GetEncoding( _
                        "SHIFT-JIS").GetBytes(colChilds.Item(j)(1))
                    If bytClass.Length < 30 Then
                        Dim p As Integer = bytClass.Length
                        ReDim Preserve bytClass(bytClass.Length + bytSpace.Length - 1)
                        Array.Copy(bytSpace, 0, bytClass, p, bytSpace.Length)
                        ReDim Preserve bytClass(30 - 1)
                    End If
                    Dim strClass As String = System.Text.Encoding.GetEncoding( _
                        "SHIFT-JIS").GetString(bytClass)

                    ' コレクションから文字列取得
                    bytTitle = System.Text.Encoding.GetEncoding( _
                        "SHIFT-JIS").GetBytes(colChilds.Item(j)(2))
                    If bytTitle.Length < 50 Then
                        Dim p As Integer = bytTitle.Length
                        ReDim Preserve bytTitle(bytTitle.Length + bytSpace.Length - 1)
                        Array.Copy(bytSpace, 0, bytTitle, p, bytSpace.Length)
                        ReDim Preserve bytTitle(50 - 1)
                    End If
                    Dim strTitle As String = System.Text.Encoding.GetEncoding( _
                        "SHIFT-JIS").GetString(bytTitle)

                    If j = 1 Then
                        ' 親ウィンドウの情報をツリービューへ追加
                        treeNodeTop = New TreeNode(strClass & " - " & strTitle)
                        TreeView1.Nodes.Add(treeNodeTop)
                    Else
                        ' 子コントロールの情報をツリービューへ追加
                        Dim treeNodeSub As TreeNode = _
                            New TreeNode(strClass & " - " & strTitle)
                        treeNodeTop.Nodes.Add(treeNodeSub)
                    End If
                Next j
            End If
        Next i
    End Sub
End Class