<commit_before>========
How To's
========

How to specify a usable Application instance
---------------------------------------------
An ``Application()`` instance is the point of contact for all work
with the application you are automating. So the Application instance needs
to be connected to a process. There are two ways of doing this:

  ::

    start(self, cmd_line, timeout=app_start_timeout)  # instance method:

or:

  ::

    connect(self, **kwargs)  # instance method:

``start()`` is used when the application is not running and you
need to start it. Use it in the following way:

  ::

   app = Application().start(r"c:\path\to\your\application -a -n -y --arguments")

The timeout parameter is optional, it should only be necessary to use
if the application takes a long time to start up.

``connect()`` is used when the application to be automated is already
launched. To specify an already running application you need to specify
one of the following:

:process: the process id of the application, e.g.

  ::

              app = Application().connect(process=2341)


:handle: The windows handle of a window of the application, e.g.

  ::

              app = Application().connect(handle=0x010f0c)


:path: The path of the executable of the process (``GetModuleFileNameEx``
  is used to find the path of each process and compared against
  the value passed in)  e.g.

  ::

          app = Application().connect(path=r"c:\windows\system32\notepad.exe")


or any combination of the parameters that specify a window, these get
passed to the :func:`pywinauto.findwindows.find_elements()` function.  e.g.

  ::

          app = Application().connect(title_re=".*Notepad", class_name="Notepad")


**Note**: The application has to be ready before you can use connect*().
There is no timeout or retries like there is when finding the application
after start(). So if you start the application outside of pywinauto you
need to either sleep or program a wait loop to wait until the application
has fully started.


How to specify a dialog of the application
------------------------------------------
Once the application instance knows what application it is connected to
a dialog to work on needs to be specified.

There are many different ways of doing this. The most common will be
using item or attribute access to select a dialog based on it's title. e.g

  ::

   dlg = app.Notepad

or equivalently

  ::

   dlg = app['Notepad']

The next easiest method is to ask for the ``top_window()`` e.g.

  ::

    dlg = app.top_window()

This will return the window that has the highest Z-Order of the top-level
windows of the application.

**Note**: This is currently fairly untested so I am not sure it will
return the correct window. It will definitely be a top level window of
the application - it just might not be the one highest in the Z-Order.

If this is not enough control then you can use the same parameters as
can be passed to ``findwindows.find_windows()`` e.g.

  ::

    dlg = app.window(title_re="Page Setup", class_name="#32770")

Finally to have the most control you can use

  ::

    dialogs = app.windows()

this will return a list of all the visible, enabled, top level windows
of the application. You can then use some of the methods in ``handleprops``
module select the dialog you want. Once you have the handle you need
then use

  ::

    app.window(handle=win)

**Note**: If the title of the dialog is very long - then attribute access
might be very long to type, in those cases it is usually easier to use

  ::

    app.window(title_re=".*Part of Title.*")



How to specify a control on a dialog
------------------------------------

There are a number of ways to specify a control, the simplest are

  ::

   app.dlg.control
   app['dlg']['control']


The 2nd is better for non English OS's where you need to pass unicode
strings e.g. ``app[u'your dlg title'][u'your ctrl title']``

The code builds up multiple identifiers for each control from the following:

 - title
 - friendly class
 - title + friendly class

If the control's text is empty (after removing non char characters) text is
not used. Instead we look for the closest control above and to the right fo
the contol. And append the friendly class. So the list becomes

 - friendly class
 - closest text + friendly class

Once a set of identifiers has been created for all controls in the dialog
we disambiguate them.

use the `WindowSpecification.print_control_identifiers()` method

e.g. 
  ::

   app.YourDialog.print_control_identifiers()

Sample output
  ::

    Button - Paper   (L1075, T394, R1411, B485)
            'PaperGroupBox' 'Paper' 'GroupBox'
    Static - Si&ze:   (L1087, T420, R1141, B433)
            'SizeStatic' 'Static' 'Size'
    ComboBox -    (L1159, T418, R1399, B439)
            'ComboBox' 'SizeComboBox'
    Static - &Source:   (L1087, T454, R1141, B467)
            'Source' 'Static' 'SourceStatic'
    ComboBox -    (L1159, T449, R1399, B470)
            'ComboBox' 'SourceComboBox'
    Button - Orientation   (L1075, T493, R1171, B584)<commit_msg>Partial fix for the docs (#305).<commit_after>========
How To's
========

How to specify a usable Application instance
---------------------------------------------
An ``Application()`` instance is the point of contact for all work
with the application you are automating. So the Application instance needs
to be connected to a process. There are two ways of doing this:

  ::

    start(self, cmd_line, timeout=app_start_timeout)  # instance method:

or:

  ::

    connect(self, **kwargs)  # instance method:

``start()`` is used when the application is not running and you
need to start it. Use it in the following way:

  ::

   app = Application().start(r"c:\path\to\your\application -a -n -y --arguments")

The timeout parameter is optional, it should only be necessary to use
if the application takes a long time to start up.

``connect()`` is used when the application to be automated is already
launched. To specify an already running application you need to specify
one of the following:

:process: the process id of the application, e.g.

  ::

              app = Application().connect(process=2341)


:handle: The windows handle of a window of the application, e.g.

  ::

              app = Application().connect(handle=0x010f0c)


:path: The path of the executable of the process (``GetModuleFileNameEx``
  is used to find the path of each process and compared against
  the value passed in)  e.g.

  ::

          app = Application().connect(path=r"c:\windows\system32\notepad.exe")


or any combination of the parameters that specify a window, these get
passed to the :func:`pywinauto.findwindows.find_elements()` function.  e.g.

  ::

          app = Application().connect(title_re=".*Notepad", class_name="Notepad")


**Note**: The application has to be ready before you can use connect*().
There is no timeout or retries like there is when finding the application
after start(). So if you start the application outside of pywinauto you
need to either sleep or program a wait loop to wait until the application
has fully started.


How to specify a dialog of the application
------------------------------------------
Once the application instance knows what application it is connected to
a dialog to work on needs to be specified.

There are many different ways of doing this. The most common will be
using item or attribute access to select a dialog based on it's title. e.g

  ::

   dlg = app.Notepad

or equivalently

  ::

   dlg = app['Notepad']

The next easiest method is to ask for the ``top_window()`` e.g.

  ::

    dlg = app.top_window()

This will return the window that has the highest Z-Order of the top-level
windows of the application.

**Note**: This is currently fairly untested so I am not sure it will
return the correct window. It will definitely be a top level window of
the application - it just might not be the one highest in the Z-Order.

If this is not enough control then you can use the same parameters as
can be passed to ``findwindows.find_windows()`` e.g.

  ::

    dlg = app.window(title_re="Page Setup", class_name="#32770")

Finally to have the most control you can use

  ::

    dialogs = app.windows()

this will return a list of all the visible, enabled, top level windows
of the application. You can then use some of the methods in ``handleprops``
module select the dialog you want. Once you have the handle you need
then use

  ::

    app.window(handle=win)

**Note**: If the title of the dialog is very long - then attribute access
might be very long to type, in those cases it is usually easier to use

  ::

    app.window(title_re=".*Part of Title.*")



How to specify a control on a dialog
------------------------------------

There are a number of ways to specify a control, the simplest are

  ::

   app.dlg.control
   app['dlg']['control']


The 2nd is better for non English OS's where you need to pass unicode
strings e.g. ``app[u'your dlg title'][u'your ctrl title']``

The code builds up multiple identifiers for each control from the following:

 - title
 - friendly class
 - title + friendly class

If the control's title text is empty (after removing non char characters) this text is
not used. Instead we look for the closest title text above and to the right of
the control. And append the friendly class. So the list becomes

 - friendly class
 - closest text + friendly class

Once a set of identifiers has been created for all controls in the dialog
we disambiguate them.

use the `WindowSpecification.print_control_identifiers()` method

e.g. 
  ::

   app.YourDialog.print_control_identifiers()

Sample output
  ::

    Button - Paper   (L1075, T394, R1411, B485)
            'PaperGroupBox' 'Paper' 'GroupBox'
    Static - Si&ze:   (L1087, T420, R1141, B433)
            'SizeStatic' 'Static' 'Size'
    ComboBox -    (L1159, T418, R1399, B439)
            'ComboBox' 'SizeComboBox'
    Static - &Source:   (L1087, T454, R1141, B467)
            'Source' 'Static' 'SourceStatic'
    ComboBox -    (L1159, T449, R1399, B470)
            'ComboBox' 'SourceComboBox'
    Button - Orientation   (L1075, T493, R1171, B584)
{'fraction_non_alphanumeric': 0.10502552021986651, 'fraction_numerical': 0.02012171181782489, 'mean_word_length': 3.0788630904723777, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7269301', 'n_tokens_mistral': 3018, 'n_tokens_neox': 2772, 'n_words': 1355}