You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Word VBA获取其他已打开应用窗口Window ID的问题

64位VBA窗口句柄获取代码报错解决

编辑说明

发布问题后我意识到,代码实际上并未切换到其他窗口,但可以获取Window ID编号。因此我修改了问题以反映代码的实际功能。我已让代码在64位环境下运行,处理完Eugene Astafiev的回答建议后会发布答案。

问题描述

我在多个线程中找到一段32位的代码,尝试将其转换为64位版本,当前代码如下:

API声明部分

Option Explicit

Private Declare PtrSafe Function FindWindow Lib "USER32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As LongPtr, ByVal lpString As String, ByVal cch As LongPtr) As Long
Private Declare PtrSafe Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As LongPtr) As Long
Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hWnd As LongPtr, ByVal wCmd As Long) As LongPtr
Private Declare PtrSafe Function IsWindowVisible Lib "user32" (ByVal hWnd As LongPtr) As Boolean

Private Const GW_HWNDNEXT = 2

Test过程

Private Sub Test()

    Dim lhWndP As Long
    If GetHandleFromPartialCaption(lhWndP, "Excel") = True Then
        If IsWindowVisible(lhWndP) = True Then
          MsgBox "Found VISIBLE Window Handle: " & lhWndP, vbOKOnly + vbInformation
        Else
          MsgBox "Found INVISIBLE Window Handle: " & lhWndP, vbOKOnly + vbInformation
        End If
    Else
        MsgBox "Window 'Excel' not found!", vbOKOnly + vbExclamation
    End If

End Sub

获取句柄函数

Private Function GetHandleFromPartialCaption(ByRef lWnd As Long, ByVal sCaption As String) As Boolean

    Dim lhWndP As Long
    Dim sStr As String

    GetHandleFromPartialCaption = False
    lhWndP = FindWindow(vbNullString, vbNullString) 'PARENT WINDOW

    Do While lhWndP <> 0
        sStr = String(GetWindowTextLength(lhWndP) + 1, Chr$(0))
        GetWindowText lhWndP, sStr, Len(sStr)
        sStr = Left$(sStr, Len(sStr) - 1)
        If InStr(1, sStr, sCaption) > 0 Then
            GetHandleFromPartialCaption = True
            lWnd = lhWndP
            Exit Do
        End If
        lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
    Loop

End Function

运行Test过程时,执行到函数最后一行出现错误(错误截图:错误截图1)。我花了很多时间查找64位的API声明调整方式,是否有遗漏的地方?

更新

发布问题后我发现未将FindWindow函数声明为LongPtr。修正后,现在又在代码开头出现Type mismatch(类型不匹配)错误(错误截图:错误截图2)。

解决方法

报错核心是变量类型与64位句柄不兼容:64位系统中窗口句柄是8字节的LongPtr类型,但代码里多处用4字节的Long存储句柄,导致类型冲突。

修正后的完整代码

Option Explicit

Private Declare PtrSafe Function FindWindow Lib "USER32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As LongPtr, ByVal lpString As String, ByVal cch As LongPtr) As Long
Private Declare PtrSafe Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As LongPtr) As Long
Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hWnd As LongPtr, ByVal wCmd As Long) As LongPtr
Private Declare PtrSafe Function IsWindowVisible Lib "user32" (ByVal hWnd As LongPtr) As Boolean

Private Const GW_HWNDNEXT = 2

Private Sub Test()

    Dim lhWndP As LongPtr ' 改为LongPtr
    If GetHandleFromPartialCaption(lhWndP, "Excel") = True Then
        If IsWindowVisible(lhWndP) = True Then
          MsgBox "找到可见窗口句柄: " & lhWndP, vbOKOnly + vbInformation
        Else
          MsgBox "找到不可见窗口句柄: " & lhWndP, vbOKOnly + vbInformation
        End If
    Else
        MsgBox "未找到包含'Excel'的窗口!", vbOKOnly + vbExclamation
    End If

End Sub

Private Function GetHandleFromPartialCaption(ByRef lWnd As LongPtr, ByVal sCaption As String) As Boolean ' 参数改为LongPtr

    Dim lhWndP As LongPtr ' 改为LongPtr
    Dim sStr As String

    GetHandleFromPartialCaption = False
    lhWndP = FindWindow(vbNullString, vbNullString) 'PARENT WINDOW

    Do While lhWndP <> 0
        sStr = String(GetWindowTextLength(lhWndP) + 1, Chr$(0))
        GetWindowText lhWndP, sStr, Len(sStr)
        sStr = Left$(sStr, Len(sStr) - 1)
        If InStr(1, sStr, sCaption) > 0 Then
            GetHandleFromPartialCaption = True
            lWnd = lhWndP
            Exit Do
        End If
        lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
    Loop

End Function

关键修正点

  1. 将所有存储窗口句柄的变量(Test中的lhWndP、GetHandleFromPartialCaption的参数lWnd和内部变量lhWndP)从Long改为LongPtr,确保64位环境下能正确存储8字节句柄。
  2. API声明部分已正确使用PtrSafe并返回LongPtr,无需修改。

内容的提问来源于stack exchange,提问作者DryBSMT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:51:56