title: pywinauto: Iterate through all controls in a window
body: <p>I'm trying to write a general test script to find errors in new software builds. My idea is to iterate through the controls in the window and interact with each one, logging any errors that are caused and restarting the software if it crashes.</p>
  
  <p>I'm looking for a way to dynamically find control identifiers, a bit like <code>print_control_identifiers()</code> but with the output being a list or similar structure which I can iterate through.</p>
  
  <p>On a <a href="https://github.com/pywinauto/pywinauto/issues/511" rel="noreferrer">GitHub question</a> about control identifiers this was mentioned:</p>
  
  <blockquote>
    <p>it's possible to walk the hierarchy by using <code>.children()</code> (immediate children only) and <code>.descendants()</code> <strong>(the whole subtree as a plain list)</strong> </p>
  </blockquote>
  
  <p>I assumed I could just iterate through my <code>Application</code> object's <code>descendants()</code> list and call a relavant interaction method for each, however I can't work out how to get this list. I assumed I could do something like this, but I haven't had any success:</p>
  
  <pre><code>def test(application):
      for child in application.descendants():
          #interact with child control
  
  software = Application(backend='uia').start(cmd_line=FILE_PATH)
  test(software)
  </code></pre>
  
  <p><em>AttributeError: Neither GUI element (wrapper) nor wrapper method 'descendants' were found (typo?)</em></p>
  
  <hr>
  
  <p><strong>EDIT</strong></p>
  
  <hr>
  
  <p>I resorted to looking through <a href="https://github.com/pywinauto/pywinauto/blob/master/pywinauto/application.py" rel="noreferrer">the code</a> and found the <code>print_control_identifiers</code> method:</p>
  
  <pre><code>class Application(object):
  
      def print_control_identifiers(self, depth=None, filename=None):
          """
          Prints the 'identifiers'
          Prints identifiers for the control and for its descendants to
          a depth of **depth** (the whole subtree if **None**).
          .. note:: The identifiers printed by this method have been made
                 unique. So if you have 2 edit boxes, they won't both have "Edit"
                 listed in their identifiers. In fact the first one can be
                 referred to as "Edit", "Edit0", "Edit1" and the 2nd should be
                 referred to as "Edit2".
          """
          if depth is None:
              depth = sys.maxsize
          # Wrap this control
          this_ctrl = self.__resolve_control(self.criteria)[-1]
  
          # Create a list of this control and all its descendants
          all_ctrls = [this_ctrl, ] + this_ctrl.descendants()
  
          # Create a list of all visible text controls
          txt_ctrls = [ctrl for ctrl in all_ctrls if ctrl.can_be_label and ctrl.is_visible() and ctrl.window_text()]
  
          # Build a dictionary of disambiguated list of control names
          name_ctrl_id_map = findbestmatch.UniqueDict()
          for index, ctrl in enumerate(all_ctrls):
              ctrl_names = findbestmatch.get_control_names(ctrl, all_ctrls, txt_ctrls)
              for name in ctrl_names:
                  name_ctrl_id_map[name] = index
  
          # Swap it around so that we are mapped off the control indices
          ctrl_id_name_map = {}
          for name, index in name_ctrl_id_map.items():
              ctrl_id_name_map.setdefault(index, []).append(name)
  </code></pre>
  
  <p>This shows that <code>.descendants()</code> isn't a method of the <code>Application</code> class, but belongs to the control. I was wrong there it seems. Is it possible to create my own version of <code>print_control-identifiers()</code> which returns a list of control objects that can be iterated through?</p>