How to get handle of menu in external application, and find button where no text is part of class.

Galaxea

New Member
Joined
Jul 20, 2018
Messages
34
Office Version
  1. 2021
Platform
  1. Windows
@Jaafar Tribak - I have seen that you have extensive experience in this topic so I am hoping that you can help me please.

I have an external application that I can launch and control from Excel, but only up to a point.
As soon as I click on the SEND TO button and the menu pops up I can't go any further as I cannot get the handle or any other info.
Even bringing up the SPY++ tool will make the menu disappear as soon as the focus is changed off the menu.

Please contact me, even off the forum if necessary as I really need to get this working! I can't see a way to contact someone directly on this forum.

1658424498840.png


I have another similar issue with the latest version of the same program (I am in the process of upgrading to it) where I can't find enough info to know what to click to open a company file (see below).
Thanks. Rob.

1658425416226.png
 
Excellent! You're getting there.

I am really liking this UIAutomation. Can it completely replace the "old" subclassing that I was doing before with FindWindow and FindWindowex?
It seems to be more reliable and there is less guesswork involved.
Yes, you should be able to replace the Windows API calls with UIAutomation to find your app's window handle.

This is how it's done with Calculator:
VBA Code:
'----- This API declaration must be put below 'Option Explicit' (if present) and above all VBA functions and procedures

#If VBA7 Then
    Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
    Private Declare Sub Sleep Lib "kernel32" (ByVal milliseconds As Long)
#End If

'----- End API declaration 


#If VBA7 Then
Public Function Find_Calculator() As LongPtr
#Else
Public Function Find_Calculator() As Long
#End If
   
    'Find the Calculator window and return its window handle

    Dim UIAuto As IUIAutomation
    Dim Desktop As IUIAutomationElement
    Dim CalcWindow As IUIAutomationElement
    Dim ControlTypeAndNameCond As IUIAutomationCondition
    Dim WindowPattern As IUIAutomationWindowPattern
    
    Find_Calculator = 0

    'Create UIAutomation object
    
    Set UIAuto = New CUIAutomation
    
    'Conditions to find the main Calculator window on the Desktop
    'ControlType:   UIA_WindowControlTypeId (0xC370)
    'Name:          "Calculator"
    
    With UIAuto
        Set Desktop = .GetRootElement
        Set ControlTypeAndNameCond = .CreateAndCondition(.CreatePropertyCondition(UIA_ControlTypePropertyId, UIA_WindowControlTypeId), _
                                                         .CreatePropertyCondition(UIA_NamePropertyId, "Calculator"))
    End With
    Set CalcWindow = Desktop.FindFirst(TreeScope_Children, ControlTypeAndNameCond)
    
    If Not CalcWindow Is Nothing Then
    
        'Restore the Calculator window, because it must not be minimised (off screen/iconic) in order to find the keypad keys
        
        If CalcWindow.CurrentIsOffscreen Then
            Set WindowPattern = CalcWindow.GetCurrentPattern(UIA_WindowPatternId)
            WindowPattern.SetWindowVisualState WindowVisualState.WindowVisualState_Normal
            DoEvents
            Sleep 100
        End If
        
        'Return the Calculator's window handle
        
        Find_Calculator = CalcWindow.GetCurrentPropertyValue(UIA_NativeWindowHandlePropertyId)
                
    End If

End Function
 
Upvote 0

Excel Facts

Last used cell?
Press Ctrl+End to move to what Excel thinks is the last used cell.
John, another strange one. I can find the MenuBar, and the FILE menu, but not the "Open..." submenu.
I tried Children and Descendants.

1658940025504.png



1658940270080.png
 
Upvote 0
I can find the MenuBar, and the FILE menu, but not the "Open..." submenu.
I think you have to click the File menu and then the Open... submenu should be available. Try inserting these lines immediately after the Set MYOBMenu = line to open the File menu:

VBA Code:
    Set InvokePattern = MYOBMenu.GetCurrentPattern(UIA_InvokePatternId)
    InvokePattern.Invoke
    DoEvents
 
Upvote 0
This one has me stumped.
I tried what you suggested and got an "Object not set" error.
I am seeing different windows depending on what I use to inspect (Inspect - UI Automation, Inspect - MSAA, and SPY++).
There seems to be an "Application" menu bar control, which I can find.
There might be a few other layers before the "Open" menu too.
The "Open..." menu also seems to have a different description depending on where I look.
It is "Open... Ctrl+O" in the MSAA view. I have tried a few different things but nothing is getting me all the way down to the "Open" menu item yet.
I will keep trying, but if you spot something I have missed or if you can explain how/why the MSAA view is different, and which one I should be using, that would help me.
Thanks again John.

1658995453503.png


1658995474351.png
 
Upvote 0
I see that there are 2 "File" menus, which is most likely part of the problem.

1659003061996.png
 
Upvote 0
It looks like the easiest option will be to use the AcceleratorKey: CTRL+O.
I will try to find out how to implement that.
 
Upvote 0
John, a Google search has yielded zero examples of how to use an Accelerator Key in UIAutomation.
If you have any pointers please let me know. Thanks.
 
Upvote 0
Have you tried looking for the Application menu bar? Control name = "Application", Control type = UIA_MenuBarControlTypeId.

Also, try clicking the File menu and Open submenu with the 'legacy' pattern. The legacy pattern is available if Inspect shows IsLegacyIAccessiblePatternAvailable: true

VBA Code:
    Dim LegacyPattern As IUIAutomationLegacyIAccessiblePattern

    Set LegacyPattern = MYOBMenu.GetCurrentPattern(UIA_LegacyIAccessiblePatternId)
    MYOBMenu.SetFocus
    LegacyPattern.DoDefaultAction
    DoEvents
    Sleep 100
    'Or, another way of clicking
    'LegacyPattern.Select 2
 
Upvote 0
I was getting as far as setting the MenuBar object, but could not get to the File menu after that.

The MYOBMenu.SetFocus line is triggering the File menu to open now, which is further than I was getting, so many thanks for that.
I will keep plugging away to see if I can get to the OPEN menu now.

The Accelerator Key option really does seem like a great way to do what I need without traversing the menu, so if you have any ideas on how to implement this please do let me know.
I might be the first person to ever attempt this from what the internet search results are returning....! Hardly possible, I know.
 
Upvote 0
Since the MSAA Inspection pane is yielding more results than the UIA window, I thought that maybe I should use that one to get my info from.
Below you can see that NAME property seems to be "Open... Ctrl+O". I can't tell if there are spaces or tabs in that name. That might be why it is proving so difficult to find.
You can also see below that the Ancestors have 3 different "File" objects. Should I not be traversing them all perhaps to get to the "Open" menu item?


1659030844880.png
 
Upvote 0

Forum statistics

Threads
1,223,888
Messages
6,175,219
Members
452,619
Latest member
Shiv1198

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top