3

I'm trying to use API with below VBA code, but there are multiple windows handle with same caption and class name like "#32770" and "Button". So, how can I move on to next handle. I have attached the screen shot of spy registry values I wanted to access second window handle with multiple button caption but they also have same window caption and class name.

screenshot

Please refer attached screen shot for multiple windows handle.

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
Community
  • 1
  • 1
SmithG
  • 31
  • 2

1 Answers1

1

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.

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
Josh Anstead
  • 328
  • 2
  • 15