如何使用vba在windowapi中使用findwindow函数定位窗口?

Posted

技术标签:

【中文标题】如何使用vba在windowapi中使用findwindow函数定位窗口?【英文标题】:How to locate the window using findwindow function in windowapi using vba? 【发布时间】:2016-03-30 04:48:29 【问题描述】:

我目前正在尝试找到一种方法来使用 Findwindow 函数检查窗口是否打开。如果我知道窗口的全名,我就能找到窗口。在下面的代码中,我知道窗口的名称是“win32api - 记事本”,所以我可以很容易地找到窗口但是我想知道如果我只知道像“win32 *”这样的部分名称是否可以识别窗口。

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Sub runapplication()


hwnd = FindWindow(vbNullString, "win32api - Notepad")
MsgBox (hwnd)
End Sub

【问题讨论】:

有人打电话吗? XD 检查我问过的第一个问题。 嗨 Findwindow 你能帮我解决一下吗 也许可以试试instr?我不知道。 只是一个想法 - 你能找到一种方法来遍历所有窗口并返回它们的名称,然后使用 Instr 来检查你正在寻找的名称吗? 我要做的是创建一个数组集合,其中包括当前打开的所有窗口的句柄 (hwnd) 和标题。然后我使用各种方法(Instr 也可以)循环遍历集合并以这种方式找到部分匹配项。我不知道是否有更简单的方法来做到这一点。 【参考方案1】:

一种方法是使用EnumWindows API 函数。由于它通过回调函数进行操作,因此您需要在超出调用函数范围的地方缓存条件和结果:

Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, _
                                                  ByVal param As Long) As Long
Public Declare Function IsWindowVisible Lib "User32" (ByVal hWnd As Long) As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
                                                 (ByVal hwnd As Long, _
                                                  ByVal lpString As String, _
                                                  ByVal cch As Long) As Long
Public Const MAX_LEN = 260

Public results As Dictionary
Public criteria As String

Public Sub Example()
    criteria = "win32*"
    Set results = New Dictionary
    Call EnumWindows(AddressOf EnumWindowCallback, &H0)
    Dim result As Variant
    For Each result In results.Keys
        Debug.Print result & " - " & results(result)
    Next result
End Sub

Public Function EnumWindowCallback(ByVal hwnd As Long, ByVal param As Long) As Long
    Dim retValue As Long
    Dim buffer As String       
    If IsWindowVisible(hwnd) Then
        buffer = Space$(MAX_LEN)
        retValue = GetWindowText(hwnd, buffer, Len(buffer))
        If retValue Then
            If buffer Like criteria Then
                results.Add hwnd, Left$(buffer, retValue)
            End If
        End If
    End If
    EnumWindowCallback = 1
End Function

【讨论】:

感谢 Comintem。你的代码对我有用,只是对代码做了一些小的修改,它就起作用了。 @RAJATHEVAR,那么您可以接受该解决方案作为答案。【参考方案2】:

下面的代码对我有用。刚刚声明了 IsWindowVisible 函数并将 Microsoft 脚本运行时库添加到我的项目中。

Public Declare Function EnumWindows Lib "User32" (ByVal lpEnumFunc As Long, _
                                                  ByVal param As Long) As Long
Public Declare Function GetWindowText Lib "User32" Alias "GetWindowTextA" _
                                                 (ByVal hWnd As Long, _
                                                  ByVal lpString As String, _
                                                  ByVal cch As Long) As Long
Public Declare Function IsWindowVisible Lib "User32" (ByVal hWnd As Long) As Long
Public Const MAX_LEN = 260

Public results As Dictionary
Public criteria As String

Public Sub Example()
    criteria = "win32"
    Set results = New Dictionary
    Call EnumWindows(AddressOf EnumWindowCallback, &H0)
    Dim result As Variant
    For Each result In results.Keys
        Debug.Print result & " - " & results(result)
    Next result
End Sub

Public Function EnumWindowCallback(ByVal hWnd As Long, ByVal param As Long) As Long
    Dim retValue As Long
    Dim buffer As String
    If IsWindowVisible(hWnd) Then
        buffer = Space$(MAX_LEN)
        retValue = GetWindowText(hWnd, buffer, Len(buffer))
        If retValue Then

            If InStr(1, buffer, criteria, vbTextCompare) > 0 Then
                results.Add hWnd, Left$(buffer, retValue)
            End If
        End If
    End If
    EnumWindowCallback = 1
End Function

【讨论】:

以上是关于如何使用vba在windowapi中使用findwindow函数定位窗口?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Window API 在窗口中显示位图(带有颜色值的数组)?

如何在 VBA 中使用 FileSystemObject?

如何在 VBA 中使用 FileSystemObject?

如何在 VBA 中使用枚举进行验证

如何在 VBA 过程中使用可选数组参数?

如何使用 VBA 在 PPT 中编辑/取消组合 EMF 粘贴?