使用VBA和VB.NET API处理多个窗口

3
我正在尝试使用以下VBA代码与API进行交互,但是有多个具有相同标题和类名(如“#32770”和“Button”)的窗口句柄。那么,我应该如何移动到下一个句柄呢?我已经附上了Spy注册表值的屏幕截图,我想访问第二个具有多个按钮标题的窗口句柄,但它们也具有相同的窗口标题和类名。请参考附加的屏幕截图以获取多个窗口句柄。
Sub sbRunCalcUsingAPI()

 hwnd = FindWindow(vbNullString, "Calculator")

    start_doc = ShellExecute(hwnd, "open", "C:\Windows\system32\calc.exe", 0, 0, SW_NORMAL)

    If start_doc = 2 Then Exit Sub
    If start_doc = 3 Then Exit Sub

    Do
    DoEvents
    hWnd2 = FindWindow(vbNullString, "Calculator")
    Loop Until hWnd2 > 0

    main_view = FindWindowEx(hWnd2, 0&, "CalcFrame", vbNullString) 
    sub_window2 = FindWindowEx(main_view, X&, "#32770", vbNullString)
    sub_window2One = FindWindowEx(main_view, 0&, "Button", vbNullString)

End Sub

各位,请尽快回复上述查询。 - SmithG
1个回答

1
你需要在这里使用 'GetNextWindow() 而不是 'FindWindowEx()。 现在你有三个选项:第一个子窗口、下一个子窗口或前一个子窗口。 每种情况都是独特的,你的方法可能需要一些微调,具体取决于元素的属性。 个人而言,当类或窗口标题不明确时,我会寻找一个唯一的窗口标签,在模糊的窗口上方或下方, 然后使用其中一个选项查找hwnd。
Public Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" ( _
    ByVal hwnd As Long, _
    ByVal lpOperation As String, _
    ByVal lpFile As String, _
    ByVal lpParameters As String, _
    ByVal lpDirectory As String, _
    ByVal nShowCmd As Long _
    ) As Long

Public Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" ( _
    ByVal hWnd1 As Long, _
    ByVal hWnd2 As Long, _
    ByVal lpsz1 As String, _
    ByVal lpsz2 As String _
    ) As Long

 Public Declare Function GetNextWindow Lib "user32.dll" Alias "GetWindow" ( _
    ByVal hwnd As Long, _
    ByVal wFlag As Long _
    ) As Long

Public Const GW_HWNDFIRST = 0
Public Const GW_HWNDPREV = 1
Public Const GW_HWNDNEXT = 2

Public Const SW_NORMAL As Long = 1


Sub sbRunCalcUsingAPI()

    Dim x As Long

'You do not need 'Let hwnd = FindWindow(vbNullString, "Calculator") '
'if you are opening it for the first time.
'It is used in cases where you want to open a 'tabbed window', like Internet Explorer.
'You would then find the parent window and open a new tab in it. For your purpose,
'you can leave it blank."

      '  Let hwnd = FindWindow(vbNullString, "Calculator")

        start_doc = ShellExecute( _
                                0&, _
                                "open", _
                                "C:\Windows\system32\calc.exe", _
                                0, _
                                0, _
                                SW_NORMAL _
                                )

        If start_doc = 2 Then Exit Sub
        If start_doc = 3 Then Exit Sub

        Do
            DoEvents
            Let hWnd2 = FindWindow( _
                                    vbNullString, _
                                    "Calculator" _
                                    )
        Loop Until hWnd2 > 0

        Let main_view = FindWindowEx( _
                                    hWnd2, _
                                    0&, _
                                    "CalcFrame", _
                                    vbNullString _
                                    )

        Let sub_window2 = FindWindowEx( _
                                    main_view, _
                                    x&, _
                                    "#32770", _
                                    vbNullString _
                                    )


'You will want to use 'GetNextWindow() instead of 'FindWindowEx() here.
'Now you have one of three options: First Child Window, Next Child Window,
'or Previous Child Window
'Every case is unique, and your approach may need some tweaking depending
'on your element's attributes.
'Personally, I use this when the class or window caption is ambiguous.
'I look for a unique window label above or below the ambiguous one
'and then find the hwnd using one of the options.

       ' Let sub_window2One = FindWindowEx(main_view, 0&, "Button", vbNullString)

    'First Child Window
    Let sub_window2One = GetNextWindow( _
                                        sub_window2, _
                                        GW_HWNDFIRST _
                                        )
    'Previous Child Window
    Let VIP_6_Digit_hwnd = GetNextWindow( _
                                        sub_window2, _
                                        GW_HWNDPREV _
                                        )
    'Next Child Window
    Let VIP_6_Digit_hwnd = GetNextWindow( _
                                        sub_window2, _
                                        GW_HWNDNEXT _
                                        )

End Sub

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接