■No34391に追記(魔界の仮面弁士の記事)
>>>> ウインドウの一覧を先に取得してそれをプロセスで束ねてく方法は>>>> 分かるのですが、それだと時間がかかるので> ウィンドウ数が膨大で列挙が遅いというのであれば、
手元の VB2005 で試してみましたが、数百ミリ秒以内に列挙が完了しており、
言うほど時間がかかるようには思えませんでした。
比較のため、そちらで実装したコードを見せて頂けないでしょうか?
Option Strict On
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.ComponentModel
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim dt As New DataTable()
dt.Columns.Add("PID", GetType(Integer))
dt.Columns.Add("ProcessName", GetType(String))
dt.Columns.Add("HWND", GetType(IntPtr))
dt.Columns.Add("Title", GetType(String))
EnumWindows(AddressOf EnumWindowCallBack, dt)
Me.DataGridView1.DataSource = dt
Me.DataGridView1.Columns("PID").DefaultCellStyle.Format = "X8"
Me.DataGridView1.Columns("HWND").DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
End Sub
Private Function EnumWindowCallBack(ByVal hWnd As IntPtr, ByVal lparam As DataTable) As Boolean
If GetWindow(hWnd) = IntPtr.Zero AndAlso IsWindowVisible(hWnd) Then
Dim processId As Integer
GetWindowThreadProcessId(hWnd, processId)
Dim procName As String = ""
Try
'procName = Process.GetProcessById(processId).ProcessName
Catch
End Try
Dim Title As String = ""
'Dim textLen As Integer = GetWindowTextLength(hWnd)
'If textLen > 0 Then
' Dim tsb As New StringBuilder(textLen + 1)
' GetWindowText(hWnd, tsb, tsb.Capacity)
' Title = tsb.ToString(0, textLen)
'End If
lparam.Rows.Add(processId, procName, hWnd, Title)
End If
Return True
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode, EntryPoint:="GetWindowTextW", SetLastError:=True)> _
Private Shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
End Function
<DllImport("user32.dll", CharSet:=CharSet.Unicode, EntryPoint:="GetWindowTextLengthW", SetLastError:=True)> _
Private Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
End Function
Private Delegate Function EnumWindowsDelegate(ByVal hWnd As IntPtr, ByVal lparam As DataTable) As Boolean
<DllImport("user32.dll")> _
Private Shared Function EnumWindows(ByVal lpEnumFunc As EnumWindowsDelegate, ByVal lparam As DataTable) As Boolean
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
End Function
Private Const GW_OWNER As Integer = 4
<DllImport("user32.dll")> _
Private Shared Function GetWindow(ByVal hWnd As IntPtr, Optional ByVal uCmd As Integer = GW_OWNER) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
End Function
End Class