投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/7/12 11:56:43
> ■「ShellWindows コレクションからウィンドウハンドルを拾う方法」
ShellWindows による列挙処理は、検索結果の取得にも使うことができます。
COM なので VBA と VB.NET とで同じライブラリを利用できますし、API 宣言も不要です。

参照設定なし(レイトバインド)でも
参照設定あり(アーリーバインド)でも書けますが、
今回は参照設定ありで書いてみます。

参照設定に、COM の "Microsoft Shell Controls And Automation" を追加します。
エクスプローラーに表示されているアイテムが多いと、列挙に時間がかかるのでご注意を。

Option Strict On
Public Class Form1
    Private WithEvents Button1 As Button
    Private WithEvents DataGrid1 As DataGrid
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        DataGrid1 = New DataGrid() With {.Name = "DataGrid1", .Dock = DockStyle.Fill}
        Controls.Add(DataGrid1)
        Button1 = New Button() With {.Name = "Button1", .Text = "エクスプローラーの列挙", .Dock = DockStyle.Top, .Height = 40}
        Controls.Add(Button1)
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Button1.Enabled = False
        UseWaitCursor = True

        DataGrid1.DataSource = Nothing
        Dim ds As New DataSet("Explorer")
        For Each sh In DirectCast(New Shell32.Shell().Windows(), IEnumerable)
            Dim doc = TryCast(CallByName(sh, "Document", CallType.Get), Shell32.ShellFolderView)
            If doc Is Nothing Then Continue For
            Dim tbl = ds.Tables.Add()
            Dim oFolder = doc.Folder
            Try
                tbl.TableName = oFolder.Title
                tbl.TableName = $"(0x{Hex(CallByName(sh, "Hwnd", CallType.Get))})" & tbl.TableName
            Catch
            End Try
            tbl.Columns.Add(oFolder.GetDetailsOf(Nothing, 0))
            tbl.Columns.Add("区分")
            tbl.Columns.Add("パス")
            tbl.Columns.Add(oFolder.GetDetailsOf(Nothing, 1))
            tbl.Columns.Add(oFolder.GetDetailsOf(Nothing, 2))
            tbl.Columns.Add(oFolder.GetDetailsOf(Nothing, 3))
            tbl.Columns.Add(oFolder.GetDetailsOf(Nothing, 4))
            Dim oItems = oFolder.Items()
            Dim values(6) As String
            Dim count = oItems.Count
            For n = 0 To count - 1
                Dim oItem = oItems.Item(n)
                Dim status As New List(Of String)()
                If oItem.IsBrowsable Then status.Add("Browsable")
                If oItem.IsFileSystem Then status.Add("FileSystem")
                If oItem.IsFolder Then status.Add("Folder")
                If oItem.IsLink Then status.Add("Link")

                values(0) = oFolder.GetDetailsOf(oItem, 0)
                values(1) = String.Join(", ", status)
                values(2) = oItem.Path
                values(3) = oFolder.GetDetailsOf(oItem, 1)
                values(4) = oFolder.GetDetailsOf(oItem, 2)
                values(5) = oFolder.GetDetailsOf(oItem, 3)
                values(6) = oFolder.GetDetailsOf(oItem, 4)
                tbl.Rows.Add(values)
            Next
        Next

        ds.AcceptChanges()
        DataGrid1.DataSource = ds
        UseWaitCursor = False
        Button1.Enabled = True
    End Sub

End Class