Skip to content

Commit

Permalink
Enable finding of undisplayed menu items
Browse files Browse the repository at this point in the history
I found with our UIA app that:

config_item = menu.item_by_path("File -> Configuration", False)

did not work. Pywinauto crashes in fact. Traced to the fact that menu.items() does not see the File menu's items until the File menu is clicked and they are displayed. That is the UIA controls don't exist until the they are displayed. 

This line of code works with this patch, and I can find and then click the configuration item on the FIle menu using:

config_item.click_input()

and all is good.
  • Loading branch information
Bernd Wechner committed Sep 24, 2019
1 parent c86c3b7 commit 104c692
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion pywinauto/controls/uia_controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -938,9 +938,27 @@ def __init__(self, elem):
super(MenuItemWrapper, self).__init__(elem)

# -----------------------------------------------------------
_cache_items = {}
def items(self):
"""Find all items of the menu item"""
return self.children(control_type="MenuItem")
items = self.children(control_type="MenuItem")

# If a menu is not displayed then the UIA controls (children of self)
# will not yet exist. We can bring them into existence by clicking the
# menu (self). The controls can also (mysteriously) lose all their
# element_info. So once we see them bv clicking the menu we cache them
# for subsequent use.
if not items:
if self._cache_items.get(self.element_info.automation_id, None):
items = self._cache_items[self.element_info.automation_id].copy()
else:
self.click_input()
if self.children():
me = self.children()[0]
items = me.children(control_type="MenuItem")
self._cache_items[self.element_info.automation_id] = items.copy()

return items

# -----------------------------------------------------------
def select(self):
Expand Down

0 comments on commit 104c692

Please sign in to comment.