Sign in to follow this  
Followers 0
MyEarth

Click on item of a standard context menu

10 posts in this topic

Hi guys,

Like title i'd like to find the better way to click an item of a context menu.

The only script of this matter ( excluding the old A3LMenu / Toolbar, now i think included in autoit ) is this by Melba:

The problem is MouseClick, not work in every scenario because the context menu is not always in the same position, it can be under the mouse cursor or on the top of the mouse cursor.

Someone knows or have a better idea to improve that script?

Many thanks

Share this post


Link to post
Share on other sites



This can be done with the UI Automation framework.

Download the two UDFs in bottom of first post, and download and run the code in the "Simple spy demo" codebox in the middle of first post.

To verify that a control can be identified place the mouse cursor over the control and press Ctrl+w. You can see an example here.

Note that the framework is based on COM interface objects (created with ObjCreateInterface), so it's not just as easy to use as most built-in commands.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Thanks LarsJ, i have do what you have asked but i don't know what i need to do now :D

Mouse position is retrieved 195-117
At least we have an element [Open path][]
Having the following values for all properties: 
Title is: <Open path>   Class   := <>   controltype:= <UIA_MenuItemControlTypeId>   ,<50011>    , (0000C35B)    
*** Parent Information ***
Title is: <Context> Class   := <#32768> controltype:= <UIA_MenuControlTypeId>   ,<50009>    , (0000C359)    
*** Detailed properties of the highlighted element ***
UIA_AcceleratorKeyPropertyId :=
UIA_AccessKeyPropertyId :=p
UIA_AriaPropertiesPropertyId :=
UIA_AriaRolePropertyId :=
UIA_AutomationIdPropertyId :=100
UIA_BoundingRectanglePropertyId :=99;106;346;22
UIA_ClassNamePropertyId :=
UIA_ClickablePointPropertyId :=
UIA_ControllerForPropertyId :=
UIA_ControlTypePropertyId :=50011
UIA_CulturePropertyId :=0
UIA_DescribedByPropertyId :=
UIA_DockDockPositionPropertyId :=5
UIA_ExpandCollapseExpandCollapseStatePropertyId :=3
UIA_FlowsToPropertyId :=
UIA_FrameworkIdPropertyId :=
UIA_GridColumnCountPropertyId :=0
UIA_GridItemColumnPropertyId :=0
UIA_GridItemColumnSpanPropertyId :=1
UIA_GridItemContainingGridPropertyId :=
UIA_GridItemRowPropertyId :=0
UIA_GridItemRowSpanPropertyId :=1
UIA_GridRowCountPropertyId :=0
UIA_HasKeyboardFocusPropertyId :=True
UIA_HelpTextPropertyId :=
UIA_IsContentElementPropertyId :=True
UIA_IsControlElementPropertyId :=True
UIA_IsDataValidForFormPropertyId :=False
UIA_IsDockPatternAvailablePropertyId :=False
UIA_IsEnabledPropertyId :=True
UIA_IsExpandCollapsePatternAvailablePropertyId :=False
UIA_IsGridItemPatternAvailablePropertyId :=False
UIA_IsGridPatternAvailablePropertyId :=False
UIA_IsInvokePatternAvailablePropertyId :=True
UIA_IsItemContainerPatternAvailablePropertyId :=False
UIA_IsKeyboardFocusablePropertyId :=False
UIA_IsLegacyIAccessiblePatternAvailablePropertyId :=True
UIA_IsMultipleViewPatternAvailablePropertyId :=False
UIA_IsOffscreenPropertyId :=False
UIA_IsPasswordPropertyId :=False
UIA_IsRangeValuePatternAvailablePropertyId :=False
UIA_IsRequiredForFormPropertyId :=False
UIA_IsScrollItemPatternAvailablePropertyId :=False
UIA_IsScrollPatternAvailablePropertyId :=False
UIA_IsSelectionItemPatternAvailablePropertyId :=False
UIA_IsSelectionPatternAvailablePropertyId :=False
UIA_IsSynchronizedInputPatternAvailablePropertyId :=False
UIA_IsTableItemPatternAvailablePropertyId :=False
UIA_IsTablePatternAvailablePropertyId :=False
UIA_IsTextPatternAvailablePropertyId :=False
UIA_IsTogglePatternAvailablePropertyId :=False
UIA_IsTransformPatternAvailablePropertyId :=False
UIA_IsValuePatternAvailablePropertyId :=False
UIA_IsVirtualizedItemPatternAvailablePropertyId :=False
UIA_IsWindowPatternAvailablePropertyId :=False
UIA_ItemStatusPropertyId :=
UIA_ItemTypePropertyId :=
UIA_LabeledByPropertyId :=
UIA_LegacyIAccessibleChildIdPropertyId :=4
UIA_LegacyIAccessibleDefaultActionPropertyId :=Run
UIA_LegacyIAccessibleDescriptionPropertyId :=
UIA_LegacyIAccessibleHelpPropertyId :=
UIA_LegacyIAccessibleKeyboardShortcutPropertyId :=p
UIA_LegacyIAccessibleNamePropertyId :=Open path
UIA_LegacyIAccessibleRolePropertyId :=12
UIA_LegacyIAccessibleSelectionPropertyId :=
UIA_LegacyIAccessibleStatePropertyId :=132
UIA_LegacyIAccessibleValuePropertyId :=
UIA_LocalizedControlTypePropertyId :=Menu Item
UIA_MultipleViewCurrentViewPropertyId :=0
UIA_MultipleViewSupportedViewsPropertyId :=
UIA_NamePropertyId :=Open path
UIA_NativeWindowHandlePropertyId :=0
UIA_OrientationPropertyId :=0
UIA_ProcessIdPropertyId :=1192
UIA_ProviderDescriptionPropertyId :=[pid:1192,hwnd:0x0 Annotation:Microsoft: Annotation Proxy (unmanaged:uiautomationcore.dll); Main(parent link):Microsoft: MSAA Proxy (unmanaged:uiautomationcore.dll)]
UIA_RangeValueIsReadOnlyPropertyId :=True
UIA_RangeValueLargeChangePropertyId :=0
UIA_RangeValueMaximumPropertyId :=0
UIA_RangeValueMinimumPropertyId :=0
UIA_RangeValueSmallChangePropertyId :=0
UIA_RangeValueValuePropertyId :=0
UIA_RuntimeIdPropertyId :=42;524912;2;-2147483646;1192;4915885;4
UIA_ScrollHorizontallyScrollablePropertyId :=False
UIA_ScrollHorizontalScrollPercentPropertyId :=0
UIA_ScrollHorizontalViewSizePropertyId :=100
UIA_ScrollVerticallyScrollablePropertyId :=False
UIA_ScrollVerticalScrollPercentPropertyId :=0
UIA_ScrollVerticalViewSizePropertyId :=100
UIA_SelectionCanSelectMultiplePropertyId :=False
UIA_SelectionIsSelectionRequiredPropertyId :=False
UIA_SelectionselectionPropertyId :=
UIA_SelectionItemIsSelectedPropertyId :=False
UIA_SelectionItemSelectionContainerPropertyId :=
UIA_TableColumnHeadersPropertyId :=
UIA_TableItemColumnHeaderItemsPropertyId :=
UIA_TableRowHeadersPropertyId :=
UIA_TableRowOrColumnMajorPropertyId :=2
UIA_TableItemRowHeaderItemsPropertyId :=
UIA_ToggleToggleStatePropertyId :=2
UIA_TransformCanMovePropertyId :=False
UIA_TransformCanResizePropertyId :=False
UIA_TransformCanRotatePropertyId :=False
UIA_ValueIsReadOnlyPropertyId :=True
UIA_ValueValuePropertyId :=
UIA_WindowCanMaximizePropertyId :=False
UIA_WindowCanMinimizePropertyId :=False
UIA_WindowIsModalPropertyId :=False
UIA_WindowIsTopmostPropertyId :=False
UIA_WindowWindowInteractionStatePropertyId :=0
UIA_WindowWindowVisualStatePropertyId :=0
Edited by MyEarth

Share this post


Link to post
Share on other sites

That depends on what you want. Do you want to open the context menu automatically and click an item? Or is the menu already open, so you just want to click the item?

Share this post


Link to post
Share on other sites

The first, thanks

Share this post


Link to post
Share on other sites

This example selects the second item in Windows Explorer listview, opens the context menu, prints the menu items in Scite console, and invokes the Properties item, that opens the Properties dialog box.

The word Properties is localized (used in bottom of the script). You must replace this word with the word in your own language.

Before you run the example, you must open Windows Explorer in a folder with at least two items. No items should be selected.

 

#include "CUIAutomation2.au3"

Opt( "MustDeclareVars", 1 )

MainFunc()


Func MainFunc()

  ; Windows Explorer on XP, Vista, 7, 8
  Local $hWindow = WinGetHandle( "[REGEXPCLASS:^(Cabinet|Explore)WClass$]" )
  If Not $hWindow Then Return ConsoleWrite( "Window handle ERR" & @CRLF )
  ConsoleWrite( "Window handle OK" & @CRLF )

  ; Create UI Automation object
  Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation )
  If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "UI Automation object ERR" & @CRLF )
  ConsoleWrite( "UI Automation object OK" & @CRLF )

  ; Get UI Automation element from window handle
  Local $pWindow, $oWindow
  $oUIAutomation.ElementFromHandle( $hWindow, $pWindow )
  $oWindow = ObjCreateInterface( $pWindow, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oWindow ) Then Return ConsoleWrite( "Automation element from window ERR" & @CRLF )
  ConsoleWrite( "Automation element from window OK" & @CRLF )

  ; Condition to find listview items
  Local $pCondition
  $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_ListItemControlTypeId, $pCondition )
  If Not $pCondition Then Return ConsoleWrite( "Property condition ERR" & @CRLF )
  ConsoleWrite( "Property condition OK" & @CRLF )

  ; Find listview items
  Local $pUIElementArray, $oUIElementArray, $iElements
  $oWindow.FindAll( $TreeScope_Descendants, $pCondition, $pUIElementArray )
  $oUIElementArray = ObjCreateInterface( $pUIElementArray, $sIID_IUIAutomationElementArray, $dtagIUIAutomationElementArray )
  $oUIElementArray.Length( $iElements )
  If Not ( $iElements > 1 ) Then Return ConsoleWrite( "Find listview items ERR" & @CRLF )
  ConsoleWrite( "Find listview items OK" & @CRLF )

  ; Select second item
  Local $pUIElement, $oUIElement, $pSelection, $oSelection
  $oUIElementArray.GetElement( 1, $pUIElement )
  $oUIElement = ObjCreateInterface( $pUIElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  $oUIElement.GetCurrentPattern( $UIA_SelectionItemPatternId, $pSelection )
  $oSelection = ObjCreateInterface( $pSelection, $sIID_IUIAutomationSelectionItemPattern, $dtagIUIAutomationSelectionItemPattern )
  $oSelection.AddToSelection()
  ConsoleWrite( "Second item selected" & @CRLF )

  ; Open context menu with Shift+F10
  Send("+{F10}")
  Sleep(100)
  ConsoleWrite( "Context menu opened" & @CRLF )

  ; Get UI Automation element for the Desktop
  Local $pDesktop, $oDesktop
  $oUIAutomation.GetRootElement( $pDesktop )
  $oDesktop = ObjCreateInterface( $pDesktop, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oDesktop ) Then Return ConsoleWrite( "Desktop automation element ERR" & @CRLF )
  ConsoleWrite( "Desktop automation element OK" & @CRLF )

  ; Condition to find menu controls
  $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_MenuControlTypeId, $pCondition )
  If Not $pCondition Then Return ConsoleWrite( "Property condition ERR" & @CRLF )
  ConsoleWrite( "Property condition OK" & @CRLF )

  ; Find menu controls
  $oDesktop.FindAll( $TreeScope_Children, $pCondition, $pUIElementArray )
  $oUIElementArray = ObjCreateInterface( $pUIElementArray, $sIID_IUIAutomationElementArray, $dtagIUIAutomationElementArray )
  $oUIElementArray.Length( $iElements )
  If Not ( $iElements = 1 ) Then Return ConsoleWrite( "Find menu controls ERR" & @CRLF )
  ConsoleWrite( "Find menu controls OK" & @CRLF )

  ; Automation element for the menu
  Local $pMenu, $oMenu, $sName
  $oUIElementArray.GetElement( 0, $pMenu )
  $oMenu = ObjCreateInterface( $pMenu, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oMenu ) Then Return ConsoleWrite( "Menu automation element ERR" & @CRLF )
  ConsoleWrite( "Menu automation element OK" & @CRLF )

  ; Condition to find menu items
  $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_MenuItemControlTypeId, $pCondition )
  If Not $pCondition Then Return ConsoleWrite( "Property condition ERR" & @CRLF )
  ConsoleWrite( "Property condition OK" & @CRLF )

  ; Find menu items
  $oMenu.FindAll( $TreeScope_Children, $pCondition, $pUIElementArray )
  $oUIElementArray = ObjCreateInterface( $pUIElementArray, $sIID_IUIAutomationElementArray, $dtagIUIAutomationElementArray )
  $oUIElementArray.Length( $iElements )
  If Not $iElements Then Return ConsoleWrite( "Find menu items ERR" & @CRLF )
  ConsoleWrite( "Find menu items OK" & @CRLF )

  ; Print menu item names
  Local $sName
  ConsoleWrite( "Menu items:" & @CRLF )
  For $i = 0 To $iElements - 1
    $oUIElementArray.GetElement( $i, $pUIElement )
    $oUIElement = ObjCreateInterface( $pUIElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
    $oUIElement.GetCurrentPropertyValue( $UIA_NamePropertyId, $sName )
    ConsoleWrite( "  " & $sName & @CRLF )
  Next

  ; Condition to find "Properties" menu item
  $oUIAutomation.CreatePropertyCondition( $UIA_NamePropertyId, "Properties", $pCondition ) ; <--- Localized ---
  If Not $pCondition Then Return ConsoleWrite( "Property condition ERR" & @CRLF )
  ConsoleWrite( "Property condition OK" & @CRLF )

  ; Find "Properties" menu item
  Local $pMenuItem, $oMenuItem
  $oMenu.FindFirst( $TreeScope_Children, $pCondition, $pMenuItem )
  $oMenuItem = ObjCreateInterface( $pMenuItem, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oMenuItem ) Then Return ConsoleWrite( """Properties"" menu item ERR" & @CRLF )
  ConsoleWrite( """Properties"" menu item OK" & @CRLF )

  ; Click (Invoke) "Properties" menu item
  Local $pInvoke, $oInvoke
  $oMenuItem.GetCurrentPattern( $UIA_InvokePatternId, $pInvoke )
  $oInvoke = ObjCreateInterface( $pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern )
  If Not IsObj( $oInvoke ) Then Return ConsoleWrite( "Invoke object ERR" & @CRLF )
  ConsoleWrite( "Invoke object OK" & @CRLF )
  $oInvoke.Invoke()

EndFunc

Note that most of the small code sections are repeated several times with different objects.

This is the output in Scite console:

Window handle OK
UI Automation object OK
Automation element from window OK
Property condition OK
Find listview items OK
Second item selected
Context menu opened
Desktop automation element OK
Property condition OK
Find menu controls OK
Menu automation element OK
Property condition OK
Find menu items OK
Menu items:
  Open
  Print
  Copy as path
  Restore previous versions
  Send to
  Cut
  Copy
  Create shortcut
  Delete
  Rename
  Properties
Property condition OK
"Properties" menu item OK
Invoke object OK

Share this post


Link to post
Share on other sites

@LarsJ

I am trying to use this example as a way to invoke the "Always available offline" menu item from a file that is located on a network drive. It is always bugging at Find menu controls ERR.

It works great on a local file from the C:\ drive ... Any thoughts or suggestions?

Share this post


Link to post
Share on other sites

If you see the context menu opens, then the most likely error is that 100 ms is too short waiting time on a network drive. This means that the subsequent code is executed before the context menu is open, and therefore fails. You can try to change the 100 ms to 1000 ms. If it works, you can gradually reduce the waiting time until it fails again. The waiting time should be as small as possible but large enough for the context menu to open.

1 person likes this

Share this post


Link to post
Share on other sites

@LarsJ

You are da man! Thank you so kindly! :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0