Compare commits

...

No commits in common. "master" and "wiki" have entirely different histories.
master ... wiki

211 changed files with 28 additions and 61124 deletions

@ -1,8 +0,0 @@
glob:*.pyc
glob:Copy of *
glob:.buildinfo
glob:.doctrees
glob:docs/_sources
glob:controlspy0798/*
glob:Coverage_report/*
glob:ref_controls.xml

@ -1,167 +0,0 @@
GNU Lesser General Public License
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]
Preamble
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.
To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.
Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.
When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.
We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.
For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.
Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.
You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.
(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.
In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.
Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.
If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:
a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.
7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.
11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).
To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and an idea of what it does.> Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the library 'Frob' (a library for tweaking knobs) written by James Random Hacker.
signature of Ty Coon, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

@ -1,30 +0,0 @@
include Readme.txt
include dev_notes.txt
include HISTORY.TXT
include LICENSE.txt
include TODO.txt
include setup.cfg
include setup.py
include pywinauto
include pywinauto\controls\*.py
include pywinauto\tests\*.py
include pywinauto\unittests\*.py
exclude pywinauto\.svn\*
# include the examples - but not Watsup or .svn directories
include pywinauto\examples\*.pkl
include examples\*.py
include examples\*.txt
exclude examples\.svn\README.txt
exclude examples\examples_watsup\*.*
# include all the website folder and make sure that
# the sub version files are not included
include docs\*.*
exclude docs\.svn\*
exclude docs\pywinauto\.svn\*
exclude docs\pywinauto\controls\.svn\*
exclude docs\pywinauto\tests\.svn\*
exclude docs\.doctrees\*

@ -1,36 +0,0 @@
@echo off
if (%1)==() goto VersionNotGiven
md previousReleases\%1
if not exist previousReleases\%1 goto FolderNotCreated
md previousReleases\%1\DlgCheck2
if not exist previousReleases\%1 goto FolderTwoNotCreated
copy *.py previousReleases\%1
copy dlgCheck2 previousReleases\%1\DlgCheck2
goto finished
:FolderNotCreated
echo.
echo Could not create the folder "previousReleases\%1"
echo.
goto finished
:FolderTwoNotCreated
echo.
echo Could not create the folder "previousReleases\%1\DlgCheck2"
echo.
goto finished
VersionNotGiven
echo.
echo please specify the version of the backup
echo.
goto finished
:finished

28
ProjectHome.md Normal file

@ -0,0 +1,28 @@
Gui Automation with Python
_If you use pywinauto - or you want to get started - then I think SWAPY
http://code.google.com/p/swapy/ is a VERY interesting tool. I have only looked at the video - but that alone convinced me to post a link to it. **VERY COOL**_
![http://wiki.pywinauto.googlecode.com/hg/notepad-simple2-ir.gif](http://wiki.pywinauto.googlecode.com/hg/notepad-simple2-ir.gif)
It is simple and the resulting scripts are very readable. How simple?
```
app.Notepad.MenuSelect("Help->About Notepad")
app.AboutNotepad.OK.Click()
app.Notepad.Edit.TypeKeys ("pywinauto Works!", with_spaces = True)
```
Please see the documentation at: http://pywinauto.googlecode.com/hg/pywinauto/docs/index.html
**Note:** if searching for pywinauto - then you may find links to:
* http://pywinauto.pbworks.com/ - Old wiki - really want to move into docs or here
* https://sourceforge.net/projects/pywinauto
* https://lists.sourceforge.net/lists/listinfo/pywinauto-users - Mailing List (best way to get help)
* Blog (not updated often) http://pywinauto.blogspot.com/
* http://pywinauto.openqa.org/ - Old links may point here (forum and bugs used to be there - but this site is not used anymore)
I am trying to consolidate most information to this site.

@ -1,87 +0,0 @@
pywinauto
(c) Mark Mc Mahon 2006
Released under the LGPL licence
What is it
----------
pywinauto is a set of python modules to automate the Microsoft Windows GUI.
At it's simplest it allows you to send mouse and keyboard actions to windows
dialogs and controls.
Installation
------------
Unzip the pywinauto zip file to a folder.
Install the following Python packages
ctypes http://starship.python.net/crew/theller/ctypes/
Sendkeys http://www.rutherfurd.net/python/sendkeys/index.html
(Optional) PIL http://www.pythonware.com/products/pil/index.htm
(Optional) elementtree http://effbot.org/downloads/
To check you have it installed correctly
run Python
>>> import application
>>> app = application.Application().start_("notepad")
>>> app.notepad.TypeKeys("%FX")
Where to start
--------------
Look at the examples provided in test_application.py
There are examples in there to work with Notepad and MSPaint.
Note: These examples currently only work on English.
How does it work
----------------
A lot is done through attribute access (__getattr__) for each class. For example
when you get the attribute of an Application or Dialog object it looks for a
dialog or control (respectively).
myapp.Notepad # looks for a Window/Dialog of your app that has a title 'similar'
# to "Notepad"
myapp.PageSetup.OK # looks first for a dialog with a title like "PageSetup"
# then it looks for a control on that dialog with a title
# like "OK"
This attribute resolution is delayed (currently a hard coded amount of time) until
it succeeds. So for example if you Select a menu option and then look for the
resulting dialog e.g.
app.Notepad.MenuSelect("File->SaveAs")
app.SaveAs.ComboBox5.Select("UTF-8")
app.SaveAs.edit1.SetText("Example-utf8.txt")
app.SaveAs.Save.Click()
At the 2nd line the SaveAs dialog might not be open by the time this line is
executed. So what happens is that we wait until we have a control to resolve
before resolving the dialog. At that point if we can't find a SaveAs dialog with
a ComboBox5 control then we wait a very short period of time and try again,
this is repeated up to a maximum time (currently 1 second!)
This avoid the user having to use time.sleep or a "WaitForDialog" function.
Some similar tools for comparison
---------------------------------
* Python tools
- Watsup
- winGuiAuto
* Other scripting language tools
- Perl Win32::GuiTest
- Ruby GuiTest
- others?
* Other free tools
- AutoIt
- See collection at:
* Commercial tools
- WinRunner
- SilkTest
- Visual Test
- Many Others

@ -1,686 +0,0 @@
==========
Change Log
==========
0.4.0 Various cleanup and bug fixes.
------------------------------------------------------------------
03-April-2010
* Gracefully Handle dir() calls on Application or WindowSpecification objects
(which used hang for a while as these classes would search for windows
matching __members__, __methods__ and __bases__). The code now checks for
any attribute that starts with '__' and ends with '__' and raises
AttributeError immediately. Thanks to Sebastian Haase for raising this.
* Removed the reference to an Application object in WindowSpecification.
It was not used in the class and made the class harder to use.
WindowSpecification is now more useful as a utility class.
* Add imports of application.WindowSpecification and application.Application
to pywinauto.__init__.py so that these classes can be used more easily
(without having to directly import pywinauto.application). Thanks again to
Sebastian Haase.
* Added a function to empty the clipboard (thanks to Tocer on Sourceforge)
* Use 'SendMessageTimeout' to get the text of a window. (SendMessage will hang
if the application is not processing messages)
* Fixed references to PIL.ImageGrab. PIL add's it's module directly to the
module path, so it should just be referenced by ImageGrab and not
PIL.ImageGrab.
* Use AttachThreadInput + PostMessage rather than SendMessageTimeout to send
mouse clicks.
* Fix how timeout retry times are calculated in timings.WaitUntil() and
timings.Wait
* Fixed some issues with application.Kill_() method, highlighted due to the
changes in the HwndWrapper.Close() method.
* Fix writing images to XML. It was broken with updates to PIL that I had not
followed. Changed the method of knowing if it is an image by checking for
various attributes.
* Renamed WindowSpecification.(Ww)indow() to ChildWindow() and added
deprecation messages for the other functions.
* Improved the tests (fixed test failures which were not pywinauto issues)
0.3.9 Experimental! New Sendkeys, and various fixes
------------------------------------------------------------------
27-November-2009
* Major change this release is that Sendkeys is no longer a requirement!
A replacement that supports Unicode is included with pywinauto. (hopefully
soon to be released as a standalone module). Please note - this is still
quite untested so this release should be treated with some care..
* Made sure that default for WindowSpecification.Window_() was to look
for non top level windows. The defaults in find_windows() had been
changed previously and it now needed to be explicitly overridden.
* Fixed a missing reference to 'win32defines' when referencing WAIT_TIMEOUT
another typo of false (changed to False)
* Removed the restriction to only get the active windows for the process,
now it will be possible to get the active windows, even if a process is
not specified.
From http://msdn.microsoft.com/en-us/library/ms633506%28VS.85%29.aspx
it gets the active window for the foreground thread.
* Hopefully improved Delphi TreeView and ListView handling (added window
class names as supported window classes to the appropriate classes).
* Added support for running UI tests with reference controls. (requried
for some localization tests)
* Various PyLint and PEP8 fixes made.
0.3.8 Collecting improvements from last 2 years
------------------------------------------------------------------
10-March-2009
* Fixed toolbar button pressing - This required for
HwndWrapper.NotifyParent() to be updated (to accept a new
ID parameter)
* Fixed a bug wherea listview without a column control would
make pywinauto fail to capture the dialog.
* Converted documenation from Pudge generated to Sphinx Generated
* Added some baic support for Pager and Progress controls
(no tests yet)
* Added some more VB 'edit' window classes
* Added some more VB 'listbox' window classes
* Added some more VB 'button' window classes
* Ensured that return value from ComboBoxWrapper.SelectedIndices
is always a tuple (there was a bug where it would sometimes be
a ctypes array)
* Changed default for finding windows to find disabled windows
as well as enabled ones (previous was to find enabled windows only)
(note this may impact scripts that relied on the previous
setting i.e. in cases where two dialogs have the same title!)
* Much better handling of InvalidWindowHandle during automation
runs. This could be raised when a closing window is still available
when the automation was called, but is gone half way through
whatever function was called.
* Made clicking more robust by adding a tiny wait between each
SendMessageTimeout in _perform_click().
* Added attributes ``can_be_label`` and ``has_title`` to ``HwndWrapper``
and subclasses to specify whether a control can act as a label for
other controls, and whether the title should be used for identifying
the control. If you have created your own HwndWrapper subclasses you
may need to override the defaults.
* Added a ``control_id`` parameter to find_windows which allows
finding windows based off of their control id's
* Added a FriendlyClassName method to MenuItem
* Split up the functions for button truncation data
* Commented out code to get a new font if the font could not
be recovered
* Moved code to get the control font from Truncation test to
handleprops
* Added a function to get the string representation of the
bug. (need to refactor PrintBugs at some point).
* Fixed a variable name (from fname -> font_attrib as fname
was not a defined variable!)
* Forced some return values from MissingExtraString test
to be Unicode
* Fixed the MiscValues test (converted to Unicode and
removed some extraneous characters)
* Updated the path for all unittests
* Made two unit tests sligthly more robust and less dependent
on computer/app settings
* Updated timing settings for unit tests
* Updated the examples to work in dev environment.
0.3.7 Merge of Wait changes and various bug fixes/improvements
------------------------------------------------------------------
10-April-2007
* Added Timings.WaitUntil() and Timings.WaitUntilPasses() which
handle the various wait until something in the code. Also
refactored existing waits to use these two methods.
* Fixed a major Handle leak in RemoteMemorBlock class (which is
used extensively for 'Common' controls. I was using OpenHandle
to open the process handle, but was not calling CloseHandle()
for each corresponding OpenHandle().
* Added an active_() method to Application class to return the
active window of the application.
* Added an 'active' option to WindowSpecification.Wait() and
WaitNot().
* Some cleanup of the clipboard module. GetFormatName()
was improved and GetData() made a little more robust.
* Added an option to findwindows.find_windows() to find only
active windows (e.g. active_only = True). Default is False.
* Fixed a bug in the timings.Timings class - timing values are
Now accessed through the class (Timings) and not through the
intance (self).
* Updated ElementTree import in XMLHelpers so that it would work
on Python 2.5 (where elementtree is a standard module) as well
as other versions where ElementTree is a separate module.
* Enhanced Item selection for ListViews, TreeViews - it is now
possible to pass strings and they will be searched for. More
documentation is required though.
* Greatly enhanced Toolbar button clicking, selection, etc.
Though more documentation is required.
* Added option to ClickInput() to allow mouse wheel movements
to be made.
* menuwrapper.Menu.GetProperties() now returns a dict like all other
GetProperties() methods. This dict for now only has one key
'MenuItems' which contains the list of menuitems (which had been
the previous return value).
0.3.6b Changes not documented in 0.3.6 history
------------------------------------------------------------------
31-July-2006
* Fixed a bug in how findbestmatch.FindBestMatches was working.
It would match against text when it should not!
* Updated how timings.Timings.Slow() worked, if any time setting
was less then .2 after 'slowing' then set it to .2
0.3.6 Scrolling and Treview Item Clicking added
------------------------------------------------------------------
28-July-2006
* Added parameter to ``_treeview_item.Rectangle()`` to have an option
to get the Text rectangle of the item. And defaulted to this.
* Added ``_treeview_item.Click()`` method to make it easy to click
on tree view items.
* Fixed a bug in ``TreeView.GetItem()`` that was expanding items
when it shouldn't.
* Added ``HwndWrapper.Scroll()`` method to allow scrolling. This
is a very minimal implementation - and if the scrollbars are
implemented as separate controls (rather then a property of a
control - this will probably not work for you!). It works for
Notepad and Paint - that is all I have tried so far.
* Added a call to ``HwndWrapper.SetFocus()`` in
``_perform_click_input()`` so that calls to
``HwndWrapper.ClickInput()`` will make sure to click on the
correct window.
0.3.5 Moved to Metaclass control wrapping
------------------------------------------------------------------
24-May-2006
* Moved to a metaclass implementation of control finding. This
removes some cyclic importing that had to be worked around and
other then metaclass magic makes the code a bit simpler.
* Some of the sample files would not run - so I updated them
so they would (Thanks to Stefaan Himpe for pointing this out)
* Disabled saving application data (it was still being saved in
Application.RecordMatch() even if the rest of the application
data code is disabled. This was causing what appeared to be a
memory leak where pywinauto would keep grabbing more and more
memory (especially for controls that contain a lot of
information). Thanks to Frank Martinez for leading me to this).
* Added ListViewWrapper.GetItemRect() to enable retrieving the
rectangle for a particular item in the listview.
* Removed references to _ctrl() method within pywinauto as it
was raising a DeprecationWarning internally even if the user
was not using it.
0.3.4 Fixed issue with latest ctypes, speed gains, other changes
------------------------------------------------------------------
25-Apr-2006
* The latest version of ctypes (0.9.9.6) removed the code generator
I was using some generated code in win32functions.py (stdcall). I
was not using those functions so I just commented them out.
* Started the process of renaming methods of the ``Application`` and
``WindowSpecification`` classes. I will be converting names to
``UppercaseNames_()``. The trailing ``_`` is to disambiguate the
method names from potential Window titles.
* Updated how print_control_identifiers works so that it now always
prints the disambiguated control name. (even for single controls)
* Added __hash__ to HwndWrapper so that controls could be dictionary
keys.
* Caching various information at various points. For example I cache
how well two pieces of text match. For short scripts this has
little impact - but for larger script it could well have a major
impact.
Also caching information for controls that cannot change
e.g. TopLeveParent, Parent, etc
0.3.3 Added some methods, and fixed some small bugs
------------------------------------------------------------------
19-Apr-2006
* Added a wait for the control to be active and configurable
sleeps after 'modifying' actions (e.g. Select, Deselect, etc)
* Fixed Timings.Slow() and Timings.Fast() - they could in certain
circumstances do the opposite! If you had already set a timing
slower or faster then they would set it then they would blindly
ignore that and set their own times. I added functionality that
they will take either the slowest or fastest of the new/current
setting rather then blindly setting to the new value.
* Fixed some hidden bugs with HwndWrapper.CloseClick()
* Fixed a bug in setup.py that would raise an error when no
argument was specified
* Added an argument to HwndWrapper.SendMessageTimeout so that
the wait options could be passed in.
* Added HwndWrapper.Close(), Maximize(), Minimize(), Restore()
and GetShowState().
* Commented out all deprecated methods (will be removed completely
in some future release).
* Added Application.kill_() method - which closes all windows and
kills the application. If the application is asking if you want
to save your changes - you will not be able to click yes or no
and the application will be killed anyway!.
0.3.2 Fixed setup.py and some typos
------------------------------------------------------------------
31-Mar-2006
* Fixed the spelling of Stefaan Himpe's name
* Fixed setup.py which was working for creating a distribution but
not for installing it (again thanks to Stefaan for pointing it out!)
0.3.1 Performance tune-ups
------------------------------------------------------------------
30-Mar-2006
* Change calculation of distance in findbestmatch.GetNonTextControlName()
so that it does not need to square or get the square root to
find the real distance - as we only need to compare values - not have
the actual distance. (Thanks to Stefaan Himpe)
* Compiled regular expression patterns before doing the match to
avoid compiling the regular expression for window that is being
tested (Thanks to Stefaan Himpe)
* Made it easier to add your own control tests by adding a file
extra_tests.py which needs to export a ModifyRegisteredTests() method.
Also cleaned up the code a little.
* Updated notepad_fast.py to make it easier to profile (adde a method)
* Changed WrapHandle to use a cache for classes it has matched - this is
to avoid having to match against all classes constantly.
* Changed default timeout in SendMessageTimeout to .001 seconds from .4
seconds this results in a significant speedup. Will need to make this
value modifiable via the timing module/routine.
* WaitNot was raising an error if the control was not found - it should
have returned (i.e. success - control is not in any particular state
because it does not exist!).
* Added ListViewWrapper.Deselect() per Chistophe Keller's suggestion.
While I was at it I added a check on the item value passed in and added
a call to WaitGuiIdle(self) so that the control has a chance to process
the message.
* Changed doc templates and moved dependencies into pywinauto
subversion to ensure that all files were availabe at www.openqa.org and
that they are not broken when viewed there.
* Moved all timing information into the timings.Timings class. There are
some simple methods for changing the timings.
0.3.0 Added Application data - now useful for localization testing
------------------------------------------------------------------
20-Mar-2006
* Added automatic Application data collection which can be used when
running the same test on a different spoken language version. Support
is still preliminary and is expected to change. Please treat as early
Alpha.
If you have a different language version of Windows then you can try
this out by running the notepad_fast.py example with the langauge
argument e.g. ::
examples\notepad_fast.py language
This will load the application data from the supplied file
notepad_fast.pkl and use it for finding the right menu items and
controls to select.
* Test implementation to make it easier to start using an application.
Previously you needed to write code like ::
app = Application().connect_(title = 'Find')
app.Find.Close.Click()
app.NotePad.MenuSelect("File->Exit")
1st change was to implement static methods ``start()`` and
``connect()``. These methods return a new Application instance
so the above code becomes::
app = Application.connect(title = 'Find')
app.Find.Close.Click()
app.NotePad.MenuSelect("File->Exit")
I also wanted to make it easier to start working with a simple
application - that may or may not have only one dialog. To make this
situation easier I made ``window_()`` not throw if the application has not
been ``start()ed`` or ``connect()ed`` first. This leads to simpler code
like::
app = Application()
app.Find.Close.Click()
app.NotePad.MenuSelect("File->Exit")
What happens here is that when you execute any of Application.window_(),
Application.__getattr__() or Application.__getitem__() when the
application hasn't been connected or started. It looks for the window
that best matches your specification and connects the application to
that process.
This is extra functionality - existing connect_() and
start_() methods still exist
* Fixed HwndWrapper.SetFocus() so that it would work even if the window
was not in the foreground. (it now makes the window foreground as well
as giving it focus). This overcomes a restriction in Windows where
you can only change the foreground window if you own the foreground
window.
* Changed some 2.4'isms that an anonymous commenter left on my blog :-)
with these changes pywinauto should run on Python 2.3 (though I haven't
done extensive testing).
* Commented out controls.common_controls.TabControlWrapper.GetTabState()
and TabStates() as these did not seem to be returning valid values anyway.
* Fixed documentation issues were parts of the documentation were not
getting generated to the HTML files.
* Fixed issue where MenuSelect would sometimes not work as expected.
Some Menu actions require that the window that owns the menu be active.
Added a call to SetFocus() before selecting a menu item to ensure that
the window was active.
* Fixed Bug 1452832 where clipboard was not closed in clipboard.GetData()
* Added more unit tests now up to 248 from 207
0.2.5 More refactoring, more tests
------------------------------------------------
07-Mar-2006
* Added wrapper classes for Menus and MenuItems this enabled cleaner
interaction with Menu's. It also gives more functionality - you can now
programmatically Click() on menus, and query if a menu item is checked
or not.
* Added application.WindowSpecification.Wait() and WaitNot() methods.
These methods allow you to wait for a control to exist, be visible,
be enabled, be ready (both enabled and visible!) or to wait for the
control to not be in any of these states. WaitReady(),
WaitNotEnabled(), WaitNotVisible() now use these methods. I was able to also
add the missing methods WaitNotReady(), WaitEnabled(), WaitVisible(),
WaitExists(), WaitnotExists(). Please use Wait() and WaitNot() as I have
Deprecated these Wait* methods.
* Slightly modified timeout waits for control resolution so that a timed
function more accurately follows the timeout value specified.
* Added application.Application.start() and connect() static methods. These
methods are factory methods in that they will return an initialized Application
instance. They work exactly the same as start_() and connect() as they are
implemented in terms of those.
from pywinauto.application import Application
notepad = Application.start("notepad")
same_notepad = Application.connect(path = "notepad")
* Updated the examples to follow changes to the code - and to make them a little
more robust.
* Added a new Controls Overview document page which lists all the actions on
all controls.
* Added more unit tests now up to 207 from 134 (added 68 tests)
0.2.1 Small Release number - big changes
------------------------------------------------
17-Feb-2006
* Quick release to get many changes out there - but this release has
been less tested then I would like for a .3 release.
* Allow access to non text controls using the closest Text control.
This closest text control will normally be the static/label associated
with the control. For example in Notepad, Format->Font dialog, the 1st
combobox can be refered to as "FontComboBox" rather than "ComboBox1"
* Added a new control wrapper - ``PopupMenuWrapper`` for context menu's
You can now work easily with context menu's
e.g. ::
app.Notepad.Edit.RightClick()
# need to use MenuClick rather then MenuSelect
app.PopupMenu.MenuClick("Select All")
app.Notepad.Edit.RightClick()
app.PopupMenu.MenuClick("Copy")
I could think of merging the ``RightClick()`` and ``MenuSelect()`` into one method
``ContextMenuSelect()`` if that makes sense to most people.
* Added Support for Up-Down controls
* Not all top level windows now have a FriendlyClassName of "Dialog".
I changed this because it made it hard to get windows of a particular
class. For example the main Notepad window has a class name of "Notepad".
This was primarily implemented due to work I did getting the System Tray.
* Renamed ``StatusBarWrapper.PartWidths()`` to ``PartRightEdges()`` as this
is more correct for what it returns.
* Changed HwndWrapper.Text() and SetText() to WindowText() and
SetWindowText() respectively to try and make it clearer that it is
the text returned by GetWindowText and not the text that is visible
on the control. This change also suggested that EditWrapper.SetText()
be changed to SetEditText() (though this is not a hard requirement
EditWrapper.SetText() still exists - but may be deprecated.
* Added ClickInput, DoubleClickInput, RightClickInput, PressMouseInput
ReleaseMouseInput to HwndWrapper - these use SendInput rather then
WM_LBUTTONDOWN, WM_RBUTTONUP, etc used by Click, DoubleClick etc.
I also added a MenuClick method that allows you to click on menu
items. This means you can now 'physically' drop menus down.
* Some further working with tooltips that need to be cleaned up.
* Fixed a bug where coordinates passed to any of the Click operations had
the X and Y coordinates swapped.
* Added new MenuItem and Menu classes that are to the most part hidden
but you can get a menu item by doing ::
app.Notepad.MenuItem("View")
app.Notepad.MenuItem("View->Status Bar")
MenuItems have various actions so for example you can use
``MenuItem.IsChecked()`` to check if the menu item is checked.
Among other methods there are ``Click()`` and ``Enabled()``.
* Modified the 'best match' algorithm for finding controls.
It now searches a couple of times, and tries to find the best
fit for the text passed to it. The idea here is to make it more
"Select what I want - not that other thing that looks a bit like
what I want!". It is possible this change could mean you need to
use new identifiers in scripts - but in general very little modification
should be necessary.
There was also a change to the algorithm that looked for the closest
text control. It missed some obvious controls in the previous
implementation. It also had a bug for controls above the control
rather than to the left.
* Added a new example scripts SaveFromInternetExplorer.py and
SaveFromFirefox.py which show automating downloading of a page
from either of these browsers.
* Added yet more unit tests, there are now a total of 134 tests.
0.2.0 Significant refactoring
------------------------------------------------
06-Feb-2006
* Changed how windows are searched for (from application)
This chage should not be a significant change for users
* Started adding unit tests (and the have already uncovered bugs
that been fixed). They also point to areas of missing functionality
that will be addded with future updates
* Changed from property access to Control attributes to function access
If your code was accessing properties of controls then this might be a
significant change! The main reasons for doing this were due to the
inheritability of properties (or lack there-of!) and the additional
scafolding that was required to define them all.
* Updated the ``DialogWrapper.MenuSelect()`` method to notify the parent
that it needs to initialize the menu's before it retrieves the items
* Added functionality to associate 'non-text' controls with the 'text'
control closest to them. This allows controls to be referenced by::
app.dlg.<Nearby_text><Window_class>
e.g. to reference the "Footer" edit control in the Page Setup dialog
you could use::
app.PageSetup.FooterEdit
* Added a MoveWindow method to HwndWrapper
* Did some more cleanup (fixing pylint warnings) but still not finished
* Added some better support for .NET controls (not to be considered final)
0.1.3 Many changes, few visible
------------------------------------------------
15-Jan-2006
* Wrote doc strings for all modules, classes and functions
* Ran pychecker and pylint and fixed some errors/warning
* changed ::
_connect, _start, _window, _control, _write
respectively to ::
connect_, start_, window_, connect_, write_
If you forget to change ``_window``, ``_connect`` and ``_start`` then you will probably get the following error. ::
TypeError: '_DynamicAttributes' object is not callable
* pywinauto is now a package name - you need to import it or its modules
* Changes to the code to deal with pywinauto package name
* Fixed searching for windows if a Parent is passed in
* Added Index to retrieved MenuItem dictionary
* Added a check to ensure that a windows Handle is a valid window
* Refactored some of the methods in common_controls
* Refactored how FriendlyClassName is discovered (and still not really happy!
0.1.2 Add Readme and rollup various changes
------------------------------------------------
15-Jan-2006
* Updated Readme (original readme was incorrect)
* Added clipboard module
* Fixed DrawOutline part of tests.__init__.print_bugs
* Added a NotifyParent to HwndWrapper
* Make sure that HwndWrapper.ref is initialized to None
* Refactored some methods of ComboBox and ListBox
* Updated Combo/ListBox selection methods
* Removed hardcoded paths from test_application.py
* Added section to save the document as UTF-8 in MinimalNotepadTest
* Fixed EscapeSpecials and UnEscapeSpecials in XMLHelpers
* Made sure that overly large bitmaps do not break XML writing
0.1.1 Minor bug fix release
------------------------------------------------
12-Jan-2006
* Fixed some minor bugs discovered after release
0.1.0 Initial Release
------------------------------------------------
6-Jan-2006

@ -1,445 +0,0 @@
========
How To's
========
How to sepcify an usable Application instance
---------------------------------------------
An ``Application()`` instance is the point of contact for all work
with the app 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):
or:
::
connect_(self, **kwargs):
``start_()`` is used when the application is not running and you
need to start it. Use it in the following way:
::
app = Application()
app.start_(r"c:\path\to\your\application -a -n -y --arguments")
The timeout parameter is optional, it should only be necessary to use
it if the application takes a long time to start up.
``connect_()`` is used when the application to be automated is already
running. To specify a an already runing application you need to specify
one of the following:
:process: the process id of the application, e.g.
::
app = Application()
app.connect_(process = 2341)
:handle: The windows handle of a window of the application, e.g.
::
app = Application()
app.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()
app.connect_(path = r"c:\windows\system32\notepad.exe")
or any combination of the parameters that specify a window, these get
passed to the ``findwindows.find_windows()`` function. e.g.
::
app = Application()
app.connect_(title_re = ".*Notepad", class_name = "Notepad")
**Note**: I have since added static methods Application.start() and
Application.connect() these can be used the same as above - except that
you no longer need to instantiate an Application object first.
**Note2**: 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 sepcify 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 they 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
::
Application.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)
'GroupBox' 'Orientation' 'OrientationGroupBox'
Button - P&ortrait (L1087, T514, R1165, B534)
'Portrait' 'RadioButton' 'PortraitRadioButton'
Button - L&andscape (L1087, T548, R1165, B568)
'RadioButton' 'LandscapeRadioButton' 'Landscape'
Button - Margins (inches) (L1183, T493, R1411, B584)
'Marginsinches' 'MarginsinchesGroupBox' 'GroupBox'
Static - &Left: (L1195, T519, R1243, B532)
'LeftStatic' 'Static' 'Left'
Edit - (L1243, T514, R1285, B534)
'Edit' 'LeftEdit'
Static - &Right: (L1309, T519, R1357, B532)
'Right' 'Static' 'RightStatic'
Edit - (L1357, T514, R1399, B534)
'Edit' 'RightEdit'
Static - &Top: (L1195, T550, R1243, B563)
'Top' 'Static' 'TopStatic'
Edit - (L1243, T548, R1285, B568)
'Edit' 'TopEdit'
Static - &Bottom: (L1309, T550, R1357, B563)
'BottomStatic' 'Static' 'Bottom'
Edit - (L1357, T548, R1399, B568)
'Edit' 'BottomEdit'
Static - &Header: (L1075, T600, R1119, B613)
'Header' 'Static' 'HeaderStatic'
Edit - (L1147, T599, R1408, B619)
'Edit' 'TopEdit'
Static - &Footer: (L1075, T631, R1119, B644)
'FooterStatic' 'Static' 'Footer'
Edit - (L1147, T630, R1408, B650)
'Edit' 'FooterEdit'
Button - OK (L1348, T664, R1423, B687)
'Button' 'OK' 'OKButton'
Button - Cancel (L1429, T664, R1504, B687)
'Cancel' 'Button' 'CancelButton'
Button - &Printer... (L1510, T664, R1585, B687)
'Button' 'Printer' 'PrinterButton'
Button - Preview (L1423, T394, R1585, B651)
'Preview' 'GroupBox' 'PreviewGroupBox'
Static - (L1458, T456, R1549, B586)
'PreviewStatic' 'Static'
Static - (L1549, T464, R1557, B594)
'PreviewStatic' 'Static'
Static - (L1466, T586, R1557, B594)
'Static' 'BottomStatic'
This exmple has been taken from test_application.py
**Note** The identifiers printed by this method have been run through
the process that makes the identifier unique. So if you have 2 edit boxes,
they will both have "Edit" listed in their identifiers. In reality though
the first one can be refered to as "Edit", "Edit0", "Edit1" and the 2nd
should be refered to as "Edit2"
**Note** You do not have to be exact!. Say we take an instance from the
example above
::
Button - Margins (inches) (L1183, T493, R1411, B584)
'Marginsinches' 'MarginsinchesGroupBox' 'GroupBox'
Let's say that you don't like any of these
- ``GroupBox`` - too generic, it could be any group box
- ``Marginsinches`` and ``MarginsinchesGroupBox`` - these just don'
look right, it would be nicer to leave out the 'inches' part
Well you CAN! The code does a best match on the identifer you use against
all the available identifiers in the dialog.
For example if you break into the debugger you can see how different
identifiers can be used
::
(Pdb) print app.PageSetup.Margins.Text()
Margins (inches)
(Pdb) print app.PageSetup.MarginsGroupBox.Text()
Margins (inches)
And this will also cater for typos. Though you still have to be careful
as if there are 2 similar identifiers in the dialog the typo you have
used might be more similar to another control then the one you were
thinking of.
How to use pywinauto with application languages other than English
------------------------------------------------------------------
Because Python does not support unicode identifiers in code
you cannot use attribute access to reference a control so
you would either have to use item access or make an explicit
calls to ``window_()``.
So instead of writing
::
app.dialog_ident.control_ident.Click()
You would have to write
::
app['dialog_ident']['control_ident'].Click()
Or use ``window_()`` explictly
::
app.window_(title_re = "NonAsciiCharacters").window_(title = "MoreNonAsciiCharacters").Click()
To see an example of this see ``examples\MiscExamples.py.GetInfo()``
How to deal with controls that do not respond as expected (e.g. OwnerDraw Controls)
------------------------------------------------------------------------------------
Some controls (especially Ownerdrawn controls) do not respond to events as
expected. For example if you look at any HLP file and go to the Index Tab (click
'Search' button) you will see a listbox. Running Spy or Winspector on this
will show you that it is indeed a list box - but it is ownerdrawn. This means
that the developer has told Windows that they will override how items are displayed
and do it themselves. And in this case they have made it so that strings cannot be
retrieved :-(.
So what problems does this cause?
::
app.HelpTopics.ListBox.Texts() # 1
app.HelpTopics.ListBox.Select("ItemInList") # 2
1. Will return a list of empty strings, all this means is that pywinauto has not
been able to get the strings in the listbox
2. This will fail with an IndexError because the Select(string) method of a ListBox
looks for the item in the Texts to know the index of the item that it should select.
The following workaround will work on this control
::
app.HelpTopics.ListBox.Select(1)
This will select the 2nd item in the listbox, because it is not a string lookup
it works correctly.
Unfortunately not even this will always work. The developer can make it so that the
control does not respond to standard events like Select. In this case the only way
you can select items in the listbox is by using the keyboard simulation of TypeKeys().
This allows you to send any keystrokes to a control. So to select the 3rd item you
would use
::
app.Helptopics.ListBox1.TypeKeys("{HOME}{DOWN 2}{ENTER}")
- ``{HOME}`` will make sure that the first item is highlighted.
- ``{DOWN 2}`` will then move the highlight down 2 items
- ``{ENTER}`` will select the highlighted item
If your application made extensive use of a similar control type then you could
make using it easier by deriving a new class from ListBox, that could use extra
knowledge about your particular application. For example in the WinHelp example
evertime an item is highlighted in the list view, it's text is inserted into the
Edit control above the list, and you CAN get the text of the item from there e.g.
::
# print the text of the item currently selected in the list box
# (as long as you are not typing into the Edit control!)
print app.HelpTopics.Edit.Texts()[1]
How to Access the System Tray (aka SysTray, aka 'Notification Area')
------------------------------------------------------------------------------------
Near the clock are icons representing running applications, this area is
normally referred to as the "System Tray". There are actually many different
windows/controls in this area. The control that contains the icons is actually
a toolbar. It is in a Pager control, in within a window with a class TrayNotifyWnd,
which is in yet another window with a class Shell_TrayWnd and all these windows
are part of the running Explorer instance. Thankfully you don't need to remeber
all that :-).
The things that are important to remember is that you are looking for a
window in the "Explorer.exe" application with the class "Shell_TrayWnd" that has
a Toolbar control with a title "Notification Area".
One way to get this is to do the following
::
imprt pywinauto.application
app = pywinauto.application.Application().connect_(path = "explorer")
systray_icons = app.ShellTrayWnd.NotificationAreaToolbar
The taskbar module provides very preliminary access to the System Tray.
It defines the following variables:
:explorer_app: defines an Application() object connected to the running
explorer. You probably don't need to use this your self
very much.
:TaskBar: The handle to the task bar (the bar containing Start Button,
the QuickLaunch icons, running tasks, etc
:StartButton: "Start me up" :-) I think you might know what this is!
:QuickLaunch: The Toolbar with the quick launch icons
:SystemTray: The window that contains the Clock and System Tray Icons
:Clock: The clock
:SystemTrayIcons: The toolbar representing the system tray icons
:RunningApplications: The toolbar representing the running applications
I have also provided 2 functions in the module that can be used to click on
system tray icons:
:``ClickSystemTrayIcon(button)``: You can use this to left click a visible icon
in the system tray. I had to specifically say
visible icon as there may be many invisible
icons that obviously cannot be clicked. Button
can be any integer. If you specify 3 then it will
find and click the 3rd visible button. (very little
error checking is performed and this method will
more then likely be moved/renamed in the futures.
:``RightClickSystemTrayIcon(button)``: Similar to ``ClickSytemTrayIcon`` but
performs a right click.
Often when you click/right click on an icon - you get a popup menu. The thing to
remember at this point is that the popup menu is part of the application being
automated not part of explorer.
e.g.
::
# connect to outlook
outlook = Application().connect_(path = 'outlook.exe')
# click on Outlook's icon
taskbar.ClickSystemTrayIcon(2)
# Select an item in the popup menu
outlook.PopupMenu.MenuClick("Cancel Server Request")

@ -1,174 +0,0 @@
============================================================================
PYWINAUTO TODO's
============================================================================
* Make sure to add documentation strings for all undocumented methods/functions
* Check coverage of the tests and work to increase it.
* Add tests for SendInput click methods
* Implement findbestmatch using FuzzyDict.
* Find a way of doing application data in a better way. Currently if someone
even adds a call to print_control_identifiers() it will break the matching
algorithm!
* Need to move the checking if a control is a Ownerdrawn/bitmap control out
of __init__ methods and into it's own method something like
IsNormallyRendered() (Why?)
* Give example how to work with Tray Window
* Fix ToolbarWrapper.PressButton() which doesn't seem to work (found wile working
on IE example script)
* Maybe supply an option so that scripts can be run by using::
pywinauto.exe yourscript.py
This would work by creating a Py2exe wrapper that would import the script
(and optionally call a particular function?)
This way pywinauto could be made available to people without python
installed (whether this is a big requirement or not I don't know
because the automation language is python anyway!.
* Message traps - how to handle unwanted message boxes popping up?
a) Wait for an Exception then handle it there
b) set a trap waiting for a specific dialog
c) on calls to window specification, if we fail to find our window then we can
run quickly through the available specified traps to see if any of them apply
- then if they do we can run the associated actions - then try our original
dialog again
* Handle adding reference controls (in that they should be the controls used
for finding windows)
* Find the reference name of a variable e.g so that in Dialog._write() we
can know the variable name that called the _write on (this we don't have
to repeat the XML file name!)
* If we remove the delay after a button click in controlactions then
trying to close two dialogs in a row might fail because the first
dialog hasn't closed yet and the 2nd may have similar title and
same closing button e.g PageSetup.OK.Click(), PageSetup2.OK.Click().
A possible solution to this might be to keep a cache of windows in the
application and no two different dialog identifiers (PageSetup and PageSetup2
in this case) can have the same handle - so returning the handle of PageSetup
when we call PageSetup2 would fail (and we would do our usual waiting until
it succeeds or times out).
* Investigate using any of the following
- BringWindowToTop: probably necessary before image capture
- GetTopWindow: maybe to re-set top window after capture?
- EnumThreadWindows
- GetGUIThreadInfo
* Make it easy to work with context(right click) menu's
* Further support .NET controls and download/create a test .NET application
* Look at supporting the Sytem Tray (e.g. right click on an icon)
* supply SystemTray class (singleton probably)
* Look at clicking and text input - maybe use SendInput
* Support Up-Down controls and other common controls
* Find out whether control.item.action() or control.action(item) is better
* Create a Recorder to visually create tests
**LOW PRIORITY**
* Create a class that makes it easy to deal with a single window (e.g. no
application)
* Allow apps to be started in a different thread so we don't lock up
- this is being done already - the problem is that some messages cannot
be sent across processes if they have pointers (so we need to send a
synchronous message which waits for the other process to respond
before returning)
- But I guess it would be possible to create a thread for sending
those messages?
* Liberate the code from HwndWrapper - there is very little this add's beyond
what is available in handleprops. The main reason this is required is for
the FriendlyClassName. So I need to look to see if this can be moved
elsewhere.
Doing this might flatten the heirarchy quite a bit and reduce the
dependencies on the various packages
* Need to make Menu items into classes so instead of Dlg.MenuSelect we should
be doing ::
dlg.Menu("blah->blah").Select()
or even ::
dlg.Menu.Blah.Blah.Select()
To do this we need to change how menu's are retrieved - rather than get all
menuitems at the start - then we just get the requested level.
This would also enable things like ::
dlg.Menu.Blah.Blah.IsChecked() IsEnabled(), etc
----------------------------------
CLOSED (in some way or the other)
----------------------------------
* Allow delay after click to be removed. The main reason that this is needed
at the moment is because if you close a dialog and then try an action on
the parent immediately it may not yet be active - so the delay is
needed to allow it to become active.
To fix this we may need to add more magic around calling actions on dialogs
e.g.
on an attribute access for an ActionDialog do the following:
- Check if it is an Action
- If it is not enabled then wait a little bit
- If it is then wait a little bit and try again
- repeat that until success or timeout
The main thing that needs to be resolved is that you don't want two of these
waits happening at once (so a wait in a function at 1 level, and another wait
in a function called by the other one - because this would mean there would
be a VERY long delay while the timeout of the nested function was reached
the number of times the calling func tried to succeed!)
* Add referencing by closest static (or surrounding group box?)
* Need to modularize the methods of the common_controls because at the moment
they are much too monolithic.
* Finish example of saving a page from IE
* Document that I have not been able to figure out how to reliably check
if a menu item is enabled or not before selecting it. (Probably FIXED NOW!)
For Example in Media Player if you try and click the View->Choose Columns
menu item when it is not enabled it crashes Media Player. Theoretically
MF_DISABLED and MF_GRAYED should be used - but I found that these are not
updated (at least for Media Player) until they are dropped down.
* Implement an opional timing/config module so that all timing can be
customized

@ -1,86 +0,0 @@
"Build up the sphinx autodoc file for the python code"
import os
import sys
docs_folder = os.path.dirname(__file__)
pywin_folder = os.path.dirname(docs_folder)
sys.path.append(pywin_folder)
pywin_folder = os.path.join(pywin_folder, "pywinauto")
excluded_dirs = ["unittests"]
excluded_files = [
"_menux.py",
"__init__.py",
"win32defines.py",
"win32structures.py",
"win32functions.py"]
output_folder = os.path.join(docs_folder, "code")
try:
os.mkdir(output_folder)
except WindowsError:
pass
module_docs = []
for root, dirs, files in os.walk(pywin_folder):
# Skip over directories we don't want to document
for i, d in enumerate(dirs):
if d in excluded_dirs:
del dirs[i]
py_files = [f for f in files if f.endswith(".py")]
for py_filename in py_files:
# skip over py files we don't want to document
if py_filename in excluded_files:
continue
py_filepath = os.path.join(root, py_filename)
# find the last instance of 'pywinauto' to make a module name from
# the path
modulename = 'pywinauto' + py_filepath.rsplit("pywinauto", 1)[1]
modulename = os.path.splitext(modulename)[0]
modulename = modulename.replace('\\', '.')
# the final doc name is the modulename + .txt
doc_source_filename = os.path.join(output_folder, modulename + ".txt")
# skip files that are already generated
if os.path.exists(doc_source_filename):
continue
print py_filename
out = open(doc_source_filename, "w")
out.write(modulename + "\n")
out.write("-" * len(modulename) + "\n")
out.write(" .. automodule:: %s\n"% modulename)
out.write(" :members:\n")
out.write(" :undoc-members:\n\n")
#out.write(" :inherited-members:\n")
#out.write(" .. autoattribute:: %s\n"% modulename)
out.close()
module_docs.append(doc_source_filename)
# This section needs to be updated - I should idealy parse the
# existing file to see if any new docs have been added, if not then
# I should just leave the file alone rathre than re-create.
#
#c = open(os.path.join(output_folder, "code.txt"), "w")
#c.write("Source Code\n")
#c.write("=" * 30 + "\n")
#
#c.write(".. toctree::\n")
#c.write(" :maxdepth: 3\n\n")
#for doc in module_docs:
# c.write(" " + doc + "\n")
#
#c.close()

@ -1,65 +0,0 @@
Main user modules
==============================
.. toctree::
:maxdepth: 1
pywinauto.application.txt
pywinauto.findbestmatch.txt
pywinauto.findwindows.txt
pywinauto.timings.txt
Specific functionality
==============================
.. toctree::
:maxdepth: 1
pywinauto.clipboard.txt
pywinauto.taskbar.txt
Controls Reference
==============================
.. toctree::
:maxdepth: 1
pywinauto.controls.common_controls.txt
pywinauto.controls.HwndWrapper.txt
pywinauto.controls.menuwrapper.txt
pywinauto.controls.win32_controls.txt
Sendkeys
==============================
.. toctree::
:maxdepth: 1
pywinauto.SendKeysCtypes.txt
Pre-supplied tests
==============================
.. toctree::
:maxdepth: 1
pywinauto.tests.allcontrols.txt
pywinauto.tests.asianhotkey.txt
pywinauto.tests.comboboxdroppedheight.txt
pywinauto.tests.comparetoreffont.txt
pywinauto.tests.leadtrailspaces.txt
pywinauto.tests.miscvalues.txt
pywinauto.tests.missalignment.txt
pywinauto.tests.missingextrastring.txt
pywinauto.tests.overlapping.txt
pywinauto.tests.repeatedhotkey.txt
pywinauto.tests.translation.txt
pywinauto.tests.truncation.txt
Internal modules
==============================
.. toctree::
:maxdepth: 1
pywinauto.controlproperties.txt
pywinauto.handleprops.txt
pywinauto.XMLHelpers.txt
pywinauto.fuzzydict.txt

@ -1,6 +0,0 @@
pywinauto.SendKeysCtypes
------------------------
.. automodule:: pywinauto.SendKeysCtypes
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.XMLHelpers
--------------------
.. automodule:: pywinauto.XMLHelpers
:members:
:undoc-members:

@ -1,27 +0,0 @@
pywinauto.application
---------------------
.. automodule:: pywinauto.application
.. autoclass:: pywinauto.application.Application
:undoc-members:
:show-inheritance:
:members: __getattr__, __getitem__, active_, connect_, kill_, start_, top_window_, window_, windows_
.. autoclass:: pywinauto.application.WindowSpecification
:members: ChildWindow, Exists, PrintControlIdentifiers, Wait, WaitNot, WrapperObject
.. automethod:: pywinauto.application.WindowSpecification.__getitem__
.. automethod:: pywinauto.application.WindowSpecification.__getattr__
.. autofunction:: pywinauto.application.process_from_module
.. autofunction:: pywinauto.application.process_module
Exceptions
==========
.. autoclass:: pywinauto.application.AppNotConnected
.. autoclass:: pywinauto.application.AppStartError
.. autoclass:: pywinauto.application.AssertValidProcess
.. autoclass:: pywinauto.application.ProcessNotFoundError

@ -1,6 +0,0 @@
pywinauto.clipboard
-------------------
.. automodule:: pywinauto.clipboard
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.controlproperties
---------------------------
.. automodule:: pywinauto.controlproperties
:members:
:undoc-members:

@ -1,7 +0,0 @@
pywinauto.controls.HwndWrapper
------------------------------
.. automodule:: pywinauto.controls.HwndWrapper
:members:
:undoc-members:
:show-inheritance:

@ -1,12 +0,0 @@
pywinauto.controls.common_controls
----------------------------------
.. automodule:: pywinauto.controls.common_controls
:members:
:show-inheritance:
.. autoclass:: pywinauto.controls.common_controls._treeview_element
:members:
.. autoclass:: pywinauto.controls.common_controls._toolbar_button
:members:

@ -1,7 +0,0 @@
pywinauto.controls.menuwrapper
------------------------------
.. automodule:: pywinauto.controls.menuwrapper
:members:
:undoc-members:
:show-inheritance:

@ -1,7 +0,0 @@
pywinauto.controls.win32_controls
---------------------------------
.. automodule:: pywinauto.controls.win32_controls
:members:
:undoc-members:
:show-inheritance:

@ -1,6 +0,0 @@
pywinauto.findbestmatch
-----------------------
.. automodule:: pywinauto.findbestmatch
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.findwindows
---------------------
.. automodule:: pywinauto.findwindows
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.fuzzydict
-------------------
.. automodule:: pywinauto.fuzzydict
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.handleprops
---------------------
.. automodule:: pywinauto.handleprops
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.taskbar
-----------------
.. automodule:: pywinauto.taskbar
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.tests.allcontrols
---------------------------
.. automodule:: pywinauto.tests.allcontrols
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.tests.asianhotkey
---------------------------
.. automodule:: pywinauto.tests.asianhotkey
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.tests.comboboxdroppedheight
-------------------------------------
.. automodule:: pywinauto.tests.comboboxdroppedheight
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.tests.comparetoreffont
--------------------------------
.. automodule:: pywinauto.tests.comparetoreffont
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.tests.leadtrailspaces
-------------------------------
.. automodule:: pywinauto.tests.leadtrailspaces
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.tests.miscvalues
--------------------------
.. automodule:: pywinauto.tests.miscvalues
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.tests.missalignment
-----------------------------
.. automodule:: pywinauto.tests.missalignment
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.tests.missingextrastring
----------------------------------
.. automodule:: pywinauto.tests.missingextrastring
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.tests.overlapping
---------------------------
.. automodule:: pywinauto.tests.overlapping
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.tests.repeatedhotkey
------------------------------
.. automodule:: pywinauto.tests.repeatedhotkey
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.tests.translation
---------------------------
.. automodule:: pywinauto.tests.translation
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.tests.truncation
--------------------------
.. automodule:: pywinauto.tests.truncation
:members:
:undoc-members:

@ -1,6 +0,0 @@
pywinauto.timings
-----------------
.. automodule:: pywinauto.timings
:members:
:undoc-members:

@ -1,210 +0,0 @@
# -*- coding: utf-8 -*-
#
# pywinauto documentation build configuration file, created by
# sphinx-quickstart on Mon Mar 02 22:29:19 2009.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# The contents of this file are pickled, so don't put values in the namespace
# that aren't pickleable (module imports are okay, they're removed automatically).
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
import re
sys.path.append("..")
sys.path.append(".")
ver_re = re.compile(r'''__version__\s*\=\s*(['"])(.*)\1''')
f = open(os.path.join(
os.path.dirname(__file__), '..', 'pywinauto', '__init__.py'))
init_data = f.read()
f.close()
found = ver_re.search(init_data)
if not found:
raise RuntimeError(
"Could not read version information from __init__.py")
version = release = found.group(2)
# If your extensions are in another directory, add it here. If the directory
# is relative to the documentation root, use os.path.abspath to make it
# absolute, like shown here.
sys.path.append(os.path.abspath('.'))
# General configuration
# ---------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc',]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['.templates']
# The suffix of source filenames.
source_suffix = '.txt'
# The encoding of source files.
#source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'contents'
# General information about the project.
project = u'pywinauto'
copyright = u'2010, Mark Mc Mahon'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
#version = '0.3.9'
# The full version, including alpha/beta/rc tags.
#release = '0.3.9'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
#unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = ['.build', "examples", "dist", r"pywinauto\unittests", "pywinauto_wait_branch"]
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# Options for HTML output
# -----------------------
# The style sheet to use for HTML and HTML Help pages. A file of that name
# must exist either in Sphinx' static/ path, or in one of the custom paths
# given in html_static_path.
html_style = 'default.css'
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['.static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_use_modindex = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, the reST sources are included in the HTML build as _sources/<name>.
#html_copy_source = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'pywinautodoc'
# Options for LaTeX output
# ------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]).
latex_documents = [
('index', 'pywinauto.tex', ur'pywinauto Documentation',
ur'Mark Mc Mahon', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True
# parameter to autodoc to make it take the doc from the __init__ methods also
autoclass_content = 'both'

@ -1,37 +0,0 @@
.. pywinauto documentation master file, created by sphinx-quickstart on Wed Apr 02 15:09:06 2008.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
.. _contents-root:
Contents
=====================================
.. toctree::
:maxdepth: 2
index
getting_started
HowTo
controls_overview
credits
dev_notes
TODO
HISTORY
Source code reference
=====================================
.. toctree::
:maxdepth: 2
code/code
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

@ -1,454 +0,0 @@
============================================================
Methods available to each different control type
============================================================
Windows has many controls, buttons, lists, etc
All Controls
------------
These functions are aviailable to all controls.
* CaptureAsImage_
* Click_
* ClickInput_
* Close_
* CloseClick_
* DebugMessage_
* DoubleClick_
* DoubleClickInput_
* DragMouse_
* DrawOutline_
* GetFocus_
* GetShowState_
* Maximize_
* MenuSelect_
* Minimize_
* MoveMouse_
* MoveWindow_
* NotifyMenuSelect_
* NotifyParent_
* PressMouse_
* PressMouseInput_
* ReleaseMouse_
* ReleaseMouseInput_
* Restore_
* RightClick_
* RightClickInput_
* RightClickInput_
* SendMessage_
* SendMessageTimeout_
* SetFocus_
* SetWindowText_
* TypeKeys_
* Children_
* Class_
* ClientRect_
* ClientRects_
* ContextHelpID_
* ControlID_
* ExStyle_
* Font_
* Fonts_
* FriendlyClassName_
* GetProperties_
* HasExStyle_
* HasStyle_
* IsChild_
* IsDialog_
* IsEnabled_
* IsUnicode_
* IsVisible_
* Menu_
* MenuItem_
* MenuItems_
* Owner_
* Parent_
* PopupWindow_
* ProcessID_
* Rectangle_
* Style_
* Texts_
* TopLevelParent_
* UserData_
* VerifyActionable_
* VerifyEnabled_
* VerifyVisible_
* WindowText_
.. _CaptureAsImage: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.CaptureAsImage
.. _Click: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Click
.. _ClickInput: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.ClickInput
.. _CloseClick: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.CloseClick
.. _DebugMessage: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.DebugMessage
.. _DoubleClick: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.DoubleClick
.. _DoubleClickInput: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.DoubleClickInput
.. _DragMouse: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.DragMouse
.. _DrawOutline: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.DrawOutline
.. _GetFocus: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.GetFocus
.. _MenuSelect: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.MenuSelect
.. _MoveMouse: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.MoveMouse
.. _MoveWindow: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.MoveWindow
.. _NotifyMenuSelect: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.NotifyMenuSelect
.. _NotifyParent: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.NotifyParent
.. _PressMouse: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.PressMouse
.. _PressMouseInput: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.PressMouseInput
.. _ReleaseMouse: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.ReleaseMouse
.. _ReleaseMouseInput: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.ReleaseMouseInput
.. _RightClick: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.RightClick
.. _RightClickInput: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.RightClickInput
.. _RightClickInput: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.RightClickInput
.. _SendMessage: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.SendMessage
.. _SendMessageTimeout: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.SendMessageTimeout
.. _SetFocus: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.SetFocus
.. _SetWindowText: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.SetWindowText
.. _TypeKeys: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.TypeKeys
.. _Close: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Close
.. _Restore: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Restore
.. _GetShowState: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.GetShowState
.. _Maximize: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Maximize
.. _Minimize: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Minimize
.. _Children: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Children
.. _Class: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Class
.. _ClientRect: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.ClientRect
.. _ClientRects: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.ClientRects
.. _ContextHelpID: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.ContextHelpID
.. _ControlID: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.ControlID
.. _ExStyle: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.ExStyle
.. _Font: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Font
.. _Fonts: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Fonts
.. _FriendlyClassName: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.FriendlyClassName
.. _GetProperties: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.GetProperties
.. _HasExStyle: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.HasExStyle
.. _HasStyle: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.HasStyle
.. _IsChild: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.IsChild
.. _IsDialog: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.IsDialog
.. _IsEnabled: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.IsEnabled
.. _IsUnicode: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.IsUnicode
.. _IsVisible: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.IsVisible
.. _Menu: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Menu
.. _MenuItem: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.MenuItem
.. _MenuItems: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.MenuItems
.. _Owner: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Owner
.. _Parent: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Parent
.. _PopupWindow: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.PopupWindow
.. _ProcessID: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.ProcessID
.. _Rectangle: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Rectangle
.. _Style: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Style
.. _Texts: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.Texts
.. _TopLevelParent: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.TopLevelParent
.. _UserData: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.UserData
.. _VerifyActionable: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.VerifyActionable
.. _VerifyEnabled: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.VerifyEnabled
.. _VerifyVisible: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.VerifyVisible
.. _WindowText: code/pywinauto.controls.HwndWrapper.html#pywinauto.controls.HwndWrapper.HwndWrapper.WindowText
Button, CheckBox, RadioButton, GroupBox
---------------------------------------
* ButtonWrapper.Check_
* ButtonWrapper.GetCheckState_
* ButtonWrapper.SetCheckIndeterminate_
* ButtonWrapper.UnCheck_
.. _ButtonWrapper.Check: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ButtonWrapper.Check
.. _ButtonWrapper.GetCheckState: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ButtonWrapper.GetCheckState
.. _ButtonWrapper.SetCheckIndeterminate: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ButtonWrapper.SetCheckIndeterminate
.. _ButtonWrapper.UnCheck: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ButtonWrapper.UnCheck
ComboBox
---------------------------------------
* ComboBoxWrapper.DroppedRect_
* ComboBoxWrapper.ItemCount_
* ComboBoxWrapper.ItemData_
* ComboBoxWrapper.ItemTexts_
* ComboBoxWrapper.Select_
* ComboBoxWrapper.SelectedIndex_
.. _ComboBoxWrapper.DroppedRect: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ComboBoxWrapper.DroppedRect
.. _ComboBoxWrapper.ItemCount: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ComboBoxWrapper.ItemCount
.. _ComboBoxWrapper.ItemData: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ComboBoxWrapper.ItemData
.. _ComboBoxWrapper.ItemTexts: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ComboBoxWrapper.ItemTexts
.. _ComboBoxWrapper.Select: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ComboBoxWrapper.Select
.. _ComboBoxWrapper.SelectedIndex: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ComboBoxWrapper.SelectedIndex
Dialog
---------------------------------------
* DialogWrapper.ClientAreaRect_
* DialogWrapper.RunTests_
* DialogWrapper.WriteToXML_
.. _DialogWrapper.ClientAreaRect: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.DialogWrapper.ClientAreaRect
.. _DialogWrapper.RunTests: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.DialogWrapper.RunTests
.. _DialogWrapper.WriteToXML: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.DialogWrapper.WriteToXML
Edit
---------------------------------------
* EditWrapper.GetLine_
* EditWrapper.LineCount_
* EditWrapper.LineLength_
* EditWrapper.Select_
* EditWrapper.SelectionIndices_
* EditWrapper.SetEditText_
* EditWrapper.SetWindowText_
* EditWrapper.TextBlock_
.. _EditWrapper.GetLine: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.EditWrapper.GetLine
.. _EditWrapper.LineCount: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.EditWrapper.LineCount
.. _EditWrapper.LineLength: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.EditWrapper.LineLength
.. _EditWrapper.Select: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.EditWrapper.Select
.. _EditWrapper.SelectionIndices: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.EditWrapper.SelectionIndices
.. _EditWrapper.SetEditText: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.EditWrapper.SetEditText
.. _EditWrapper.SetWindowText: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.EditWrapper.SetWindowText
.. _EditWrapper.TextBlock: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.EditWrapper.TextBlock
Header
---------------------------------------
* HeaderWrapper.GetColumnRectangle_
* HeaderWrapper.GetColumnText_
* HeaderWrapper.ItemCount_
.. _HeaderWrapper.GetColumnRectangle: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.HeaderWrapper.GetColumnRectangle
.. _HeaderWrapper.GetColumnText: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.HeaderWrapper.GetColumnText
.. _HeaderWrapper.ItemCount: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.HeaderWrapper.ItemCount
ListBox
---------------------------------------
* ListBoxWrapper.GetItemFocus_
* ListBoxWrapper.ItemCount_
* ListBoxWrapper.ItemData_
* ListBoxWrapper.ItemTexts_
* ListBoxWrapper.Select_
* ListBoxWrapper.SelectedIndices_
* ListBoxWrapper.SetItemFocus_
.. _ListBoxWrapper.GetItemFocus: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ListBoxWrapper.GetItemFocus
.. _ListBoxWrapper.ItemCount: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ListBoxWrapper.ItemCount
.. _ListBoxWrapper.ItemData: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ListBoxWrapper.ItemData
.. _ListBoxWrapper.ItemTexts: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ListBoxWrapper.ItemTexts
.. _ListBoxWrapper.Select: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ListBoxWrapper.Select
.. _ListBoxWrapper.SelectedIndices: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ListBoxWrapper.SelectedIndices
.. _ListBoxWrapper.SetItemFocus: code/pywinauto.controls.win32_controls.html#pywinauto.controls.win32_controls.ListBoxWrapper.SetItemFocus
ListView
---------------------------------------
* ListViewWrapper.Check_
* ListViewWrapper.ColumnCount_
* ListViewWrapper.Columns_
* ListViewWrapper.ColumnWidths_
* ListViewWrapper.GetColumn_
* ListViewWrapper.GetHeaderControl_
* ListViewWrapper.GetItem_
* ListViewWrapper.GetSelectedCount_
* ListViewWrapper.IsChecked_
* ListViewWrapper.IsFocused_
* ListViewWrapper.IsSelected_
* ListViewWrapper.ItemCount_
* ListViewWrapper.Items_
* ListViewWrapper.Select_
* ListViewWrapper.Deselect_
* ListViewWrapper.UnCheck_
.. _ListViewWrapper.Check: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.Check
.. _ListViewWrapper.ColumnCount: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.ColumnCount
.. _ListViewWrapper.Columns: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.Columns
.. _ListViewWrapper.ColumnWidths: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.ColumnWidths
.. _ListViewWrapper.GetColumn: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.GetColumn
.. _ListViewWrapper.GetHeaderControl: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.GetHeaderControl
.. _ListViewWrapper.GetItem: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.GetItem
.. _ListViewWrapper.GetSelectedCount: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.GetSelectedCount
.. _ListViewWrapper.IsChecked: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.IsChecked
.. _ListViewWrapper.IsFocused: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.IsFocused
.. _ListViewWrapper.IsSelected: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.IsSelected
.. _ListViewWrapper.ItemCount: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.ItemCount
.. _ListViewWrapper.Items: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.Items
.. _ListViewWrapper.Select: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.Select
.. _ListViewWrapper.Deselect: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.Deselect
.. _ListViewWrapper.UnCheck: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ListViewWrapper.UnCheck
PopupMenu
---------------------------------------
(no extra visible methods)
ReBar
---------------------------------------
* ReBarWrapper.BandCount_
* ReBarWrapper.GetBand_
* ReBarWrapper.GetToolTipsControl_
.. _ReBarWrapper.BandCount: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ReBarWrapper.BandCount
.. _ReBarWrapper.GetBand: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ReBarWrapper.GetBand
.. _ReBarWrapper.GetToolTipsControl: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ReBarWrapper.GetToolTipsControl
Static
---------------------------------------
(no extra visible methods)
StatusBar
---------------------------------------
* StatusBarWrapper.BorderWidths_
* StatusBarWrapper.GetPartRect_
* StatusBarWrapper.GetPartText_
* StatusBarWrapper.PartCount_
* StatusBarWrapper.PartRightEdges_
.. _StatusBarWrapper.BorderWidths: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.StatusBarWrapper.BorderWidths
.. _StatusBarWrapper.GetPartRect: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.StatusBarWrapper.GetPartRect
.. _StatusBarWrapper.GetPartText: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.StatusBarWrapper.GetPartText
.. _StatusBarWrapper.PartCount: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.StatusBarWrapper.PartCount
.. _StatusBarWrapper.PartRightEdges: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.StatusBarWrapper.PartRightEdges
TabControl
---------------------------------------
* TabControlWrapper.GetSelectedTab_
* TabControlWrapper.GetTabRect_
* TabControlWrapper.GetTabState_
* TabControlWrapper.GetTabText_
* TabControlWrapper.RowCount_
* TabControlWrapper.Select_
* TabControlWrapper.TabCount_
* TabControlWrapper.TabStates_
.. _TabControlWrapper.GetSelectedTab: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TabControlWrapper.GetSelectedTab
.. _TabControlWrapper.GetTabRect: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TabControlWrapper.GetTabRect
.. _TabControlWrapper.GetTabState: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TabControlWrapper.GetTabState
.. _TabControlWrapper.GetTabText: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TabControlWrapper.GetTabText
.. _TabControlWrapper.RowCount: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TabControlWrapper.RowCount
.. _TabControlWrapper.Select: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TabControlWrapper.Select
.. _TabControlWrapper.TabCount: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TabControlWrapper.TabCount
.. _TabControlWrapper.TabStates: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TabControlWrapper.TabStates
Toolbar
---------------------------------------
* ToolbarWrapper.Button_
* ToolbarWrapper.ButtonCount_
* ToolbarWrapper.GetButton_
* ToolbarWrapper.GetButtonRect_
* ToolbarWrapper.GetToolTipsControl_
* ToolbarWrapper.PressButton_
.. _ToolbarWrapper.Button: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ToolbarWrapper.Button
.. _ToolbarWrapper.ButtonCount: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ToolbarWrapper.ButtonCount
.. _ToolbarWrapper.GetButton: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ToolbarWrapper.GetButton
.. _ToolbarWrapper.GetButtonRect: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ToolbarWrapper.GetButtonRect
.. _ToolbarWrapper.GetToolTipsControl: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ToolbarWrapper.GetToolTipsControl
.. _ToolbarWrapper.PressButton: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ToolbarWrapper.PressButton
*ToolbarButton* (returned by ``Button()``)
* ToolbarButton.Rectangle_
* ToolbarButton.Style_
* ToolbarButton.ClickInput_
* ToolbarButton.Click_
* ToolbarButton.IsCheckable_
* ToolbarButton.IsChecked_
* ToolbarButton.IsEnabled_
* ToolbarButton.IsPressable_
* ToolbarButton.IsPressed_
* ToolbarButton.State_
.. _ToolbarButton.Rectangle: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._toolbar_button.Rectangle
.. _ToolbarButton.Style: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._toolbar_button.Style
.. _ToolbarButton.ClickInput: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._toolbar_button.ClickInput
.. _ToolbarButton.Click: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._toolbar_button.Click
.. _ToolbarButton.IsCheckable: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._toolbar_button.IsCheckable
.. _ToolbarButton.IsChecked: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._toolbar_button.IsChecked
.. _ToolbarButton.IsEnabled: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._toolbar_button.IsEnabled
.. _ToolbarButton.IsPressable: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._toolbar_button.IsPressable
.. _ToolbarButton.IsPressed: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._toolbar_button.IsPressed
.. _ToolbarButton.State: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._toolbar_button.State
ToolTips
---------------------------------------
* ToolTipsWrapper.GetTip_
* ToolTipsWrapper.GetTipText_
* ToolTipsWrapper.ToolCount_
.. _ToolTipsWrapper.GetTip: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ToolTipsWrapper.GetTip
.. _ToolTipsWrapper.GetTipText: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ToolTipsWrapper.GetTipText
.. _ToolTipsWrapper.ToolCount: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.ToolTipsWrapper.ToolCount
TreeView
---------------------------------------
* TreeViewWrapper.EnsureVisible_
* TreeViewWrapper.GetItem_
* TreeViewWrapper.GetProperties_
* TreeViewWrapper.IsSelected_
* TreeViewWrapper.ItemCount_
* TreeViewWrapper.Root_
* TreeViewWrapper.Select_
.. _TreeViewWrapper.EnsureVisible: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TreeViewWrapper.EnsureVisible
.. _TreeViewWrapper.GetItem: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TreeViewWrapper.GetItem
.. _TreeViewWrapper.GetProperties: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TreeViewWrapper.GetProperties
.. _TreeViewWrapper.IsSelected: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TreeViewWrapper.IsSelected
.. _TreeViewWrapper.ItemCount: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TreeViewWrapper.ItemCount
.. _TreeViewWrapper.Root: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TreeViewWrapper.Root
.. _TreeViewWrapper.Select: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TreeViewWrapper.Select
*TreeViewElement* (returned by ``GetItem()`` and ``Root()``)
* TreeViewElement.Children_
* TreeViewElement.Item_
* TreeViewElement.Next_
* TreeViewElement.Rectangle_
* TreeViewElement.State_
* TreeViewElement.SubElements_
* TreeViewElement.Text_
.. _TreeViewElement.Children: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._treeview_element.Children
.. _TreeViewElement.Item: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._treeview_element.Item
.. _TreeViewElement.Next: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._treeview_element.Next
.. _TreeViewElement.Rectangle: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._treeview_element.Rectangle
.. _TreeViewElement.State: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._treeview_element.State
.. _TreeViewElement.SubElements: code/pywinauto.controlscommon_controls.html#pywinauto.controls.common_controls._treeview_element.SubElements
.. _TreeViewElement.Text: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls._treeview_element.Text
UpDown
---------------------------------------
* UpDownWrapper.GetBase_
* UpDownWrapper.GetBuddyControl_
* UpDownWrapper.GetRange_
* UpDownWrapper.GetValue_
* UpDownWrapper.SetValue_
* UpDownWrapper.Increment_
* UpDownWrapper.Decrement_
.. _UpDownWrapper.GetBase: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.UpDownWrapper.GetBase
.. _UpDownWrapper.GetBuddyControl: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.UpDownWrapper.GetBuddyControl
.. _UpDownWrapper.GetRange: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.UpDownWrapper.GetRange
.. _UpDownWrapper.GetValue: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.UpDownWrapper.GetValue
.. _UpDownWrapper.SetValue: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.UpDownWrapper.SetValue
.. _UpDownWrapper.Increment: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.UpDownWrapper.Increment
.. _UpDownWrapper.Decrement: code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.UpDownWrapper.Decrement

@ -1,6 +0,0 @@
Credits
-------
Stefaan Himpe - Lots of speed and stability improvements early on
Jeff Winkler - Early encouragement, creation of screencasts
Dalius Dobravolskas - Help on the forums and prompted major improvements on the wait* functionality
Daisuke Yamashita - Bugs/suggestions for 2.5 that MenuWrapper.GetProperties() returns a list rather then a dict.

@ -1,179 +0,0 @@
++++++++++++++++++++
Dev Notes
++++++++++++++++++++
===========
FILE LAYOUT
===========
# used by just about everything (and considered a block!)
win32defines.py
win32functions.py
win32structures.py
# Find windows and their attributes
findwindows.py
handleprops.py
# wrap windows, get extra info for particular controls
# set the friendly class name
controls\common_controls.py
controls\controlactions.py
controls\HwndWrapper.py
controls\win32_controls.py
# currently depends on the Friendly class name
# probably needs to be refactored to make it independent of controls!
# maybe move that stuff to _application_?
findbestmatch.py # currently depends on controls!
controlactions.py
tests\allcontrols.py
tests\asianhotkey.py
tests\comboboxdroppedheight.py
tests\comparetoreffont.py
tests\leadtrailspaces.py
tests\miscvalues.py
tests\missalignment.py
tests\missingextrastring.py
tests\overlapping.py
tests\repeatedhotkey.py
tests\translation.py
tests\truncation.py
controlproperties.py
XMLHelpers.py
FindDialog.py
PyDlgCheckerWrapper.py
application.py
test_application.py
====================
Best matching
====================
difflib provides this support
For menu's it is simple we match against the text of the menu item.
For controls the story is more complicated because we want to match
against the following:
- Control text if it exists
- Friendly Class name
- Control text + Friendly class name (if control text exists)
- (Possibly) closest static + FriendlyClassName
e.g.
FindWhatCombo, ComboBox1,
or
Text, TextRiadio, RadioButton2
1) the control itself knows what it should be referred to
2) Need to disambiguate across all controls in the dialog
3) then we need to match
====================
ATTRIBUTE RESOLUTION
====================
Thinking again...
app.dlg.control
TWO LEVELS
* application.member (Python resolves)
an attribute of application object
* application.dialog
a dialog reference
THREE LEVELS
* application.member.attr (Python resolves)
another attribute of the previous member
* application.dialog.member
a member of the dialog object
* application.dialog.control
a control on the dialog
FOUR LEVELS (leaving out Python resolved)
* application.dialog.member.member
* application.dialog.control.member
DELAYED RESOLUTION FOR SUCCESS
Taking the example ::
app.dlg.control.action()
If we leave out syntax and programming errors there are still a number of reasons why it could fail.
dlg might not be found
control might not be found
either dlg or control may be disabled
dialog and control may be found but on the wrong dialog (e.g. in Notepad you can bring up 2 "Page Setup" dialogs both with an OK button)
One solution would just be to add a "sleep" before trying to find each new dialog (to ensure that it is there and ready) - but this will mean lots of unnecessary waiting.
So the solution I have tried is:
- perform the complete attribute access resolution at the latest possible time
- if it fails then wait and try again
- after a specified timeout fail raising the original exception.
This means that in the normal case you don't have unnecessary waits - and in the failure case - you still get an exception with the error.
Also waiting to do resolution as late as possible stops errors where an earlier part of the path succeedes - but finds the wrong item.
So for example if finds the page setup dialog in Notepad
# open the Printer setup dialog (which has "Page Setup" as title)
app.PageSetup.Printer.Click()
# if this runs too quickly it actually finds the current page setup dialog
# before the next dialog opens, but that dialog does not have a Properties
# button - so an error is raised.
# because we re-run the resolution from the start we find the new pagesetup dialog.
app.PageSetup.Properties.Click()
==================
WRITING TO DIALOGS
==================
We need a way of making sure that the dialog is active without having to access a control on it.
e.g. ::
app.MainWin.MenuSelect("Something That->Loads a Dialog")
app.Dlg._write("dlg.xml")
or a harder problem::
app.PageSetup.Printer.Click()
app.PageSetup._write("pagesetup.xml")
In this second example it is very hard to be sure that the correct Page Setup dialog is shown.
The only way to be realy sure is to check for the existance of certain control(s) (ID, Class, text, whatever) - but it would be nice to not have to deal with those :-(
Another less declarative (more magic?) is to scan the list of available windows/controls and if they haven't changed then accept that the correct one is shown.
When testing and having XML files then we should use those to make sure that we have the correct dialog up (by using Class/ID)

@ -1,112 +0,0 @@
==========================
Automating an application
==========================
Once you have installed pywinauto - how do you get going?
Sit back and have a look at a little movie
-------------------------------------------
Jeff Winkler has created a nice screencast of using pywinauto, you
can see it at :
http://showmedo.com/videos/video?name=UsingpyWinAutoToControlAWindowsApplication&fromSeriesID=7
Look at the examples
--------------------
The following examples are included:
**Note**: Examples are language dependent - they will only work on the
language of product that they were programmed for. All examples have
been programmed for English Software except where highlighted.
- ``mspaint.py`` Control MSPaint
- ``notepad_fast.py`` Use fast timing settings to control Notepad
- ``notepad_slow.py`` Use slow timing settings to control Notepad
- ``notepad_item.py`` Use item rather then attribute access to control Notepad.
- ``MiscExamples.py`` Show some exceptions and how to get control identifiers.
- ``SaveFromInternetExplorer.py`` Save a Web Page from Internet Explorer -
- ``SaveFromFirefox.py`` Save a Web Page from Firefox.
- ``get_winrar_info.py`` Example of how to do multilingual automation.
This is not an ideal example (works on French, Czech and German WinRar)
- ``ForteAgentSample.py`` Example of dealing with a complex application that
is quite dynamic and gives different dialogs often when starting.
- ``windowmediaplayer.py`` Just another example - deals with check boxes in a
ListView.
- ``test_sakura.py``, ``test_sakura2.py`` Two examples of automating a Japanase product.
Automate notepad at the command line
-------------------------------------
Please find below a sample run ::
C:\>python
Python 2.4.2 (#67, Sep 28 2005, 12:41:11) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(1) >>> from pywinauto import application
(2) >>> app = application.Application()
(3) >>> app.Start_("Notepad.exe")
<pywinauto.application.Application object at 0x00AE0990>
(4) >>> app.Notepad.DrawOutline()
(5) >>> app.Notepad.MenuSelect("Edit -> Replace")
(6) >>> app.Replace.PrintControlIdentifiers()
Control Identifiers:
Static - 'Fi&nd what:' (L1018, T159, R1090, B172)
'Fi&nd what:' 'Fi&nd what:Static' 'Static' 'Static0' 'Static1'
Edit - '' (L1093, T155, R1264, B175)
'Edit' 'Edit0' 'Edit1' 'Fi&nd what:Edit'
Static - 'Re&place with:' (L1018, T186, R1090, B199)
'Re&place with:' 'Re&place with:Static' 'Static2'
Edit - '' (L1093, T183, R1264, B203)
'Edit2' 'Re&place with:Edit'
Button - 'Match &case' (L1020, T245, R1109, B265)
'CheckBox2' 'Match &case' 'Match &caseCheckBox'
Button - '&Find Next' (L1273, T151, R1348, B174)
'&Find Next' '&Find NextButton' 'Button' 'Button0' 'Button1'
Button - '&Replace' (L1273, T178, R1348, B201)
'&Replace' '&ReplaceButton' 'Button2'
Button - 'Replace &All' (L1273, T206, R1348, B229)
'Button3' 'Replace &All' 'Replace &AllButton'
Button - 'Cancel' (L1273, T233, R1348, B256)
'Button4' 'Cancel' 'CancelButton'
(7) >>> app.Replace.Cancel.Click()
(8) >>> app.Notepad.Edit.TypeKeys("Hi from Python interactive prompt %s" % str(dir()), with_spaces = True)
<pywinauto.controls.win32_controls.EditWrapper object at 0x00DDC2D0>
(9) >>> app.Notepad.MenuSelect("File -> Exit")
(10) >>> app.Notepad.No.Click()
>>>
1. Import the pywinauto.application module (usually the only module you need
to import directly)
2. Create an Application instance. All access to the application is done
through this object.
3. We have created an Application instance in step 2 but we did not supply
any information on the Windows application it referred to. By using the
Start_() method we execute that application and connect it to the
Application instance app.
4. Draw a green rectangle around the Notepad dialog - so that we know we have
the correct window.
5. Select the Replace item from the Edit Menu on the Notepad Dialog of the
application that app is connected to.
This action will make the Replace dialog appear.
6. Print the identifiers for the controls on the Replace dialog, for
example the 1st edit control on the Replace dialog can be referred to by
any of the following identifiers::
app.Replace.Edit
app.Replace.Edit0
app.Replace.Edit1
app.FindwhatEdit
The last is the one that gives the user reading the script aftewards the
best idea of what the script does.
7. Close the Replace dialog. (In a script file it is safer to use CloseClick()
rather than Click() because CloseClick() waits a little longer to give windows
time to close the dialog.)
8. Let's type some text into the Notepad text area. Without the ``with_spaces``
argument spaces would not be typed. Please see documentation for SendKeys
for this method as it is a thin wrapper around SendKeys.
9. Ask to exit Notepad
10. We will be asked if we want to save - Click on the "No" button.

@ -1,141 +0,0 @@
====================
What is pywinauto
====================
(c) Mark Mc Mahon 2006-2009
Released under the LGPL licence
:ref:`Full table of contents. <contents-root>`
What is it?
-----------
pywinauto is a set of python modules to automate the Microsoft Windows GUI.
At it's simplest it allows you to send mouse and keyboard actions to windows
dialogs and controls.
Installation
------------
- Download pywinauto from https://sourceforge.net/project/showfiles.php?group_id=157379
- Unzip the pywinauto zip file to a folder.
- Run ``python.exe setup.py install``
- Install the following Python packages
- *Optional* PIL http://www.pythonware.com/products/pil/index.htm
- *Optional* elementtree http://effbot.org/downloads/
- Releases prior to 0.3.9 require Sendkeys - http://www.rutherfurd.net/python/sendkeys/index.html
- If you are using Python 2.3 or 2.4 then you will have to install ctypes http://starship.python.net/crew/theller/ctypes/ (download from http://sourceforge.net/project/showfiles.php?group_id=71702)
To check you have it installed correctly
Run Python ::
>>> from pywinauto import application
>>> app = application.Application.start("notepad.exe")
>>> app.notepad.TypeKeys("%FX")
Where to start
--------------
Look at the examples provided in test_application.py
There are examples in there to work with Notepad and MSPaint.
How does it work
----------------
A lot is done through attribute access (``__getattr__``) for each class. For example
when you get the attribute of an Application or Dialog object it looks for a
dialog or control (respectively).
::
myapp.Notepad # looks for a Window/Dialog of your app that has a title 'similar'
# to "Notepad"
myapp.PageSetup.OK # looks first for a dialog with a title like "PageSetup"
# then it looks for a control on that dialog with a title
# like "OK"
This attribute resolution is delayed (currently a hard coded amount of time) until
it succeeds. So for example if you Select a menu option and then look for the
resulting dialog e.g. ::
app.Notepad.MenuSelect("File->SaveAs")
app.SaveAs.ComboBox5.Select("UTF-8")
app.SaveAs.edit1.SetText("Example-utf8.txt")
app.SaveAs.Save.Click()
At the 2nd line the SaveAs dialog might not be open by the time this line is
executed. So what happens is that we wait until we have a control to resolve
before resolving the dialog. At that point if we can't find a SaveAs dialog with
a ComboBox5 control then we wait a very short period of time and try again,
this is repeated up to a maximum time (currently 1 second!)
This avoid the user having to use time.sleep or a "WaitForDialog" function.
Some similar tools for comparison
---------------------------------
* Python tools
- Watsup (http://www.tizmoi.net/watsup/intro.html)
- winGuiAuto (http://www.brunningonline.net/simon/blog/archives/winGuiAuto.py.html)
* Other scripting language tools
- Perl Win32::GuiTest (http://erngui.com/prog/perl/guitest/)
- Ruby GuiTest (http://raa.ruby-lang.org/list.rhtml?name=win32-guitest)
- others (http://opensourcetesting.org/)
* Other free tools
- AutoIt (http://www.autoitscript.com/)
- See collection at: http://tejasconsulting.com/open-testware/feature/gui-test-driver-survey.html
* Commercial tools
- WinRunner (http://www.mercury.com/us/products/quality-center/functional-testing/winrunner/)
- SilkTest (http://www.segue.com/products/functional-regressional-testing/silktest.asp)
- Many Others (http://www.testingfaqs.org/t-gui.html)
Why write yet another automation tool if there are so many out there?
---------------------------------------------------------------------
There are loads of reasons :-)
**Takes a different approach:**
Most other tools are not object oriented you end up writing stuff like::
window = findwindow(title = "Untitled - Notepad", class = "Notepad")
SendKeys(window, "%OF") # Format -> Font
fontdialog = findwindow("title = "Font")
buttonClick(fontdialog, "OK")
I was hoping to create something more userfriendly (and pythonic). For example
the translation of above would be::
win = app.UntitledNotepad
win.MenuSelect("Format->Font")
app.Font.OK.Click()
**Python makes it easy:**
Python is a great programming language, but I didn't find
any automation tools that were Pythonic (I only found one
that was implemented in python) and I didn't care for it
too much.
**Localization as a main requirement:**
I work in the localization industry and GUI
automation is used extensively as often all
you need to do is ensure that your UI behaves
and is correct with respect to the Source
UI. This is actually an easier job then for
testing the original source UI.
But most automation tools are based off of coordinates or text of the
controls and these can change in the localized software. So my goal (
though not yet implemented) is to allow scripts to run unchanged
between original source language (often English) and the translated
software (Japanese, German, etc).

@ -1,93 +0,0 @@
"""Perform some tests with Forte Agent
NOTE: Forte Agent has a very dynamic interface
e.g. whether it is free or not, whether it is still in the grace
period. For this reason this example script may or may not work well
for you"""
print __doc__
import time
from pprint import pprint
from pywinauto.application import Application
# start the application and wait for the Agent Dialog to be ready
app = Application().start_(r"c:\program files\agent\agent.exe")
while not app.Windows_():
time.sleep(.5)
# if the trial nag dialog pops up
if app.window_(title = "Forte Agent Trial").Exists():
#app.ForteAgentTrial.IdLikeToContinueUsingAgentfor7moredays.Click()
app.ForteAgentTrial.IdliketouseFreeAgent
app.ForteAgentTrial.OK.Click()
if app.window_(title = "Free Agent Registration").Exists():
app.FreeAgentRegistration.ImreallybusyRemindmein30.Click()
app.FreeAgentRegistration.OK.CloseClick()
if app.window_(title = "What's New Reminder").Exists():
app.WhatsNewReminder.ImreallybusyRemindmein90.Click()
app.WhatsNewReminder.OK.CloseClick()
# wait until the app is ready
app.FreeAgent.Wait("ready")
# if we get the Agent Setup wizard pops up close it
if app.AgentSetupWizard.Cancel.Exists(1):
app.AgentSetupWizard.Cancel.Click()
app.AgentSetupWizard2.Yes.Click()
# Select to emtpy trash
app.FreeAgent.MenuSelect("File->EmptyTrash")
app.EmptyTrash.No.Click()
# Select some more menus (typo not important :-)
app.FreeAgent.MenuSelect("File->Purge and Compact -> Compact All Folders")
app.FreeAgent.OK.Click()
#print app.FreeAgent.MenuItem("File->Purge and compact").GetProperties()
#app.FreeAgent.MenuSelect("File->Purge and Compact->PurgeFolder")
#app.PurgeFoldersInDesks.Cancel.Click()
# this is strange - when I do it by hand this is "Purge Folder" but during
# automation the text of the menu item is Purge Selected Folders
# FIXED - need to init the sub menu!
app.FreeAgent.MenuSelect("File->Purge and Compact->Purge Folder")
app.AgentTip.OK.Click()
app.FreeAgent.MenuSelect("File->Import and Export->Import Messages")
app.ImportMessages.Cancel.Click()
app.FreeAgent.MenuSelect("File->Import and Export->Import Address Book")
app.ImportAddresses.Cancel.Click()
app.FreeAgent.MenuSelect("File->Import and Export->Export Address Book")
app.ExportAddresses.Cancel.Click()
# pick something other then a file menu item
app.FreeAgent.MenuSelect("Tools->ApplyFiltersToFolder")
if app.ToolsApplyFilters.OK.Exists():
app.ToolsApplyFilters.OK.Click()
#app.AgentTip.OK.Click()
#app.ApplyFiltersToFolders.Cancel.Click()
print "==" * 20
print "The Agent File Menu..."
print "==" * 20
pprint (app.FreeAgent.MenuItems()[1])
try:
app.FreeAgent.MenuSelect("File->Print")
app.Print.Cancel.Click()
except:
print "Print Menu was probably disabled"
# quit Agent
app.FreeAgent.MenuSelect("File -> Exit")

@ -1,99 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"Run some automations to test things"
__revision__ = "$Revision: 214 $"
import time
try:
from pywinauto import application
except ImportError:
import os.path
pywinauto_path = os.path.abspath(__file__)
pywinauto_path = os.path.split(os.path.split(pywinauto_path)[0])[0]
import sys
sys.path.append(pywinauto_path)
from pywinauto import application
from pywinauto import tests
from pywinauto.findbestmatch import MatchError
from pywinauto import findwindows
from pywinauto.timings import Timings
Timings.window_find_timeout = 10
def TestExceptions():
"Test some things that should raise exceptions"
# test that trying to connect_ to a non existent app fails
try:
app = application.Application()
app.connect_(path = ur"No process with this please")
assert False
except application.ProcessNotFoundError:
pass
# test that trying to connect_ to a non existent app fails
try:
app = application.Application()
app.start_(cmd_line = ur"No process with this please")
assert False
except application.AppStartError:
pass
# # try when it isn't connected
# try:
# app = application.Application()
# #app.start_(ur"c:\windows\system32\notepad.exe")
# app.Notepad.Click()
# #assert False
# except application.AppNotConnected:
# pass
def GetInfo():
app = application.Application()
app.start_(ur"notepad.exe")
app.Notepad.MenuSelect("File->PageSetup")
print "==" * 20
print "Windows of this application:", app.windows_()
print "The list of identifiers for the Page Setup dialog in Notepad"
print "==" * 20
app.PageSetup.print_control_identifiers()
print "==" * 20
print "The list of identifiers for the 2nd Edit control in the dialog"
app.PageSetup.Edit2.print_control_identifiers()
print "==" * 20
app.PageSetup.OK.CloseClick()
app.Notepad.MenuSelect("File->Exit")
if __name__ == '__main__':
TestExceptions()
GetInfo()

@ -1,82 +0,0 @@
try:
from pywinauto import application
except ImportError:
import os.path
pywinauto_path = os.path.abspath(__file__)
pywinauto_path = os.path.split(os.path.split(pywinauto_path)[0])[0]
import sys
sys.path.append(pywinauto_path)
from pywinauto import application
import sys
import time
import os.path
from pywinauto import WindowAmbiguousError
if len(sys.argv) < 2:
print "please specify a web address to download"
sys.exit()
web_addresss = sys.argv[1]
if len(sys.argv) > 2:
outputfilename = sys.argv[2]
else:
outputfilename = web_addresss
outputfilename = outputfilename.replace('/', '')
outputfilename = outputfilename.replace('\\', '')
outputfilename = outputfilename.replace(':', '')
if not (outputfilename.lower().endswith("htm") or
outputfilename.lower().endswith("html")):
outputfilename += ".html"
# make sure that we have an absolute path - otherwise it is
# hard to know where firefox might save the file!
outputfilename = os.path.abspath(outputfilename)
# start IE with a start URL of what was passed in
app = application.Application().start_(
r"c:\program files\Mozilla Firefox\Firefox.exe %s"% web_addresss)
# some pages are slow to open - so wait some seconds
time.sleep(4)
# mozilla is one of thos applications that use existing windows
# if they exist (at least on my machine!)
# so if we cannot find any window for that process
# - find the actual process
# - connect to it
if app.windows_():
mozilla = app.window_(title_re = ".*Mozilla Firefox")
else:
app = application.Application().connect_(title_re = ".*Mozilla Firefox")
mozilla = app.window_(title_re = ".*Mozilla Firefox")
# ie doesn't define it's menus as Menu's but actually as a toolbar!
print "No Menu's in FireFox:", mozilla.MenuItems()
# File -> Save As
mozilla.TypeKeys("%FA")
#ie.Toolbar3.PressButton("File")
app.SaveAs.FileNameEdit.SetEditText(outputfilename)
app.SaveAs.Save.CloseClick()
try:
# if asked to overwrite say yes
if app.SaveAs.Yes.Exists():
app.SaveAs.Yes.CloseClick()
except WindowAmbiguousError, e:
for w in e.windows:
w = HwndWrapper(w)
print w.WindowText(), w.Class()
print "saved:", outputfilename
# File close tab or close
#(Firefox makes it easy for us having the same shortcut for both!
mozilla.TypeKeys("%FC")

@ -1,61 +0,0 @@
try:
from pywinauto import application
except ImportError:
import os.path
pywinauto_path = os.path.abspath(__file__)
pywinauto_path = os.path.split(os.path.split(pywinauto_path)[0])[0]
import sys
sys.path.append(pywinauto_path)
from pywinauto import application
import sys
import time
import os.path
if len(sys.argv) < 2:
print "please specify a web address to download"
sys.exit()
web_addresss = sys.argv[1]
if len(sys.argv) > 2:
outputfilename = sys.argv[2]
else:
outputfilename = web_addresss
outputfilename = outputfilename.replace('/', '')
outputfilename = outputfilename.replace('\\', '')
outputfilename = outputfilename.replace(':', '')
outputfilename = os.path.abspath(outputfilename)
# start IE with a start URL of what was passed in
app = application.Application().start_(
r"c:\program files\internet explorer\iexplore.exe %s"% web_addresss)
# some pages are slow to open - so wait some seconds
time.sleep(4)
ie = app.window_(title_re = ".*Microsoft Internet Explorer.*")
# ie doesn't define it's menus as Menu's but actually as a toolbar!
print "No Menu's in IE:", ie.MenuItems()
print "They are implemented as a toolbar:", ie.Toolbar3.Texts()
ie.TypeKeys("%FA")
#ie.Toolbar3.PressButton("File")
app.SaveWebPage.FileNameEdit.SetEditText(os.path.join(r"c:\.temp",outputfilename))
app.SaveWebPage.Save.CloseClick()
# if asked to overwrite say yes
if app.SaveWebPage.Yes.Exists():
app.SaveWebPage.Yes.CloseClick()
print "saved:", outputfilename
# quit IE
ie.TypeKeys("%FC")

@ -1,89 +0,0 @@
#encoding=latin1
"Reimplement some of the watsup tests using pywinauto"
import sys
from time import sleep
import os
import os.path
from application import Application, WindowNotFoundError
def do_test_1():
"1st Watsup Test"
app = Application().start_(r"c:\windows\Notepad")
notepadWindow = app.Notepad
notepadWindow.Edit1.SetEditText(u"Hello, ägain!", 0, -1)
sleep(0.8)
notepadWindow.Edit.SetEditText("\r\nYou still there?")
sleep(0.2)
notepadWindow.Edit.SetEditText("\r\nGoing Bye Bye now!!")
sleep(1)
notepadWindow.MenuSelect("File->Exit")
app.Notepad.No.Click()
def do_test_2():
"2nd Watsup Test"
filename = 'atestfile.txt'
if os.path.exists(filename):
os.remove(filename)
app = Application()
try:
app.connect_(title ='Simple Form')
except WindowNotFoundError:
app.start_(r'examples\simple.exe')
form = app.SimpleForm
form.Edit.SetText(filename)
sleep(.6)
print 'clicking button to create file'
form.CreateFile.Click()
# now check that the file is there
if os.path.exists(filename):
print 'file %s is present' % filename
else:
print "file %s isn't there" % filename
form.MenuSelect("File->Exit")
def do_test_3():
"3rd Watsup Test"
app = Application()
try:
app.connect_(title ='Performance Form 2')
except WindowNotFoundError:
app.start_(r'examples\perform2.exe')
app.PerformanceForm1.Clickme.Click()
waited = 0
while not app.PerformacneForm1.Edit1._.Texts and not waited >= 1:
print 'waiting'
sleep(.1)
waited += .1
print `app.PerformacneForm1.Edit1._.Texts`
def Main():
"run the specified test"
for test_num in sys.argv[1:]:
globals()['do_test_%s'%test_num] ()
if __name__ == "__main__":
Main()

@ -1,156 +0,0 @@
"""Automate WinRAR evaluation copy
We hit a few dialogs and save XML dump and
screenshot from each dialog.
Specify a language at the command line:
0 Czech
1 German
2 French
More then likely you will need to modify the apppath
entry in the 't' dictionary to where you have
extracted the WinRAR executables.
"""
__revision__ = "$Revision$"
import sys
from pywinauto.application import Application
import time
folders = ['wrar351cz', 'wrar351d', 'wrar351fr']
# translations for each language
t = {
'apppath' : (
'c:\.temp\wrar351fr\winrar.exe',
'c:\.temp\wrar351d\winrar.exe',
'c:\.temp\wrar351cz\winrar.exe'
),
# Buy Licence Dialog
'Buy Licence' : (
"Acheter une licence pur winRAR",
"Bittekaufensieeine",
"Zakuptesiprosmlicenci WinRARu"),
'Close' : (
"Fermer",
"Schleissen",
"Zavrit"),
# Options->Configure menu items
"Options->Configure" : (
"Options->Configuration",
"Optionen->Einstellungen",
"Moznosti->Nastaveni"),
# Configure/Options dialog box
'Configure' : (
"Configuration",
"Einstellungen",
"Nastaveni"),
# personalise toolbar buttons button
'Buttons' : (
"Boutons",
"Schaltflachen",
"Vybrattlacitka"),
# Personalize toolbars dialog
'PeronnaliseToolbars' : (
"Peronnalisation de la barre doutils",
"Werkzeugleisteanpassen",
"Vybertlaciteknastrojovelisty"),
# create profile button
'CreateDefaultProfile' : (
u"Creerleprofilpardéfault",
"Standardfestlegen",
"Vytvoritimplicitni"),
# create profile dialog box title
'ConfigureDefaultOptions' : (
"Configurer les options de compre...",
"Standardkomprimierungs",
"Zmenaimplicitnichnast..."),
# context menu's button
"ContextMenus" : (
"Menus contextuels",
"Optionenimkontextmenu",
"Polozkykontextovehamenu"),
# context menu's dialog
"contextMenuDlg" : (
"Rubriques des menus contextuels",
"OptionenindenKontextmenus",
"Polozkykontextovehamenu"),
# file->exit menu option
"File->Exit" : (
"Fichier->Quitter",
"Datei->Beenden",
"Soubor->Konec"),
}
def get_winrar_dlgs(rar_dlg, app, lang):
rar_dlg.MenuSelect(t["Options->Configure"][lang])
optionsdlg = app[t['Configure'][lang]]
optionsdlg.WriteToXML("Options_%d.xml"%lang)
optionsdlg.CaptureAsImage().save("Options_%d.png"%lang)
optionsdlg[t['Buttons'][lang]].Click()
contextMenuDlg = app[t['PeronnaliseToolbars'][lang]]
contextMenuDlg.WriteToXML("PersonaliseToolbars_%d.xml"%lang)
contextMenuDlg.CaptureAsImage().save("PersonaliseToolbars_%d.png"%lang)
contextMenuDlg.OK.Click()
optionsdlg.TabCtrl.Select(1)
optionsdlg[t['CreateDefaultProfile'][lang]].Click()
defaultOptionsDlg = app[t['ConfigureDefaultOptions'][lang]]
defaultOptionsDlg.WriteToXML("DefaultOptions_%d.xml"%lang)
defaultOptionsDlg.CaptureAsImage().save("DefaultOptions_%d.png"%lang)
defaultOptionsDlg.OK.Click()
optionsdlg.TabCtrl.Select(6)
optionsdlg[t['ContextMenus'][lang]].Click()
anotherMenuDlg = app[t['contextMenuDlg'][lang]]
anotherMenuDlg.WriteToXML("2ndMenuDlg_%d.xml"%lang)
anotherMenuDlg.CaptureAsImage().save("2ndMenuDlg_%d.png"%lang)
anotherMenuDlg.OK.Click()
optionsdlg.OK.Click()
# get the languages as an integer
langs = [int(arg) for arg in sys.argv[1:]]
for lang in langs:
# start the application
app = Application().start_(t['apppath'][lang])
# we have to wait for the Licence Dialog to open
time.sleep(2)
# close the Buy licence dialog box
licence_dlg = app[t['Buy Licence'][lang]]
licence_dlg[t['Close'][lang]].Click()
# find the WinRar main dialog
rar_dlg = app.window_(title_re = ".* - WinRAR.*")
# dump and capture some dialogs
get_winrar_dlgs(rar_dlg, app, lang)
# exit WinRar
time.sleep(.5)
rar_dlg.MenuSelect(t['File->Exit'][lang])

@ -1,124 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"Run some automations to test things"
__revision__ = "$Revision: 214 $"
import time
try:
from pywinauto import application
except ImportError:
import os.path
pywinauto_path = os.path.abspath(__file__)
pywinauto_path = os.path.split(os.path.split(pywinauto_path)[0])[0]
import sys
sys.path.append(pywinauto_path)
from pywinauto import application
from pywinauto import tests
from pywinauto.findbestmatch import MatchError
from pywinauto import findwindows
from pywinauto import WindowAmbiguousError
from pywinauto.controls import WrapHandle
from pywinauto.timings import Timings
Timings.Fast()
app = application.Application()
# for distribution we don't want to connect to anybodies application
# because we may mess up something they are working on!
#try:
# app.connect_(path = ur"c:\windows\system32\mspaint.exe")
#except application.ProcessNotFoundError:
# app.start_(ur"c:\windows\system32\mspaint.exe")
app.start_(ur"mspaint.exe")
pwin = app.window_(title_re = ".* - Paint")
# get the previous image size
pwin.MenuSelect("Image->Attributes")
prev_width = app.Attributes.Edit1.Texts()[1]
prev_height = app.Attributes.Edit2.Texts()[1]
# set our preferred area
app.Attributes.Edit1.TypeKeys("350") # you can use TypeKeys or
app.Attributes.Edit2.SetEditText("350") # SetText - they work differently!
app.Attributes.OK.CloseClick()
try:
# get the reference to the Canvas window
canvas = pwin.Afx100000008
canvas.WrapperObject()
except WindowAmbiguousError, e:
print e, e.windows
for w in e.windows:
w = WrapHandle(w)
print w.WindowText(), w.Class()
import sys
sys.exit()
# make sure the pencil tool is selected
pwin.Tools2.Click(coords = (91, 16))
size = 15
num_slants = 20
# draw the axes
canvas.PressMouse(coords = (size, size * num_slants))
canvas.MoveMouse(coords = (size*num_slants, size*num_slants))
canvas.MoveMouse(coords = (size * num_slants, size))
canvas.ReleaseMouse()
# now draw the lines
print "*** if you move your mouse over Paint as it is drawing ***"
print "*** these lines then it will mess up the drawing! ***\n"
for i in range(1, num_slants):
endcoords = (size * (num_slants - i), size * num_slants)
canvas.PressMouse(coords = (size * num_slants, i * size)) # start
canvas.MoveMouse(coords = endcoords) # x and y axes
canvas.ReleaseMouse(coords = endcoords)
# may fail if PIL is not installed
image = canvas.CaptureAsImage()
if image:
image.save(r"Application_Paint_test.png")
print "Saved image as: Application_Paint_test.png"
# set it back to original width and height
pwin.MenuSelect("Image->Attributes")
# set our preferred area
app.Attributes.Edit1.TypeKeys(prev_width)
app.Attributes.Edit2.SetEditText(prev_height)
app.Attributes.OK.CloseClick()
# close Paint
pwin.MenuSelect("File->Exit")
if app.Paint.No.Exists():
#print "It existed!"
# Click the no button on the message box asking if we want to save
app.Paint.No.CloseClick()

@ -1,269 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"Run some automations to test things"
__revision__ = "$Revision: 214 $"
import time
try:
from pywinauto import application
except ImportError:
import os.path
pywinauto_path = os.path.abspath(__file__)
pywinauto_path = os.path.split(os.path.split(pywinauto_path)[0])[0]
import sys
sys.path.append(pywinauto_path)
from pywinauto import application
import pywinauto
from pywinauto import application
from pywinauto import tests
#from pywinauto.findbestmatch import MatchError
from pywinauto.timings import Timings
def RunNotepad():
"Run notepad and do some small stuff with it"
print "Run with option 'language' e.g. notepad_fast.py language to use"
print "application data. This should work on any language Windows/Notepad"
print
print "Trying fast timing settings - it's possible these won't work"
print "if pywinauto tries to access a window that is not accessible yet"
# use fast timings - but allow to wait for windows a long time
Timings.Fast()
Timings.window_find_timeout = 10
start = time.time()
run_with_appdata = False
if len(sys.argv) > 1 and sys.argv[1].lower() == 'language':
run_with_appdata = True
scriptdir = os.path.split(os.path.abspath(__file__))[0]
if run_with_appdata:
print "\nRunning this script so it will load application data and run"
print "against any lanuguage version of Notepad/Windows"
# make sure that the app data gets read from the same folder as
# the script
app = application.Application(
os.path.join(scriptdir, "Notepad_fast.pkl"))
else:
app = application.Application()
## for distribution we don't want to connect to anybodies application
## because we may mess up something they are working on!
#try:
# app.connect_(path = ur"c:\windows\system32\notepad.exe")
#except application.ProcessNotFoundError:
# app.start_(ur"c:\windows\system32\notepad.exe")
app.start_(ur"notepad.exe")
app.Notepad.MenuSelect("File->PageSetup")
# ----- Page Setup Dialog ----
# Select the 4th combobox item
app.PageSetupDlg.SizeComboBox.Select(4)
# Select the 'Letter' combobox item or the Letter
try:
app.PageSetupDlg.SizeComboBox.Select("Letter")
except ValueError:
app.PageSetupDlg.SizeComboBox.Select('Letter (8.5" x 11")')
app.PageSetupDlg.SizeComboBox.Select(2)
# run some tests on the Dialog. List of available tests:
# "AllControls",
# "AsianHotkey",
# "ComboBoxDroppedHeight",
# "CompareToRefFont",
# "LeadTrailSpaces",
# "MiscValues",
# "Missalignment",
# "MissingExtraString",
# "Overlapping",
# "RepeatedHotkey",
# "Translation",
# "Truncation",
bugs = app.PageSetupDlg.RunTests('RepeatedHotkey Truncation')
# if there are any bugs they will be printed to the console
# and the controls will be highlighted
tests.print_bugs(bugs)
# ----- Next Page Setup Dialog ----
app.PageSetupDlg.Printer.Click()
# do some radio button clicks
# Open the Connect to printer dialog so we can
# try out checking/unchecking a checkbox
app.PageSetupDlg.Network.Click()
# ----- Connect To Printer Dialog ----
# Select a checkbox
app.ConnectToPrinter.ExpandByDefault.Check()
app.ConnectToPrinter.ExpandByDefault.UnCheck()
# try doing the same by using click
app.ConnectToPrinter.ExpandByDefault.Click()
app.ConnectToPrinter.ExpandByDefault.Click()
# close the dialog
app.ConnectToPrinter.Cancel.CloseClick()
# ----- 2nd Page Setup Dialog again ----
app.PageSetupDlg.Properties.Click()
doc_props = app.window_(title_re = ".*Properties$")
doc_props.Wait('exists', timeout = 40)
#
# # ----- Document Properties Dialog ----
# # some tab control selections
# # Two ways of selecting tabs with indices...
# doc_props.TabCtrl.Select(0)
# doc_props.TabCtrl.Select(1)
# try:
# doc_props.TabCtrl.Select(2)
# except IndexError:
# # not all users have 3 tabs in this dialog
# pass
#
# # or with text...
# #doc_props.TabCtrl.Select("PaperQuality")
# doc_props.TabCtrl.Select(1)
#
# try:
# #doc_props.TabCtrl.Select("JobRetention")
# doc_props.TabCtrl.Select("3")
# except MatchError:
# # some people do not have the "Job Retention" tab
# pass
#
# doc_props.TabCtrl.Select("Finishing")
# #doc_props.TabCtrl.Select(0)
#
# # do some radio button clicks
# doc_props.RotatedLandscape.Click()
# doc_props.BackToFront.Click()
# doc_props.FlipOnShortEdge.Click()
#
# doc_props.Portrait.Click()
# doc_props._None.Click()
# #doc_props.FrontToBack.Click()
#
# # open the Advanced options dialog in two steps
# advbutton = doc_props.Advanced
# advbutton.Click()
#
# # close the 4 windows
#
# # ----- Advanced Options Dialog ----
# app.window_(title_re = ".* Advanced Options").Ok.Click()
# ----- Document Properties Dialog again ----
doc_props.Cancel.CloseClick()
# for some reason my current printer driver
# window does not close cleanly :(
if doc_props.Cancel.Exists():
doc_props.OK.CloseClick()
# ----- 2nd Page Setup Dialog again ----
app.PageSetupDlg.OK.CloseClick()
# ----- Page Setup Dialog ----
app.PageSetupDlg.Ok.CloseClick()
# type some text - note that extended characters ARE allowed
app.Notepad.Edit.SetEditText(u"I am typing s\xe4me text to Notepad\r\n\r\n"
"And then I am going to quit")
app.Notepad.Edit.RightClick()
app.Popup.MenuItem("Right To Left Reading Order").Click()
#app.PopupMenu.MenuSelect("Paste", app.Notepad.ctrl_())
#app.Notepad.Edit.RightClick()
#app.PopupMenu.MenuSelect(
# "Right To Left Reading Order", app.Notepad.ctrl_())
#app.PopupMenu.MenuSelect(
# "Show unicode control characters", app.Notepad.ctrl_())
#time.sleep(1)
#app.Notepad.Edit.RightClick()
#app.PopupMenu.MenuSelect("Right To Left Reading Order", app.Notepad.ctrl_())
#time.sleep(1)
#app.Notepad.Edit.RightClick()
#app.PopupMenu.MenuSelect(
# "Insert Unicode control character -> IAFS", app.Notepad.ctrl_())
#time.sleep(1)
#app.Notepad.Edit.TypeKeys("{ESC}")
# the following shows that Sendtext does not accept
# accented characters - but does allow 'control' characters
app.Notepad.Edit.TypeKeys(u"{END}{ENTER}SendText d\xf6\xe9s "
u"s\xfcpp\xf4rt \xe0cce\xf1ted characters!!!", with_spaces = True)
# Try and save
app.Notepad.MenuSelect("File->SaveAs")
app.SaveAs.EncodingComboBox.Select("UTF-8")
app.SaveAs.FileNameEdit.SetEditText("Example-utf8.txt")
app.SaveAs.Save.CloseClick()
# my machine has a weird problem - when connected to the network
# the SaveAs Dialog appears - but doing anything with it can
# cause a LONG delay - the easiest thing is to just wait
# until the dialog is no longer active
# - Dialog might just be gone - because click worked
# - dialog might be waiting to disappear
# so can't wait for next dialog or for it to be disabled
# - dialog might be waiting to display message box so can't wait
# for it to be gone or for the main dialog to be enabled.
# while the dialog exists wait upto 30 seconds (and yes it can
# take that long on my computer sometimes :-( )
app.SaveAsDialog2.Cancel.WaitNot('enabled')
# If file exists - it asks you if you want to overwrite
try:
app.SaveAs.Yes.Wait('exists').CloseClick()
except pywinauto.MatchError:
pass
# exit notepad
app.Notepad.MenuSelect("File->Exit")
if not run_with_appdata:
app.WriteAppData(os.path.join(scriptdir, "Notepad_fast.pkl"))
print "That took %.3f to run"% (time.time() - start)
if __name__ == "__main__":
RunNotepad()

@ -1,100 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"Run some automations to test things"
__revision__ = "$Revision: 214 $"
import time
from pywinauto import application
from pywinauto import tests
from pywinauto.findbestmatch import MatchError
from pywinauto import findwindows
#application.set_timing(3, .5, 10, .5, .4, .2, .2, .1, .2, .5)
"Run a quick test on Notepad"
app = application.Application()
app.start_(ur"notepad.exe")
app['Notepad'].Wait('ready')
app['Notepad'].MenuSelect("File->PageSetup")
# ----- Page Setup Dialog ----
# Select the 4th combobox item
app['PageSetupDlg']['ComboBox1'].Select(4)
# Select the 'Letter' combobox item
app['PageSetupDlg']['ComboBox1'].Select("Letter")
# ----- Next Page Setup Dialog ----
app['PageSetupDlg']['Printer'].Click()
app['PageSetupDlg']['Network'].Click()
# ----- Connect To Printer Dialog ----
# Select a checkbox
app['ConnectToPrinter']['ExpandByDef'].Check()
# Uncheck it again - but use Click this time!
app['ConnectToPrinter']['ExpandByDef'].Click()
app['ConnectToPrinter']['OK'].CloseClick()
# ----- 2nd Page Setup Dialog again ----
app['PageSetupDlg2']['Properties'].Click()
# ----- Document Properties Dialog ----
doc_props = app.window_(title_re = ".*Document Properties")
# Two ways of selecting tabs
doc_props['TabCtrl'].Select(2)
doc_props['TabCtrl'].Select("Layout")
# click a Radio button
doc_props['RotatedLandscape'].Click()
doc_props['Portrait'].Click()
# open the Advanced options dialog in two steps
advbutton = doc_props['Advanced']
advbutton.Click()
# ----- Advanced Options Dialog ----
# close the 4 windows
app.window_(title_re = ".* Advanced Options")['Ok'].Click()
# ----- Document Properties Dialog again ----
doc_props['Cancel'].CloseClick()
# ----- 2nd Page Setup Dialog again ----
app['PageSetup2']['OK'].CloseClick()
# ----- Page Setup Dialog ----
app['PageSetup']['Ok'].CloseClick()
# type some text
app['Notepad']['Edit'].SetEditText(u"I am typing s\xe4me text to Notepad"
"\r\n\r\nAnd then I am going to quit")
# exit notepad
app['NotepadDialog'].MenuSelect("File->Exit")
app['Notepad']['No'].CloseClick()

@ -1,243 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"Run some automations to test things"
__revision__ = "$Revision: 214 $"
import time
try:
from pywinauto import application
except ImportError:
import os.path
pywinauto_path = os.path.abspath(__file__)
pywinauto_path = os.path.split(os.path.split(pywinauto_path)[0])[0]
import sys
sys.path.append(pywinauto_path)
from pywinauto import application
from pywinauto import tests
from pywinauto.findbestmatch import MatchError
from pywinauto import findwindows
from pywinauto.timings import Timings
print "Setting timings to slow settings, may be necessary for"
print "slow applications or slow machines."
Timings.Slow()
#application.set_timing(3, .5, 10, .5, .4, .2, .2, .1, .2, .5)
def RunNotepad():
"Run notepad and do some small stuff with it"
start = time.time()
app = application.Application()
## for distribution we don't want to connect to anybodies application
## because we may mess up something they are working on!
#try:
# app.connect_(path = ur"c:\windows\system32\notepad.exe")
#except application.ProcessNotFoundError:
# app.start_(ur"c:\windows\system32\notepad.exe")
app.start_(ur"notepad.exe")
app.Notepad.MenuSelect("File->PageSetup")
# ----- Page Setup Dialog ----
# Select the 4th combobox item
app.PageSetupDlg.SizeComboBox.Select(4)
# Select the 'Letter' combobox item or the Letter
try:
app.PageSetupDlg.SizeComboBox.Select("Letter")
except ValueError:
app.PageSetupDlg.SizeComboBox.Select('Letter (8.5" x 11")')
app.PageSetupDlg.SizeComboBox.Select(2)
# run some tests on the Dialog. List of available tests:
# "AllControls",
# "AsianHotkey",
# "ComboBoxDroppedHeight",
# "CompareToRefFont",
# "LeadTrailSpaces",
# "MiscValues",
# "Missalignment",
# "MissingExtraString",
# "Overlapping",
# "RepeatedHotkey",
# "Translation",
# "Truncation",
bugs = app.PageSetupDlg.RunTests('RepeatedHotkey Truncation')
# if there are any bugs they will be printed to the console
# and the controls will be highlighted
tests.print_bugs(bugs)
# ----- Next Page Setup Dialog ----
app.PageSetupDlg.Printer.Click()
# do some radio button clicks
# Open the Connect to printer dialog so we can
# try out checking/unchecking a checkbox
app.PageSetupDlg.Network.Click()
# ----- Connect To Printer Dialog ----
# Select a checkbox
app.ConnectToPrinter.ExpandByDefault.Check()
app.ConnectToPrinter.ExpandByDefault.UnCheck()
# try doing the same by using click
app.ConnectToPrinter.ExpandByDefault.Click()
app.ConnectToPrinter.ExpandByDefault.Click()
# close the dialog
app.ConnectToPrinter.Cancel.CloseClick()
# ----- 2nd Page Setup Dialog again ----
app.PageSetupDlg.Properties.Click()
doc_props = app.window_(title_re = ".*Properties$")
doc_props.Wait('exists', timeout = 40)
# ----- Document Properties Dialog ----
# some tab control selections
# Two ways of selecting tabs with indices...
doc_props.TabCtrl.Select(0)
doc_props.TabCtrl.Select(1)
try:
doc_props.TabCtrl.Select(2)
except IndexError:
# not all users have 3 tabs in this dialog
pass
# or with text...
doc_props.TabCtrl.Select("PaperQuality")
try:
doc_props.TabCtrl.Select("JobRetention")
except MatchError:
# some people do not have the "Job Retention" tab
pass
# doc_props.TabCtrl.Select("Layout")
#
# # do some radio button clicks
# doc_props.RotatedLandscape.Click()
# doc_props.BackToFront.Click()
# doc_props.FlipOnShortEdge.Click()
#
# doc_props.Portrait.Click()
# doc_props._None.Click()
# doc_props.FrontToBack.Click()
#
# # open the Advanced options dialog in two steps
# advbutton = doc_props.Advanced
# advbutton.Click()
#
# # close the 4 windows
#
# # ----- Advanced Options Dialog ----
# app.window_(title_re = ".* Advanced Options").Ok.Click()
# ----- Document Properties Dialog again ----
doc_props.Cancel.CloseClick()
# for some reason my current printer driver
# window does not close cleanly :(
if doc_props.Cancel.Exists():
doc_props.OK.CloseClick()
# ----- 2nd Page Setup Dialog again ----
app.PageSetupDlg.OK.CloseClick()
# ----- Page Setup Dialog ----
app.PageSetupDlg.Ok.CloseClick()
# type some text - note that extended characters ARE allowed
app.Notepad.Edit.SetEditText(u"I am typing s\xe4me text to Notepad\r\n\r\n"
"And then I am going to quit")
app.Notepad.Edit.RightClick()
app.Popup.MenuItem("Right To Left Reading Order").Click()
#app.PopupMenu.MenuSelect("Paste", app.Notepad.ctrl_())
#app.Notepad.Edit.RightClick()
#app.PopupMenu.MenuSelect("Right To Left Reading Order", app.Notepad.ctrl_())
#app.PopupMenu.MenuSelect("Show unicode control characters", app.Notepad.ctrl_())
#time.sleep(1)
#app.Notepad.Edit.RightClick()
#app.PopupMenu.MenuSelect("Right To Left Reading Order", app.Notepad.ctrl_())
#time.sleep(1)
#app.Notepad.Edit.RightClick()
#app.PopupMenu.MenuSelect("Insert Unicode control character -> IAFS", app.Notepad.ctrl_())
#time.sleep(1)
#app.Notepad.Edit.TypeKeys("{ESC}")
# the following shows that Sendtext does not accept
# accented characters - but does allow 'control' characters
app.Notepad.Edit.TypeKeys(u"{END}{ENTER}SendText d\xf6\xe9s "
u"s\xfcpp\xf4rt \xe0cce\xf1ted characters!!!", with_spaces = True)
# Try and save
app.Notepad.MenuSelect("File->SaveAs")
app.SaveAs.EncodingComboBox.Select("UTF-8")
app.SaveAs.FileNameEdit.SetEditText("Example-utf8.txt")
app.SaveAs.Save.CloseClick()
# my machine has a weird problem - when connected to the network
# the SaveAs Dialog appears - but doing anything with it can
# cause a LONG delay - the easiest thing is to just wait
# until the dialog is no longer active
# - Dialog might just be gone - because click worked
# - dialog might be waiting to disappear
# so can't wait for next dialog or for it to be disabled
# - dialog might be waiting to display message box so can't wait
# for it to be gone or for the main dialog to be enabled.
# while the dialog exists wait upto 30 seconds (and yes it can
# take that long on my computer sometimes :-( )
app.SaveAsDialog2.Cancel.WaitNot('enabled')
# If file exists - it asks you if you want to overwrite
try:
app.SaveAs.Yes.Wait('exists').CloseClick()
except pywinauto.MatchError:
pass
# exit notepad
app.Notepad.MenuSelect("File->Exit")
#if not run_with_appdata:
# app.WriteAppData(os.path.join(scriptdir, "Notepad_fast.pkl"))
print "That took %.3f to run"% (time.time() - start)
if __name__ == "__main__":
RunNotepad()

@ -1,62 +0,0 @@
# -*- coding: UTF-8 -*-
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
import time
from pywinauto import application
from pywinauto import tests
def SakuraTest():
app = application.Application()
app.start_(ur"\Program Files\sakura\sakura.exe")
mainwin = app.window_(title_re = u'\(無題\) - sakura .*')
# menu's from this application are not recovered well
# but even with Japanese Regional settings they are not
# rendered correctly by windows!
# so using keys to select a menu item
# open some dialog
mainwin.TypeKeys("%OC")
dlg = app.window_(title = u'共通設定')
dlg.window_(title_re = ur"フリーカーソル.*").Click()
dlg.MSDOS.Click()
dlg.Cancel.Click()
# quit the application
mainwin.TypeKeys("%FX")
def Main():
start = time.time()
SakuraTest()
print "Total time taken:", time.time() - start
if __name__ == "__main__":
Main()

@ -1,65 +0,0 @@
# -*- coding: UTF-8 -*-
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
import time
from pywinauto import application
from pywinauto import tests
def SakuraTest():
app = application.Application()
app.start_(ur"\Program Files\sakura\sakura.exe")
mainwin = app[u'無題sakura']
# menu's from this application are not recovered well
# but even with Japanese Regional settings they are not
# rendered correctly by windows!
# so using keys to select a menu item
# open some dialog
mainwin.TypeKeys("%OC")
dlg = app[u'共通設定']
app[u'共通設定'][u"フリーカーソル"].Click()
dlg.MSDOS.Click()
dlg.Cancel.Click()
# quit the application
mainwin.TypeKeys("%FX")
def Main():
start = time.time()
SakuraTest()
print "Total time taken:", time.time() - start
if __name__ == "__main__":
Main()

@ -1,89 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"Some automation of Windows Media player"
__revision__ = "$Revision$"
#import os
import time
import sys
try:
from pywinauto import application
except ImportError:
import os.path
pywinauto_path = os.path.abspath(__file__)
pywinauto_path = os.path.split(os.path.split(pywinauto_path)[0])[0]
import sys
sys.path.append(pywinauto_path)
from pywinauto import application
def WindowsMedia():
app = application.Application()
try:
app.start_( # connect_(path =
ur"C:\Program Files\Windows Media Player\wmplayer.exe")
except application.ProcessNotFoundError:
print "You must first start Windows Media "\
"Player before running this script"
sys.exit()
app.WindowsMediaPlayer.MenuSelect("View->GoTo->Library")
app.WindowsMediaPlayer.MenuSelect("View->Choose Columns")
#for ctrl in app.ChooseColumns.Children():
# print ctrl.Class()
print "Is it checked already:", app.ChooseColumsn.ListView.IsChecked(1)
# Check an Item in the listview
app.ChooseColumns.ListView.Check(1)
time.sleep(.5)
print "Shold be checked now:", app.ChooseColumsn.ListView.IsChecked(1)
# Uncheck it
app.ChooseColumns.ListView.UnCheck(1)
time.sleep(.5)
print "Should not be checked now:", app.ChooseColumsn.ListView.IsChecked(1)
# Check it again
app.ChooseColumns.ListView.Check(1)
time.sleep(.5)
app.ChooseColumsn.Cancel.Click()
app.WindowsMediaPlayer.MenuSelect("File->Exit")
def Main():
start = time.time()
WindowsMedia()
print "Total time taken:", time.time() - start
if __name__ == "__main__":
Main()

@ -1,31 +0,0 @@
@echo off
doc_src\build_autodoc_files.py
sphinx-build -b html doc_src pywinauto\docs
REM c:\.temp\pudge\pudge\cli --documents doc_source\index.rst,doc_source\controls_overview.rst,doc_source\howto.rst,doc_source\getting_started.rst,history.txt,license.txt,todo.txt --title pywinauto -v -d website -m pywinauto.application,pywinauto.taskbar,pywinauto.clipboard,pywinauto.timings,pywinauto.findbestmatch,pywinauto.findwindows,pywinauto.handleprops,pywinauto.XMLHelpers,pywinauto.controls,pywinauto.tests -t doc_source\template
REM These are the python modules
REM application.py
REM clipboard.py
REM findbestmatch.py
REM findwindows.py
REM handleprops.py
REM taskbar.py
REM win32defines.py
REM win32functions.py
REM win32structures.py
REM XMLHelpers.py
REM controls
REM tests
REM c:\.temp\pudge\pudge\cli --title pywinauto -v -m pywinauto --documents docs\index.rst,history.txt,license.txt,todo.txt,docs\howto.rst -d pudge_output_green_paste -t \.temp\pudge\pudge\template\green_paste

BIN
notepad-simple2-ir.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

@ -1,691 +0,0 @@
# -*- coding: utf-8 -*-
"""
Check that SendInput can work the way we want it to
The tips and tricks at http://www.pinvoke.net/default.aspx/user32.sendinput
is useful!
"""
import time
import ctypes
__all__ = ['KeySequenceError', 'SendKeys']
#pylint: disable-msg=R0903
DEBUG = 0
MapVirtualKey = ctypes.windll.user32.MapVirtualKeyW
SendInput = ctypes.windll.user32.SendInput
VkKeyScan = ctypes.windll.user32.VkKeyScanW
VkKeyScan.restype = ctypes.c_short
VkKeyScan.argtypes = [ctypes.c_wchar]
DWORD = ctypes.c_ulong
LONG = ctypes.c_long
WORD = ctypes.c_ushort
# C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4283
class MOUSEINPUT(ctypes.Structure):
"Needed for complete definition of INPUT structure - not used"
_pack_ = 2
_fields_ = [
# C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4283
('dx', LONG),
('dy', LONG),
('mouseData', DWORD),
('dwFlags', DWORD),
('time', DWORD),
('dwExtraInfo', DWORD),
]
assert ctypes.sizeof(MOUSEINPUT) == 24, ctypes.sizeof(MOUSEINPUT)
assert ctypes.alignment(MOUSEINPUT) == 2, ctypes.alignment(MOUSEINPUT)
# C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4292
class KEYBDINPUT(ctypes.Structure):
"A particular keyboard event"
_pack_ = 2
_fields_ = [
# C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4292
('wVk', WORD),
('wScan', WORD),
('dwFlags', DWORD),
('time', DWORD),
('dwExtraInfo', DWORD),
]
assert ctypes.sizeof(KEYBDINPUT) == 16, ctypes.sizeof(KEYBDINPUT)
assert ctypes.alignment(KEYBDINPUT) == 2, ctypes.alignment(KEYBDINPUT)
class HARDWAREINPUT(ctypes.Structure):
"Needed for complete definition of INPUT structure - not used"
_pack_ = 2
_fields_ = [
# C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4300
('uMsg', DWORD),
('wParamL', WORD),
('wParamH', WORD),
]
assert ctypes.sizeof(HARDWAREINPUT) == 8, ctypes.sizeof(HARDWAREINPUT)
assert ctypes.alignment(HARDWAREINPUT) == 2, ctypes.alignment(HARDWAREINPUT)
# C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4314
class UNION_INPUT_STRUCTS(ctypes.Union):
"The C Union type representing a single Event of any type"
_fields_ = [
# C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4314
('mi', MOUSEINPUT),
('ki', KEYBDINPUT),
('hi', HARDWAREINPUT),
]
assert ctypes.sizeof(UNION_INPUT_STRUCTS) == 24, \
ctypes.sizeof(UNION_INPUT_STRUCTS)
assert ctypes.alignment(UNION_INPUT_STRUCTS) == 2, \
ctypes.alignment(UNION_INPUT_STRUCTS)
# C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4310
class INPUT(ctypes.Structure):
"See: http://msdn.microsoft.com/en-us/library/ms646270%28VS.85%29.aspx"
_pack_ = 2
_fields_ = [
# C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4310
('type', DWORD),
# Unnamed field renamed to '_'
('_', UNION_INPUT_STRUCTS),
]
assert ctypes.sizeof(INPUT) == 28, ctypes.sizeof(INPUT)
assert ctypes.alignment(INPUT) == 2, ctypes.alignment(INPUT)
INPUT_KEYBOARD = 1
KEYEVENTF_EXTENDEDKEY = 1
KEYEVENTF_KEYUP = 2
KEYEVENTF_UNICODE = 4
KEYEVENTF_SCANCODE = 8
VK_SHIFT = 16
VK_CONTROL = 17
VK_MENU = 18
# 'codes' recognized as {CODE( repeat)?}
CODES = {
'BACK': 8,
'BACKSPACE':8,
'BKSP': 8,
'BREAK': 3,
'BS': 8,
'CAP': 20,
'CAPSLOCK': 20,
'DEL': 46,
'DELETE': 46,
'DOWN': 40,
'END': 35,
'ENTER': 13,
'ESC': 27,
'F1': 112,
'F2': 113,
'F3': 114,
'F4': 115,
'F5': 116,
'F6': 117,
'F7': 118,
'F8': 119,
'F9': 120,
'F10': 121,
'F11': 122,
'F12': 123,
'F13': 124,
'F14': 125,
'F15': 126,
'F16': 127,
'F17': 128,
'F18': 129,
'F19': 130,
'F20': 131,
'F21': 132,
'F22': 133,
'F23': 134,
'F24': 135,
'HELP': 47,
'HOME': 36,
'INS': 45,
'INSERT': 45,
'LEFT': 37,
'LWIN': 91,
'NUMLOCK': 144,
'PGDN': 34,
'PGUP': 33,
'PRTSC': 44,
'RIGHT': 39,
'RMENU': 165,
'RWIN': 92,
'SCROLLLOCK':145,
'SPACE': 32,
'TAB': 9,
'UP': 38,
'VK_ACCEPT': 30,
'VK_ADD': 107,
'VK_APPS': 93,
'VK_ATTN': 246,
'VK_BACK': 8,
'VK_CANCEL': 3,
'VK_CAPITAL': 20,
'VK_CLEAR': 12,
'VK_CONTROL': 17,
'VK_CONVERT': 28,
'VK_CRSEL': 247,
'VK_DECIMAL': 110,
'VK_DELETE': 46,
'VK_DIVIDE': 111,
'VK_DOWN': 40,
'VK_END': 35,
'VK_EREOF': 249,
'VK_ESCAPE': 27,
'VK_EXECUTE': 43,
'VK_EXSEL': 248,
'VK_F1': 112,
'VK_F2': 113,
'VK_F3': 114,
'VK_F4': 115,
'VK_F5': 116,
'VK_F6': 117,
'VK_F7': 118,
'VK_F8': 119,
'VK_F9': 120,
'VK_F10': 121,
'VK_F11': 122,
'VK_F12': 123,
'VK_F13': 124,
'VK_F14': 125,
'VK_F15': 126,
'VK_F16': 127,
'VK_F17': 128,
'VK_F18': 129,
'VK_F19': 130,
'VK_F20': 131,
'VK_F21': 132,
'VK_F22': 133,
'VK_F23': 134,
'VK_F24': 135,
'VK_FINAL': 24,
'VK_HANGEUL': 21,
'VK_HANGUL': 21,
'VK_HANJA': 25,
'VK_HELP': 47,
'VK_HOME': 36,
'VK_INSERT': 45,
'VK_JUNJA': 23,
'VK_KANA': 21,
'VK_KANJI': 25,
'VK_LBUTTON': 1,
'VK_LCONTROL':162,
'VK_LEFT': 37,
'VK_LMENU': 164,
'VK_LSHIFT': 160,
'VK_LWIN': 91,
'VK_MBUTTON': 4,
'VK_MENU': 18,
'VK_MODECHANGE': 31,
'VK_MULTIPLY': 106,
'VK_NEXT': 34,
'VK_NONAME': 252,
'VK_NONCONVERT': 29,
'VK_NUMLOCK': 144,
'VK_NUMPAD0': 96,
'VK_NUMPAD1': 97,
'VK_NUMPAD2': 98,
'VK_NUMPAD3': 99,
'VK_NUMPAD4': 100,
'VK_NUMPAD5': 101,
'VK_NUMPAD6': 102,
'VK_NUMPAD7': 103,
'VK_NUMPAD8': 104,
'VK_NUMPAD9': 105,
'VK_OEM_CLEAR': 254,
'VK_PA1': 253,
'VK_PAUSE': 19,
'VK_PLAY': 250,
'VK_PRINT': 42,
'VK_PRIOR': 33,
'VK_PROCESSKEY': 229,
'VK_RBUTTON': 2,
'VK_RCONTROL': 163,
'VK_RETURN': 13,
'VK_RIGHT': 39,
'VK_RMENU': 165,
'VK_RSHIFT': 161,
'VK_RWIN': 92,
'VK_SCROLL': 145,
'VK_SELECT': 41,
'VK_SEPARATOR': 108,
'VK_SHIFT': 16,
'VK_SNAPSHOT': 44,
'VK_SPACE': 32,
'VK_SUBTRACT': 109,
'VK_TAB': 9,
'VK_UP': 38,
'ZOOM': 251,
}
# reverse the CODES dict to make it easy to look up a particular code name
CODE_NAMES = dict((entry[1], entry[0]) for entry in CODES.items())
# modifier keys
MODIFIERS = {
'+': VK_SHIFT,
'^': VK_CONTROL,
'%': VK_MENU,
}
class KeySequenceError(Exception):
"""Exception raised when a key sequence string has a syntax error"""
def __str__(self):
return ' '.join(self.args)
class KeyAction(object):
"""Class that represents a single 'keyboard' action
It represents either a PAUSE action (not reallly keyboard) or a keyboard
action (press or release or both) of a particular key.
"""
def __init__(self, key, down = True, up = True):
self.key = key
if isinstance(self.key, basestring):
self.key = unicode(key)
self.down = down
self.up = up
def _get_key_info(self):
"""Return virtual_key, scan_code, and flags for the action
This is one of the methods that will be overridden by sub classes"""
return 0, ord(self.key), KEYEVENTF_UNICODE
def GetInput(self):
"Build the INPUT structure for the action"
actions = 1
# if both up and down
if self.up and self.down:
actions = 2
inputs = (INPUT * actions)()
vk, scan, flags = self._get_key_info()
for inp in inputs:
inp.type = INPUT_KEYBOARD
inp._.ki.wVk = vk
inp._.ki.wScan = scan
inp._.ki.dwFlags |= flags
# if we are releasing - then let it up
if self.up:
inputs[-1]._.ki.dwFlags |= KEYEVENTF_KEYUP
return inputs
def Run(self):
"Execute the action"
inputs = self.GetInput()
return SendInput(
len(inputs),
ctypes.byref(inputs),
ctypes.sizeof(INPUT))
def _get_down_up_string(self):
"""Return a string that will show whether the string is up or down
return 'down' if the key is a press only
return 'up' if the key is up only
return '' if the key is up & down (as default)
"""
down_up = ""
if not (self.down and self.up):
if self.down:
down_up = "down"
elif self.up:
down_up = "up"
return down_up
def key_description(self):
"Return a description of the key"
vk, scan, flags = self._get_key_info()
desc = ''
if vk:
if vk in CODE_NAMES:
desc = CODE_NAMES[vk]
else:
desc = "VK %d"% vk
else:
desc = "%s"% self.key
return desc
def __str__(self):
parts = []
parts.append(self.key_description())
up_down = self._get_down_up_string()
if up_down:
parts.append(up_down)
return "<%s>"% (" ".join(parts))
__repr__ = __str__
class VirtualKeyAction(KeyAction):
"""Represents a virtual key action e.g. F9 DOWN, etc
Overrides necessary methods of KeyAction"""
def _get_key_info(self):
"Virtual keys have extended flag set"
# copied more or less verbatim from
# http://www.pinvoke.net/default.aspx/user32.sendinput
if (
(self.key >= 33 and self.key <= 46) or
(self.key >= 91 and self.key <= 93) ):
flags = KEYEVENTF_EXTENDEDKEY;
else:
flags = 0
# This works for %{F4} - ALT + F4
#return self.key, 0, 0
# this works for Tic Tac Toe i.e. +{RIGHT} SHIFT + RIGHT
return self.key, MapVirtualKey(self.key, 0), flags
class EscapedKeyAction(KeyAction):
"""Represents an escaped key action e.g. F9 DOWN, etc
Overrides necessary methods of KeyAction"""
def _get_key_info(self):
"""EscapedKeyAction doesn't send it as Unicode and the vk and
scan code are generated differently"""
vkey_scan = LoByte(VkKeyScan(self.key))
return (vkey_scan, MapVirtualKey(vkey_scan, 0), 0)
def key_description(self):
"Return a description of the key"
return "KEsc %s"% self.key
class PauseAction(KeyAction):
"Represents a pause action"
def __init__(self, how_long):
self.how_long = how_long
def Run(self):
"Pause for the lenght of time specified"
time.sleep(self.how_long)
def __str__(self):
return "<PAUSE %1.2f>"% (self.how_long)
__repr__ = __str__
#def GetInput(self):
# print `self.key`
# keys = KeyAction.GetInput(self)
#
# shift_state = HiByte(VkKeyScan(self.key))
#
# shift_down = shift_state & 0x100 # 1st bit
# ctrl_down = shift_state & 0x80 # 2nd bit
# alt_down = shift_state & 0x40 # 3rd bit
#
# print bin(shift_state), shift_down, ctrl_down, alt_down
#
# print keys
# keys = [k for k in keys]
#
# modifiers = []
# if shift_down:
# keys[0:0] = VirtualKeyAction(VK_SHIFT, up = False).GetInput()
# keys.append(VirtualKeyAction(VK_SHIFT, down = False).GetInput())
# if ctrl_down:
# keys[0:0] = VirtualKeyAction(VK_CONTROL, up = False).GetInput()
# keys.append(VirtualKeyAction(VK_CONTROL, down = False).GetInput())
# if alt_down:
# keys[0:0] = VirtualKeyAction(VK_ALT, up = False).GetInput()
# keys.append(VirtualKeyAction(VK_ALT, down = False).GetInput())
#
# print keys
# new_keys = (INPUT * len(keys)) ()
#
# for i, k in enumerate(keys):
# if hasattr(k, 'type'):
# new_keys[i] = k
# else:
# for sub_key in k:
# new_keys[i] = sub_key
#
# return new_keys
#
def handle_code(code):
"Handle a key or sequence of keys in braces"
code_keys = []
# it is a known code (e.g. {DOWN}, {ENTER}, etc)
if code in CODES:
code_keys.append(VirtualKeyAction(CODES[code]))
# it is an escaped modifier e.g. {%}, {^}, {+}
elif len(code) == 1:
code_keys.append(KeyAction(code))
# it is a repetition or a pause {DOWN 5}, {PAUSE 1.3}
elif ' ' in code:
to_repeat, count = code.rsplit(None, 1)
if to_repeat == "PAUSE":
try:
pause_time = float(count)
except ValueError:
raise KeySequenceError('invalid pause time %s'% count)
code_keys.append(PauseAction(pause_time))
else:
try:
count = int(count)
except ValueError:
raise KeySequenceError(
'invalid repetition count %s'% count)
# If the value in to_repeat is a VK e.g. DOWN
# we need to add the code repeated
if to_repeat in CODES:
code_keys.extend(
[VirtualKeyAction(CODES[to_repeat])] * count)
# otherwise parse the keys and we get back a KeyAction
else:
to_repeat = parse_keys(to_repeat)
if isinstance(to_repeat, list):
keys = to_repeat * count
else:
keys = [to_repeat] * count
code_keys.extend(keys)
else:
raise RuntimeError("Unknown code: %s"% code)
return code_keys
def parse_keys(string,
with_spaces = False,
with_tabs = False,
with_newlines = False,
modifiers = None):
"Return the parsed keys"
keys = []
if not modifiers:
modifiers = []
index = 0
while index < len(string):
c = string[index]
index += 1
# check if one of CTRL, SHIFT, ALT has been pressed
if c in MODIFIERS.keys():
modifier = MODIFIERS[c]
# remember that we are currently modified
modifiers.append(modifier)
# hold down the modifier key
keys.append(VirtualKeyAction(modifier, up = False))
if DEBUG:
print("MODS+", modifiers)
continue
# Apply modifiers over a bunch of characters (not just one!)
elif c == "(":
# find the end of the bracketed text
end_pos = string.find(")", index)
if end_pos == -1:
raise KeySequenceError('`)` not found')
keys.extend(
parse_keys(string[index:end_pos], modifiers = modifiers))
index = end_pos + 1
# Escape or named key
elif c == "{":
# We start searching from index + 1 to account for the case {}}
end_pos = string.find("}", index + 1)
if end_pos == -1:
raise KeySequenceError('`}` not found')
code = string[index:end_pos]
index = end_pos + 1
keys.extend(handle_code(code))
# unmatched ")"
elif c == ')':
raise KeySequenceError('`)` should be preceeded by `(`')
# unmatched "}"
elif c == '}':
raise KeySequenceError('`}` should be preceeded by `{`')
# so it is a normal character
else:
# don't output white space unless flags to output have been set
if (c == ' ' and not with_spaces or
c == '\t' and not with_tabs or
c == '\n' and not with_newlines):
continue
# output nuewline
if c in ('~', '\n'):
keys.append(VirtualKeyAction(CODES["ENTER"]))
# safest are the virtual keys - so if our key is a virtual key
# use a VirtualKeyAction
#if ord(c) in CODE_NAMES:
# keys.append(VirtualKeyAction(ord(c)))
elif modifiers:
keys.append(EscapedKeyAction(c))
else:
keys.append(KeyAction(c))
# as we have handled the text - release the modifiers
while modifiers:
if DEBUG:
print("MODS-", modifiers)
keys.append(VirtualKeyAction(modifiers.pop(), down = False))
# just in case there were any modifiers left pressed - release them
while modifiers:
keys.append(VirtualKeyAction(modifiers.pop(), down = False))
return keys
def LoByte(val):
"Return the low byte of the value"
return val & 0xff
def HiByte(val):
"Return the high byte of the value"
return (val & 0xff00) >> 8
def SendKeys(keys,
pause=0.05,
with_spaces=False,
with_tabs=False,
with_newlines=False,
turn_off_numlock=True):
"Parse the keys and type them"
keys = parse_keys(keys, with_spaces, with_tabs, with_newlines)
for k in keys:
k.Run()
time.sleep(pause)
def main():
"Send some test strings"
actions = """
{LWIN}
{PAUSE .25}
r
{PAUSE .25}
Notepad.exe{ENTER}
{PAUSE 1}
Hello{SPACE}World!
{PAUSE 1}
%{F4}
{PAUSE .25}
n
"""
SendKeys(actions, pause = .1)
keys = parse_keys(actions)
for k in keys:
print(k)
k.Run()
time.sleep(.1)
test_strings = [
"\n"
"(aa)some text\n",
"(a)some{ }text\n",
"(b)some{{}text\n",
"(c)some{+}text\n",
"(d)so%me{ab 4}text",
"(e)so%me{LEFT 4}text",
"(f)so%me{ENTER 4}text",
"(g)so%me{^aa 4}text",
"(h)some +(asdf)text",
"(i)some %^+(asdf)text",
"(j)some %^+a text+",
"(k)some %^+a tex+{&}",
"(l)some %^+a tex+(dsf)",
"",
]
for s in test_strings:
print(repr(s))
keys = parse_keys(s, with_newlines = True)
print(keys)
for k in keys:
k.Run()
time.sleep(.1)
print()
if __name__ == "__main__":
main()

@ -1,504 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"""Module containing operations for reading and writing dialogs as XML
"""
__revision__ = "$Revision$"
# how should we read in the XML file
# NOT USING MS Components (requirement on machine)
# maybe using built in XML
# maybe using elementtree
# others?
#import elementtree
try:
# Python 2.5 (thanks to Daisuke Yamashita)
from xml.etree.ElementTree import Element, SubElement, ElementTree
from xml.etree.cElementTree import Element, SubElement, ElementTree
except ImportError:
from elementtree.ElementTree import Element, SubElement, ElementTree
from cElementTree import Element, SubElement, ElementTree
import ctypes
import re
import PIL.Image
import controls
# reported that they are not used - but in fact they are
# through a search of globals()
from win32structures import LOGFONTW, RECT
class XMLParsingError(RuntimeError):
"Wrap parsing Exceptions"
pass
#DONE: Make the dialog reading function not actually know about the
# types of each element (so that we can read the control properties
# without having to know each and every element type)
# probably need to store info on what type things are.
#
# - if it is a ctypes struct then there is a __type__ field
# which says what kind of stuct it is
# - If it is an image then a "_IMG" is appeded to the the element tag
# - if it is a long then _LONG is appended to attribute name
# everything else is considered a string!
#-----------------------------------------------------------------------------
def _SetNodeProps(element, name, value):
"Set the properties of the node based on the type of object"
# if it is a ctypes structure
if isinstance(value, ctypes.Structure):
# create an element for the structure
struct_elem = SubElement(element, name)
#clsModule = value.__class__.__module__
cls_name = value.__class__.__name__
struct_elem.set("__type__", "%s" % cls_name)
# iterate over the fields in the structure
for prop_name in value._fields_:
prop_name = prop_name[0]
item_val = getattr(value, prop_name)
if isinstance(item_val, (int, long)):
prop_name += "_LONG"
item_val = unicode(item_val)
struct_elem.set(prop_name, _EscapeSpecials(item_val))
elif hasattr(value, 'tostring') and hasattr(value, 'size'):
try:
# if the image is too big then don't try to
# write it out - it would probably product a MemoryError
# anyway
if value.size[0] * value.size[1] > (5000*5000):
raise MemoryError
image_data = value.tostring().encode("bz2").encode("base64")
_SetNodeProps(
element,
name + "_IMG",
{
"mode": value.mode,
"size_x":value.size[0],
"size_y":value.size[1],
"data":image_data
})
# a system error is raised from time to time when we try to grab
# the image of a control that has 0 height or width
except (SystemError, MemoryError):
pass
elif isinstance(value, (list, tuple)):
# add the element to hold the values
# we do this to be able to support empty lists
listelem = SubElement(element, name + "_LIST")
for i, attrval in enumerate(value):
_SetNodeProps(listelem, "%s_%05d"%(name, i), attrval)
elif isinstance(value, dict):
dict_elem = SubElement(element, name)
for item_name, val in value.items():
_SetNodeProps(dict_elem, item_name, val)
else:
if isinstance(value, bool):
value = long(value)
if isinstance(value, (int, long)):
name += "_LONG"
element.set(name, _EscapeSpecials(value))
#-----------------------------------------------------------------------------
def WriteDialogToFile(filename, props):
"""Write the props to the file
props can be either a dialog of a dictionary
"""
# if we are passed in a wrapped handle then
# get the properties
try:
props[0].keys()
except (TypeError, AttributeError):
props = controls.GetDialogPropsFromHandle(props)
# build a tree structure
root = Element("DIALOG")
root.set("_version_", "2.0")
for ctrl in props:
ctrlelem = SubElement(root, "CONTROL")
for name, value in sorted(ctrl.items()):
_SetNodeProps(ctrlelem, name, value)
# wrap it in an ElementTree instance, and save as XML
tree = ElementTree(root)
tree.write(filename, encoding="utf-8")
#-----------------------------------------------------------------------------
def _EscapeSpecials(string):
"Ensure that some characters are escaped before writing to XML"
# ensure it is unicode
string = unicode(string)
# escape backslashs
string = string.replace('\\', r'\\')
# escape non printable characters (chars below 30)
for i in range(0, 32):
string = string.replace(unichr(i), "\\%02d"%i)
return string
#-----------------------------------------------------------------------------
def _UnEscapeSpecials(string):
"Replace escaped characters with real character"
# Unescape all the escape characters
for i in range(0, 32):
string = string.replace("\\%02d"%i, unichr(i))
# convert doubled backslashes to a single backslash
string = string.replace(r'\\', '\\')
return unicode(string)
#-----------------------------------------------------------------------------
def _XMLToStruct(element, struct_type = None):
"""Convert an ElementTree to a ctypes Struct
If struct_type is not specified then element['__type__']
will be used for the ctypes struct type"""
# handle if we are passed in an element or a dictionary
try:
attribs = element.attrib
except AttributeError:
attribs = element
# if the type has not been passed in
if not struct_type:
# get the type and create an instance of the type
struct = globals()[attribs["__type__"]]()
else:
# create an instance of the type
struct = globals()[struct_type]()
# get the attribute and set them upper case
struct_attribs = dict([(at.upper(), at) for at in dir(struct)])
# for each of the attributes in the element
for prop_name in attribs:
# get the value
val = attribs[prop_name]
# if the value ends with "_long"
if prop_name.endswith("_LONG"):
# get an long attribute out of the value
val = long(val)
prop_name = prop_name[:-5]
# if the value is a string
elif isinstance(val, basestring):
# make sure it if Unicode
val = unicode(val)
# now we can have all upper case attribute name
# but structure name will not be upper case
if prop_name.upper() in struct_attribs:
prop_name = struct_attribs[prop_name.upper()]
# set the appropriate attribute of the Struct
setattr(struct, prop_name, val)
# reutrn the struct
return struct
#====================================================================
def _OLD_XMLToTitles(element):
"For OLD XML files convert the titles as a list"
# get all the attribute names
title_names = element.keys()
# sort them to make sure we get them in the right order
title_names.sort()
# build up the array
titles = []
for name in title_names:
val = element[name]
val = val.replace('\\n', '\n')
val = val.replace('\\x12', '\x12')
val = val.replace('\\\\', '\\')
titles.append(unicode(val))
return titles
#====================================================================
# TODO: this function should be broken up into smaller functions
# for each type of processing e.g.
# ElementTo
def _ExtractProperties(properties, prop_name, prop_value):
"""Hmmm - confusing - can't remember exactly how
all these similar functions call each other"""
# get the base property name and number if it in the form
# "PROPNAME_00001" = ('PROPNAME', 1)
prop_name, reqd_index = _SplitNumber(prop_name)
# if there is no required index, and the property
# was not already set - then just set it
# if this is an indexed member of a list
if reqd_index == None:
# Have we hit a property with this name already
if prop_name in properties:
# try to append current value to the property
try:
properties[prop_name].append(prop_value)
# if that fails then we need to make sure that
# the curruen property is a list and then
# append it
except AttributeError:
new_val = [properties[prop_name], prop_value]
properties[prop_name] = new_val
# No index, no previous property with that name
# - just set the property
else:
properties[prop_name] = prop_value
# OK - so it HAS an index
else:
# make sure that the property is a list
properties.setdefault(prop_name, [])
# make sure that the list has enough elements
while 1:
if len(properties[prop_name]) <= reqd_index:
properties[prop_name].append('')
else:
break
# put our value in at the right index
properties[prop_name][reqd_index] = prop_value
#====================================================================
def _GetAttributes(element):
"Get the attributes from an element"
properties = {}
# get all the attributes
for attrib_name, val in element.attrib.items():
# if it is 'Long' element convert it to an long
if attrib_name.endswith("_LONG"):
val = long(val)
attrib_name = attrib_name[:-5]
else:
# otherwise it is a string - make sure we get it as a unicode string
val = _UnEscapeSpecials(val)
_ExtractProperties(properties, attrib_name, val)
return properties
#====================================================================
number = re.compile(r"^(.*)_(\d{5})$")
def _SplitNumber(prop_name):
"""Return (string, number) for a prop_name in the format string_number
The number part has to be 5 digits long
None is returned if there is no _number part
e.g.
>>> _SplitNumber("NoNumber")
('NoNumber', None)
>>> _SplitNumber("Anumber_00003")
('Anumber', 3)
>>> _SplitNumber("notEnoughDigits_0003")
('notEnoughDigits_0003', None)
"""
found = number.search(prop_name)
if not found:
return prop_name, None
return found.group(1), int(found.group(2))
#====================================================================
def _ReadXMLStructure(control_element):
"""Convert an element into nested Python objects
The values will be returned in a dictionary as following:
- the attributes will be items of the dictionary
for each subelement
+ if it has a __type__ attribute then it is converted to a
ctypes structure
+ if the element tag ends with _IMG then it is converted to
a PIL image
- If there are elements with the same name or attributes with
ordering e.g. texts_00001, texts_00002 they will be put into a
list (in the correct order)
"""
# get the attributes for the current element
properties = _GetAttributes(control_element)
for elem in control_element:
# if it is a ctypes structure
if "__type__" in elem.attrib:
# create a new instance of the correct type
# grab the data
propval = _XMLToStruct(elem)
elif elem.tag.endswith("_IMG"):
elem.tag = elem.tag[:-4]
# get image Attribs
img = _GetAttributes(elem)
data = img['data'].decode('base64').decode('bz2')
propval = PIL.Image.fromstring(
img['mode'],
(img['size_x'], img['size_y']),
data)
elif elem.tag.endswith("_LIST"):
# All this is just to handle the edge case of
# an empty list
elem.tag = elem.tag[:-5]
# read the structure
propval = _ReadXMLStructure(elem)
# if it was empty then convert the returned dict
# to a list
if propval == {}:
propval = list()
# otherwise extract the list out of the returned dict
else:
propval = propval[elem.tag]
else:
propval = _ReadXMLStructure(elem)
_ExtractProperties(properties, elem.tag, propval)
return properties
#====================================================================
def ReadPropertiesFromFile(filename):
"""Return an list of controls from XML file filename"""
# parse the file
parsed = ElementTree().parse(filename)
# Return the list that has been stored under 'CONTROL'
props = _ReadXMLStructure(parsed)['CONTROL']
if not isinstance(props, list):
props = [props]
# it is an old XML so let's fix it up a little
if not parsed.attrib.has_key("_version_"):
# find each of the control elements
for ctrl_prop in props:
ctrl_prop['Fonts'] = [_XMLToStruct(ctrl_prop['FONT'], "LOGFONTW"), ]
ctrl_prop['Rectangle'] = \
_XMLToStruct(ctrl_prop["RECTANGLE"], "RECT")
ctrl_prop['ClientRects'] = [
_XMLToStruct(ctrl_prop["CLIENTRECT"], "RECT"),]
ctrl_prop['Texts'] = _OLD_XMLToTitles(ctrl_prop["TITLES"])
ctrl_prop['Class'] = ctrl_prop['CLASS']
ctrl_prop['ContextHelpID'] = ctrl_prop['HELPID']
ctrl_prop['ControlID'] = ctrl_prop['CTRLID']
ctrl_prop['ExStyle'] = ctrl_prop['EXSTYLE']
ctrl_prop['FriendlyClassName'] = ctrl_prop['FRIENDLYCLASS']
ctrl_prop['IsUnicode'] = ctrl_prop['ISUNICODE']
ctrl_prop['IsVisible'] = ctrl_prop['ISVISIBLE']
ctrl_prop['Style'] = ctrl_prop['STYLE']
ctrl_prop['UserData'] = ctrl_prop['USERDATA']
for prop_name in [
'CLASS',
'CLIENTRECT',
'CTRLID',
'EXSTYLE',
'FONT',
'FRIENDLYCLASS',
'HELPID',
'ISUNICODE',
'ISVISIBLE',
'RECTANGLE',
'STYLE',
'TITLES',
'USERDATA',
]:
del(ctrl_prop[prop_name])
return props

@ -1,35 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"""
Python package for automating GUI manipulation on Windows
"""
__revision__ = "$Revision$"
__version__ = "0.4.2"
import findwindows
WindowAmbiguousError = findwindows.WindowAmbiguousError
WindowNotFoundError = findwindows.WindowNotFoundError
import findbestmatch
MatchError = findbestmatch.MatchError
from application import Application, WindowSpecification

File diff suppressed because it is too large Load Diff

@ -1,138 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"Some clipboard wrapping functions - more to be added later"
__revision__ = "$Revision$"
import ctypes
import win32functions
import win32defines
#from ctypes.wintypes import *
#====================================================================
def _get_standard_formats():
"Get the known formats by looking in win32defines"
formats = {}
for define_name in win32defines.__dict__.keys():
if define_name.startswith("CF_"):
formats[getattr(win32defines, define_name)] = define_name
return formats
# get all the formats names keyed on the value
_standard_formats = _get_standard_formats()
#====================================================================
def GetClipboardFormats():
"Get a list of the formats currently in the clipboard"
if not win32functions.OpenClipboard(0):
raise WinError()
available_formats = []
format = 0
while True:
# retrieve the next format
format = win32functions.EnumClipboardFormats(format)
# stop enumerating because all formats have been
# retrieved
if not format:
break
available_formats.append(format)
win32functions.CloseClipboard()
return available_formats
#====================================================================
def GetFormatName(format):
"Get the string name for a format value"
# standard formats should not be passed to GetClipboardFormatName
if format in _standard_formats:
return _standard_formats[format]
if not win32functions.OpenClipboard(0):
raise WinError()
max_size = 500
buffer_ = ctypes.create_unicode_buffer(max_size+1)
ret = win32functions.GetClipboardFormatName(
format, ctypes.byref(buffer_), max_size)
if not ret:
raise RuntimeError("test")
win32functions.CloseClipboard()
return buffer_.value
#====================================================================
def GetData(format = win32defines.CF_UNICODETEXT):
"Return the data from the clipboard in the requested format"
if format not in GetClipboardFormats():
raise RuntimeError("That format is not available")
if not win32functions.OpenClipboard(0):
raise WinError()
handle = win32functions.GetClipboardData(format)
if not handle:
error = ctypes.WinError()
win32functions.CloseClipboard()
raise error
buffer_ = ctypes.c_wchar_p(win32functions.GlobalLock(handle))
data = buffer_.value
win32functions.GlobalUnlock(handle)
win32functions.CloseClipboard()
return data
#====================================================================
def EmptyClipboard():
if not win32functions.OpenClipboard(0):
raise RuntimeError("Couldn't open clipboard")
win32functions.EmptyClipboard()
win32functions.CloseClipboard()
#====================================================================
# Todo: Implement setting clipboard data
#def SetData(data, formats = [win32defines.CF_UNICODETEXT, ]):
# pass
#====================================================================
if __name__ == "__main__":
_unittests()

@ -1,258 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"""Wrap"""
__revision__ = "$Rev: 439 $"
try:
import pywinauto
except ImportError:
import sys
sys.path.append("..")
from pywinauto.win32structures import RECT, LOGFONTW
#====================================================================
class func_wrapper(object):
"Little class to allow attribute access to return a callable object"
def __init__(self, value):
self.value = value
def __call__(self, *args, **kwargs):
"Return the saved value"
return self.value
#====================================================================
class ControlProps(dict):
"Wrap controls read from a file to resemble hwnd controls"
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
self.ref = None
#self.MenuItems = []
def __getattr__(self, attr):
# if the key is not in the dictionary but the plural is
if attr not in self and attr + "s" in self:
# return the first element of the possible list item
return func_wrapper(self[attr+'s'][0])
return func_wrapper(self[attr])
#def FriendlyClassName(self):
# print "sdafafasdfafasdfasdf",
# try:
# print "---", self['FriendlyClassName']
# except Exception, e:
# print "fffffffffffffffffffff"
# print `e`
# return self['FriendlyClassName']
def WindowText(self):
return self['Texts'][0]
def HasStyle(self, style):
return self['Style'] & style == style
def HasExStyle(self, exstyle):
return self['ExStyle'] & exstyle == exstyle
#====================================================================
def GetMenuBlocks(ctrls):
allMenuBlocks = []
for ctrl in ctrls:
if ctrl.has_key('MenuItems'):
# we need to get all the separate menu blocks!
menuBlocks = MenuBlockAsControls(ctrl.MenuItems())
allMenuBlocks.extend(menuBlocks)
return allMenuBlocks
#====================================================================
def MenuBlockAsControls(menuItems, parentage = []):
blocks = []
curBlock = []
for item in menuItems:
# do a bit of conversion first :-)
itemAsCtrl = MenuItemAsControl(item)
# update the FriendlyClassName to contain the 'path' to
# this particular item
# TODO: CHECK - as itemPath is currently unused!
if parentage:
itemPath = "%s->%s" % ("->".join(parentage), item['Text'])
else:
itemPath = item['Text']
#append the item to the current menu block
curBlock.append(itemAsCtrl)
# If the item has a sub menu
if item.has_key('MenuItems'):
# add the current item the path
parentage.append(item['Text'])
# Get the block for the SubMenu, and add it to the list of
# blocks we have found
blocks.extend(
MenuBlockAsControls(
item['MenuItems']['MenuItems'], parentage))
# and seeing as we are dong with that sub menu remove the current
# item from the path
del(parentage[-1])
# add the current block to the list of blocks
blocks.append(curBlock)
return blocks
#====================================================================
def MenuItemAsControl(menuItem):
"Make a menu item look like a control for tests"
itemAsCtrl = ControlProps()
itemAsCtrl["Texts"] = [menuItem['Text'], ]
itemAsCtrl["ControlID"] = menuItem['ID']
itemAsCtrl["Type"] = menuItem['Type']
itemAsCtrl["State"] = menuItem['State']
itemAsCtrl["Class"] = "MenuItem"
itemAsCtrl["FriendlyClassName"] = "MenuItem"
# as most of these don't matter - just set them up with default stuff
itemAsCtrl["Rectangle"] = RECT(0, 0, 999, 999)
itemAsCtrl["Fonts"] = [LOGFONTW(), ]
itemAsCtrl["ClientRects"] = [RECT(0, 0, 999, 999), ]
itemAsCtrl["ContextHelpID"] = 0
itemAsCtrl["UserData"] = 0
itemAsCtrl["Style"] = 0
itemAsCtrl["ExStyle"] = 0
itemAsCtrl["IsVisible"] = 1
return itemAsCtrl
#====================================================================
def SetReferenceControls(controls, refControls):
"""Set the reference controls for the controls passed in
This does some minor checking as following:
* test that there are the same number of reference controls as
controls - fails with an exception if there are not
* test if all the ID's are the same or not
"""
# numbers of controls must be the same (though in future I could imagine
# relaxing this constraint)
if len(controls) != len(refControls):
raise RuntimeError(
"Numbers of controls on ref. dialog does not match Loc. dialog")
# set the controls
for i, ctrl in enumerate(controls):
ctrl.ref = refControls[i]
toRet = 1
allIDsSameFlag = 2
allClassesSameFlag = 4
# find if all the control id's match
if [ctrl.ControlID() for ctrl in controls] == \
[ctrl.ControlID() for ctrl in refControls]:
toRet += allIDsSameFlag
# check if the control classes match
if [ctrl.Class() for ctrl in controls] == \
[ctrl.Class() for ctrl in refControls]:
toRet += allClassesSameFlag
return toRet
##====================================================================
#class ControlProps(dict):
# #----------------------------------------------------------------
# def __init__(self, props = {}):
# # default to having menuItems for all things
# self.MenuItems = []
#
# self.update(props)
# #for x in props:
# #self[x] = props[x]
#
# if hasattr(props, "handle"):
# self.__dict__['handle'] = props.handle
# else:
# self.__dict__['handle'] = None
#
# self.__dict__['ref'] = None
#
# #----------------------------------------------------------------
# # handles attribute access for dictionary items and
# # for plurals (e.g. if self.Fonts = [4, 2] then self.Font = 4)
# def __getattr__(self, key):
#
# # if the key is not in the dictionary but the plural is
# if key not in self and key + "s" in self:
#
# # try to get the first element of the possible list item
# try:
# return self[key + "s"][0]
# except TypeError, e:
# pass
#
# if key in self:
# return self[key]
#
# return self.__dict__[key]
#
# #----------------------------------------------------------------
# def __setattr__(self, key, value):
# if key in self.__dict__:
# self.__dict__[key] = value
# else:
# self[key] = value
#
# #----------------------------------------------------------------
# def HasStyle(self, flag):
# return self.Style & flag == flag
#
# #----------------------------------------------------------------
# def HasExStyle(self, flag):
# return self.ExStyle & flag == flag
#
#

File diff suppressed because it is too large Load Diff

@ -1,67 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"Controls package"
__revision__ = "$Revision$"
from HwndWrapper import GetDialogPropsFromHandle
from HwndWrapper import InvalidWindowHandle
# make an alias for the HwndWrapper object as WrapHandle
from HwndWrapper import HwndWrapper as WrapHandle
# import the control clases - this will register the classes they
# contain
import common_controls
import win32_controls
#
##====================================================================
#def _unittests():
# "Run some tests on the controls"
# from pywinauto import win32functions
#
# "do some basic testing"
# from pywinauto.findwindows import find_windows
# import sys
#
# if len(sys.argv) < 2:
# handle = win32functions.GetDesktopWindow()
# else:
# try:
# handle = int(eval(sys.argv[1]))
#
# except ValueError:
#
# handle = find_windows(
# title_re = "^" + sys.argv[1], class_name = "#32770", )
# #visible_only = False)
#
# if not handle:
# print "dialog not found"
# sys.exit()
#
#
# props = GetDialogPropsFromHandle(handle)
# print len(props)
# #pprint(GetDialogPropsFromHandle(handle))
#
#if __name__ == "__main__":
# _unittests()

File diff suppressed because it is too large Load Diff

@ -1,556 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"""Wrapper around Menu's and Menu items
These wrappers allow you to work easily with menu items.
You can select or click on items and check if they are
checked or unchecked.
"""
__revision__ = "$Revision: 330 $"
import ctypes
import time
from pywinauto import win32structures
from pywinauto import win32functions
from pywinauto import win32defines
from pywinauto import findbestmatch
from pywinauto.timings import Timings
class MenuItemNotEnabled(RuntimeError):
"Raised when a menuitem is not enabled"
pass
class MenuItem(object):
"""Wrap a menu item"""
def __init__(self, ctrl, menu, index, on_main_menu = False):
"""Initalize the menu item
* **ctrl** The dialog or control that owns this menu
* **menu** The menu that this item is on
* **index** The Index of this menuitem on the menu
* **on_main_menu** True if the item is on the main menu
"""
self.index = index
self.menu = menu
self.ctrl = ctrl
self.on_main_menu = on_main_menu
def _read_item(self):
"""Read the menu item info
See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/resources/menus/menureference/menufunctions/getmenuiteminfo.asp
for more information."""
menu_info = win32structures.MENUITEMINFOW()
menu_info.cbSize = ctypes.sizeof (menu_info)
menu_info.fMask = \
win32defines.MIIM_CHECKMARKS | \
win32defines.MIIM_ID | \
win32defines.MIIM_STATE | \
win32defines.MIIM_SUBMENU | \
win32defines.MIIM_TYPE #| \
#MIIM_FTYPE #| \
#MIIM_STRING
#MIIM_DATA | \
ret = win32functions.GetMenuItemInfo (
self.menu,
self.index,
True,
ctypes.byref(menu_info))
if not ret:
raise ctypes.WinError()
return menu_info
def FriendlyClassName(self):
return "MenuItem"
def Rectangle(self):
"Get the rectangle of the menu item"
rect = win32structures.RECT()
if self.on_main_menu:
ctrl = self.ctrl
else:
ctrl = 0
win32functions.GetMenuItemRect(
ctrl,
self.menu,
self.index,
ctypes.byref(rect))
return rect
def Index(self):
"Return the index of this menu item"
return self.index
def State(self):
"Return the state of this menu item"
return self._read_item().fState
def ID(self):
"Return the ID of this menu item"
return self._read_item().wID
def Type(self):
"""Return the Type of this menu item
Main types are MF_STRING, MF_BITMAP, MF_SEPARATOR.
See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/resources/menus/menureference/menustructures/menuiteminfo.asp
for further information."""
return self._read_item().fType
def Text(self):
"Return the state of this menu item"
info = self._read_item()
# if there is text
if info.cch:
# allocate a buffer
buffer_size = info.cch+1
text = ctypes.create_unicode_buffer(buffer_size)
# update the structure and get the text info
info.dwTypeData = ctypes.addressof(text)
info.cch = buffer_size
win32functions.GetMenuItemInfo (
self.menu,
self.index,
True,
ctypes.byref(info))
text = text.value
else:
text = ''
return text
def SubMenu(self):
"Return the SubMenu or None if no submenu"
submenu_handle = self._read_item().hSubMenu
if submenu_handle:
self.ctrl.SendMessageTimeout(
win32defines.WM_INITMENUPOPUP,
submenu_handle,
self.index)
return Menu(self.ctrl, submenu_handle, False, self)
return None
def IsEnabled(self):
"Return True if the item is enabled."
return not (
self.State() & win32defines.MF_DISABLED or
self.State() & win32defines.MF_GRAYED)
def IsChecked(self):
"Return True if the item is checked."
return bool(self.State() & win32defines.MF_CHECKED)
def Click(self):
"""Click on the menu item
If the menu is open this it will click with the mouse on the item.
If the menu is not open each of it's parent's will be opened
until the item is visible.
"""
self.ctrl.VerifyEnabled()
rect = self.Rectangle()
if not self.IsEnabled():
raise MenuItemNotEnabled(
"MenuItem '%s' is disabled"% self.Text())
# if the item is not visible - work up along it's parents
# until we find an item we CAN click on
if rect == (0, 0, 0, 0):
if self.menu.owner_item:
self.menu.owner_item.Click()
rect = self.Rectangle()
x_pt = (rect.left + rect.right) /2
y_pt = (rect.top + rect.bottom) /2
from HwndWrapper import _perform_click_input #, delay_after_menuselect
_perform_click_input(
None,
coords = (x_pt, y_pt),
absolute = True)
win32functions.WaitGuiThreadIdle(self.ctrl)
#import time
#time.sleep(delay_after_menuselect)
def Select(self):
"""Select the menu item
This will send a message to the parent window that the
item was picked
"""
if not self.IsEnabled():
raise MenuItemNotEnabled(
"MenuItem '%s' is disabled"% self.Text())
#from HwndWrapper import delay_after_menuselect
#if self.State() & win32defines.MF_BYPOSITION:
# print self.Text(), "BYPOSITION"
# self.ctrl.NotifyMenuSelect(self.Index(), True)
#else:
# seems like SetFoucs might be messing with getting the
# id for Popup menu items - so I calling it before SetFocus
command_id = self.ID()
# notify the control that a menu item was selected
self.ctrl.SetFocus()
self.ctrl.SendMessageTimeout(
win32defines.WM_COMMAND,
win32functions.MakeLong(0, command_id))
#self.ctrl.NotifyMenuSelect(self.ID())
win32functions.WaitGuiThreadIdle(self.ctrl)
time.sleep(Timings.after_menu_wait)
def GetProperties(self):
"""Return the properties for the item as a dict
If this item opens a sub menu then call Menu.GetProperties()
to return the list of items in the sub menu. This is avialable
under the 'MenuItems' key
"""
props = {}
props['Index'] = self.Index()
props['State'] = self.State()
props['Type'] = self.Type()
props['ID'] = self.ID()
props['Text'] = self.Text()
submenu = self.SubMenu()
if submenu:
props['MenuItems'] = submenu.GetProperties()
return props
def __repr__(self):
"Return a representation of the object as a string"
return "<MenuItem %s>" % `self.Text()`
# def Check(self):
# item = self._read_item()
# item.fMask = win32defines.MIIM_STATE
# item.fState &= win32defines.MF_CHECKED
#
## ret = win32functions.SetMenuItemInfo(
## self.menuhandle,
## self.ID(),
## 0, # by position
## ctypes.byref(item))
##
## if not ret:
## raise ctypes.WinError()
#
# print win32functions.CheckMenuItem(
# self.menuhandle,
# self.index,
# win32defines.MF_BYPOSITION | win32defines.MF_CHECKED)
#
# win32functions.DrawMenuBar(self.ctrl)
#
# def UnCheck(self):
# item = self._read_item()
# item.fMask = win32defines.MIIM_STATE
# item.fState &= win32defines.MF_UNCHECKED
#
# ret = win32functions.SetMenuItemInfo(
# self.menuhandle,
# self.ID(),
# 0, # by position
# ctypes.byref(item))
#
# if not ret:
# raise ctypes.WinError()
#
# win32functions.DrawMenuBar(self.ctrl)
#
#
class Menu(object):
"""A simple wrapper around a menu handle
A menu supports methods for querying the menu
and getting it's menu items."""
def __init__(
self,
owner_ctrl,
menuhandle,
is_main_menu = True,
owner_item = None):
"""Initialize the class.
* **owner_ctrl** is the Control that owns this menu
* **menuhandle** is the menu handle of the menu
* **is_main_menu** we have to track whether it is the main menu
or a popup menu
* **owner_item** The item that contains this menu - this will be
None for the main menu, it will be a MenuItem instance for a
submenu.
"""
self.ctrl = owner_ctrl
self.handle = menuhandle
self.is_main_menu = is_main_menu
self.owner_item = owner_item
self._as_parameter_ = self.handle
if self.is_main_menu:
self.ctrl.SendMessageTimeout(win32defines.WM_INITMENU, self.handle)
def ItemCount(self):
"Return the count of items in this menu"
return win32functions.GetMenuItemCount(self.handle)
def Item(self, index):
"""Return a specific menu item
* **index** is the 0 based index of the menu item you want
"""
return MenuItem(self.ctrl, self, index, self.is_main_menu)
def Items(self):
"Return a list of all the items in this menu"
items = []
for i in range(0, self.ItemCount()):
items.append(self.Item(i))
return items
def GetProperties(self):
"""Return the properties for the menu as a list of dictionaries
This method is actually recursive. It calls GetProperties() for each
of the items. If the item has a sub menu it will call this
GetProperties to get the sub menu items.
"""
item_props = []
for item in self.Items():
item_props.append(item.GetProperties())
return {'MenuItems': item_props}
def GetMenuPath(self, path, path_items = None, appdata = None):
"""Walk the items in this menu to find the item specified by path
The path is specified by a list of items separated by '->' each Item
can be either a string (can include spaces) e.g. "Save As" or the zero
based index of the item to return prefaced by # e.g. #1.
These can be mixed as necessary. For Example:
"#0 -> Save As",
"Tools -> #0 -> Configure"
Text matching is done using a 'best match' fuzzy algorithm, so you don't
have to add all puntuation, elipses, etc.
"""
if path_items is None:
path_items = []
# get the first part (and remainder)
parts = path.split("->", 1)
current_part = parts[0]
if current_part.startswith("#"):
index = int(current_part[1:])
best_item = self.Item(index)
else:
# get the text names from the menu items
if appdata is None:
item_texts = [item.Text() for item in self.Items()]
else:
item_texts = [item['Text'] for item in appdata]
# find the item that best matches the current part
best_item = findbestmatch.find_best_match(
current_part,
item_texts,
self.Items())
path_items.append(best_item)
# if there are more parts - then get the next level
if parts[1:]:
if appdata:
appdata = appdata[best_item.Index()]['MenuItems']
if best_item.SubMenu() is not None:
best_item.SubMenu().GetMenuPath(
"->".join(parts[1:]),
path_items,
appdata)
return path_items
def __repr__(self):
"Return a simple representation of the menu"
return "<Menu %d>" % self.handle
# def GetProperties(self):
#
# for i in range(0, self.ItemCount()):
# menu_info = self.Item(self, i)[0]
#
# item_prop['Index'] = i
# item_prop['State'] = menu_info.fState
# item_prop['Type'] = menu_info.fType
# item_prop['ID'] = menu_info.wID
#
# else:
# item_prop['Text'] = ""
#
# if self.IsSubMenu(i):
# item_prop['MenuItems'] = self.SubMenu(i).GetProperties()
#
# return item_prop
##====================================================================
#def _GetMenuItems(menu_handle, ctrl):
# "Get the menu items as a list of dictionaries"
# # If it doesn't have a real menu just return
# if not win32functions.IsMenu(menu_handle):
# return []
#
#
# menu = Menu(ctrl, menu_handle)
#
# props = []
# for item in menu.Items():
# item_props = {}
#
# item_prop['Index'] = item.Index()
# item_prop['State'] = item.State()
# item_prop['Type'] = item.Type()
# item_prop['ID'] = item.ID()
# item_prop['Text'] = item.Text()
#
# props.append(item_props)
#
#
#
#
#
#
#
# items = []
#
#
# # for each menu item
# for i in range(0, item_count):
#
# item_prop = {}
#
# # get the information on the menu Item
# menu_info = win32structures.MENUITEMINFOW()
# menu_info.cbSize = ctypes.sizeof (menu_info)
# menu_info.fMask = \
# win32defines.MIIM_CHECKMARKS | \
# win32defines.MIIM_ID | \
# win32defines.MIIM_STATE | \
# win32defines.MIIM_SUBMENU | \
# win32defines.MIIM_TYPE #| \
# #MIIM_FTYPE #| \
# #MIIM_STRING
# #MIIM_DATA | \
#
#
# ret = win32functions.GetMenuItemInfo (
# menu_handle, i, True, ctypes.byref(menu_info))
# if not ret:
# raise ctypes.WinError()
#
# # if there is text
# if menu_info.cch:
# # allocate a buffer
# buffer_size = menu_info.cch+1
# text = ctypes.create_unicode_buffer(buffer_size)
#
# # update the structure and get the text info
# menu_info.dwTypeData = ctypes.addressof(text)
# menu_info.cch = buffer_size
# win32functions.GetMenuItemInfo (
# menu_handle, i, True, ctypes.byref(menu_info))
# item_prop['Text'] = text.value
# else:
# item_prop['Text'] = ""
#
# # if it's a sub menu then get it's items
# if menu_info.hSubMenu:
# # make sure that the app updates the menu if it need to
# ctrl.SendMessage(
# win32defines.WM_INITMENUPOPUP, menu_info.hSubMenu, i)
#
# #ctrl.SendMessage(
# # win32defines.WM_INITMENU, menu_info.hSubMenu, )
#
# # get the sub menu items
# sub_menu_items = _GetMenuItems(menu_info.hSubMenu, ctrl)
#
# # append them
# item_prop['MenuItems'] = sub_menu_items
#
# items.append(item_prop)
#
# return items
#

@ -1,847 +0,0 @@
# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
"Wraps various standard windows controls"
__revision__ = "$Revision$"
import time
import ctypes
import HwndWrapper
from pywinauto import win32functions
from pywinauto import win32defines
from pywinauto import win32structures
#from pywinauto import findbestmatch
from pywinauto import controlproperties
from pywinauto import tests
from pywinauto.timings import Timings
#====================================================================
class ButtonWrapper(HwndWrapper.HwndWrapper):
"Wrap a windows Button control"
friendlyclassname = "Button"
windowclasses = [
"Button",
r"WindowsForms\d*\.BUTTON\..*",
"TButton",
"ThunderCommandButton",
"ThunderOptionButton",
"ThunderCheckBox"]
can_be_label = True
#-----------------------------------------------------------
def __init__(self, hwnd):
"Initialize the control"
super(ButtonWrapper, self).__init__(hwnd)
#self._set_if_needs_image()
def _set_if_needs_image(self, value):
"Does nothing see _get_if_needs_image"
pass
#-----------------------------------------------------------
def _get_if_needs_image(self):
"Set the _NeedsImageProp attribute if it is an image button"
# optimization call Style once and work with that rather than
# calling HasStyle a number of times
style = self.Style()
if self.IsVisible() and (\
style & win32defines.BS_BITMAP == style or \
style & win32defines.BS_ICON == style or \
style & win32defines.BS_OWNERDRAW == style):
#self._NeedsImageProp = True
return True
else:
return False
_NeedsImageProp = property(_get_if_needs_image, _set_if_needs_image)
#-----------------------------------------------------------
def FriendlyClassName(self):
"""Return the friendly class name of the button
Windows controls with the class "Button" can look like different
controls based on their style. They can look like the following
controls:
- Buttons, this method returns "Button"
- CheckBoxes, this method returns "CheckBox"
- RadioButtons, this method returns "RadioButton"
- GroupBoxes, this method returns "GroupBox"
"""
# get the least significant BIT
style_lsb = self.Style() & 0xF
f_class_name = 'Button'
vb_buttons = {
"ThunderOptionButton": "RadioButton",
"ThunderCheckBox": "CheckBox",
"ThunderCommandButton": "Button"
}
if self.Class() in vb_buttons:
f_class_name = vb_buttons[self.Class()]
if style_lsb == win32defines.BS_3STATE or \
style_lsb == win32defines.BS_AUTO3STATE or \
style_lsb == win32defines.BS_AUTOCHECKBOX or \
style_lsb == win32defines.BS_CHECKBOX:
f_class_name = "CheckBox"
elif style_lsb == win32defines.BS_RADIOBUTTON or \
style_lsb == win32defines.BS_AUTORADIOBUTTON:
f_class_name = "RadioButton"
elif style_lsb == win32defines.BS_GROUPBOX:
f_class_name = "GroupBox"
if self.Style() & win32defines.BS_PUSHLIKE:
f_class_name = "Button"
return f_class_name
#-----------------------------------------------------------
def GetCheckState(self):
"""Return the check state of the checkbox
The check state is represented by an integer
0 - unchecked
1 - checked
2 - indeterminate
The following constants are defined in the win32defines module
BST_UNCHECKED = 0
BST_CHECKED = 1
BST_INDETERMINATE = 2
"""
return self.SendMessage(win32defines.BM_GETCHECK)
#-----------------------------------------------------------
def Check(self):
"Check a checkbox"
self.SendMessageTimeout(win32defines.BM_SETCHECK,
win32defines.BST_CHECKED)
win32functions.WaitGuiThreadIdle(self)
time.sleep(Timings.after_buttoncheck_wait)
# return this control so that actions can be chained.
return self
#-----------------------------------------------------------
def UnCheck(self):
"Uncheck a checkbox"
self.SendMessageTimeout(win32defines.BM_SETCHECK,
win32defines.BST_UNCHECKED)
win32functions.WaitGuiThreadIdle(self)
time.sleep(Timings.after_buttoncheck_wait)
# return this control so that actions can be chained.
return self
#-----------------------------------------------------------
def SetCheckIndeterminate(self):
"Set the checkbox to indeterminate"
self.SendMessageTimeout(win32defines.BM_SETCHECK,
win32defines.BST_INDETERMINATE)
win32functions.WaitGuiThreadIdle(self)
time.sleep(Timings.after_buttoncheck_wait)
# return this control so that actions can be chained.
return self
#-----------------------------------------------------------
def IsDialog(self):
"Buttons are never dialogs so return False"
return False
#-----------------------------------------------------------
def Click(self, *args, **kwargs):
"Click the Button control"
# import win32functions
# win32functions.WaitGuiThreadIdle(self)
# self.NotifyParent(win32defines.BN_CLICKED)
HwndWrapper.HwndWrapper.Click(self, *args, **kwargs)
# win32functions.WaitGuiThreadIdle(self)
time.sleep(Timings.after_button_click_wait)
#def IsSelected (self):
# (for radio buttons)
#====================================================================
def _get_multiple_text_items(wrapper, count_msg, item_len_msg, item_get_msg):
"Helper function to get multiple text items from a control"
texts = []
# find out how many text items are in the combobox
num_items = wrapper.SendMessage(count_msg)
# get the text for each item in the combobox
for i in range(0, num_items):
text_len = wrapper.SendMessage (item_len_msg, i, 0)
text = ctypes.create_unicode_buffer(text_len + 1)
wrapper.SendMessage(item_get_msg, i, ctypes.byref(text))
texts.append(text.value)
return texts
#====================================================================
class ComboBoxWrapper(HwndWrapper.HwndWrapper):
"Wrap a windows ComboBox control"
friendlyclassname = "ComboBox"
windowclasses = [
"ComboBox",
"WindowsForms\d*\.COMBOBOX\..*",
"TComboBox"]
has_title = False
#-----------------------------------------------------------
def __init__(self, hwnd):
"Initialize the control"
super(ComboBoxWrapper, self).__init__(hwnd)
self.writable_props.extend([
"SelectedIndex",
"DroppedRect",
])
#-----------------------------------------------------------
def DroppedRect(self):
"Get the dropped rectangle of the combobox"
dropped_rect = win32structures.RECT()
self.SendMessage(
win32defines.CB_GETDROPPEDCONTROLRECT,
0,
ctypes.byref(dropped_rect))
# we need to offset the dropped rect from the control
dropped_rect -= self.Rectangle()
return dropped_rect
#-----------------------------------------------------------
def ItemCount(self):
"Return the number of items in the combobox"
return self.SendMessage(win32defines.CB_GETCOUNT)
#-----------------------------------------------------------
def SelectedIndex(self):
"Return the selected index"
return self.SendMessage(win32defines.CB_GETCURSEL)
#-----------------------------------------------------------
def _get_item_index(self, ident):
"Get the index for the item with this 'ident'"
if isinstance(ident, (int, long)):
if ident >= self.ItemCount():
raise IndexError(
"Combobox has %d items, you requested item %d (0 based)"%
(self.ItemCount(),
ident))
# negative index
if ident < 0:
# convert it to a positive index
ident = (self.ItemCount() + ident)
elif isinstance(ident, basestring):
# todo - implement fuzzy lookup for ComboBox items
# todo - implement appdata lookup for combobox items
ident = self.ItemTexts().index(ident)
return ident
#-----------------------------------------------------------
def ItemData(self, item):
"Returns the item data associated with the item if any"
index = self._get_item_index(item)
return self.SendMessage(win32defines.CB_GETITEMDATA, index)
#-----------------------------------------------------------
def ItemTexts(self):
"Return the text of the items of the combobox"
return _get_multiple_text_items(
self,
win32defines.CB_GETCOUNT,
win32defines.CB_GETLBTEXTLEN,
win32defines.CB_GETLBTEXT)
#-----------------------------------------------------------
def Texts(self):
"Return the text of the items in the combobox"
texts = [self.WindowText()]
texts.extend(self.ItemTexts())
return texts
#-----------------------------------------------------------
def GetProperties(self):
"Return the properties of the control as a dictionary"
props = HwndWrapper.HwndWrapper.GetProperties(self)
#props['ItemData'] = []
#for i in range(self.ItemCount()):
# props['ItemData'].append(self.ItemData(i))
return props
#-----------------------------------------------------------
def Select(self, item):
"""Select the ComboBox item
item can be either a 0 based index of the item to select
or it can be the string that you want to select
"""
self.VerifyActionable()
index = self._get_item_index(item)
# change the selected item
self.SendMessageTimeout(win32defines.CB_SETCURSEL, index)
# Notify the parent that we are finished selecting
self.NotifyParent(win32defines.CBN_SELENDOK)
# Notify the parent that we have changed
self.NotifyParent(win32defines.CBN_SELCHANGE)
# simple combo boxes don't have drop downs so they do not recieve
# this notification
if self.HasStyle(win32defines.CBS_DROPDOWN):
# Notify the parent that the drop down has closed
self.NotifyParent(win32defines.CBN_CLOSEUP)
win32functions.WaitGuiThreadIdle(self)
time.sleep(Timings.after_comboboxselect_wait)
# return this control so that actions can be chained.
return self
#-----------------------------------------------------------
#def Deselect(self, item):
# Not implemented because it doesn't make sense for combo boxes.
#TODO def EditControl(self): # return the edit control of the Combobox
#TODO def ListControl(self): # return the list control of the combobox
#TODO def ItemText(self, index): # get the test of item XX?
#TODO def EditText(self): # or should this be self.EditControl.Text()?
#====================================================================
class ListBoxWrapper(HwndWrapper.HwndWrapper):
"Wrap a windows ListBox control"
friendlyclassname = "ListBox"
windowclasses = [
"ListBox",
r"WindowsForms\d*\.LISTBOX\..*",
"ThunderListBox",
"ThunderFileListBox",
"TListBox",]
has_title = False
#-----------------------------------------------------------
def __init__(self, hwnd):
"Initialize the control"
super(ListBoxWrapper, self).__init__(hwnd)
self.writable_props.extend([
"SelectedIndices"])
#-----------------------------------------------------------
def SelectedIndices(self):
"The currently selected indices of the listbox"
num_selected = self.SendMessage(win32defines.LB_GETSELCOUNT)
# if we got LB_ERR then it is a single selection list box
if num_selected == win32defines.LB_ERR:
items = (self.SendMessage(win32defines.LB_GETCURSEL), )
# otherwise it is a multiselection list box
else:
items = (ctypes.c_int * num_selected)()
self.SendMessage(
win32defines.LB_GETSELITEMS, num_selected, ctypes.byref(items))
# Need to convert from Ctypes array to a python tuple
items = tuple(items)
return items
#-----------------------------------------------------------
def _get_item_index(self, ident):
"Return the index of the item 'ident'"
if isinstance(ident, (int, long)):
if ident >= self.ItemCount():
raise IndexError(
"ListBox has %d items, you requested item %d (0 based)"%
(self.ItemCount(),
ident))
# negative index
if ident < 0:
ident = (self.ItemCount() + ident)
elif isinstance(ident, basestring):
# todo - implement fuzzy lookup for ComboBox items
# todo - implement appdata lookup for combobox items
ident = self.ItemTexts().index(ident) #-1
return ident
#-----------------------------------------------------------
def ItemCount(self):
"Return the number of items in the ListBox"
return self.SendMessage(win32defines.LB_GETCOUNT)
#-----------------------------------------------------------
def ItemData(self, i):
"Return the ItemData if any associted with the item"
index = self._get_item_index(i)
return self.SendMessage(win32defines.LB_GETITEMDATA, index)
#-----------------------------------------------------------
def ItemTexts(self):
"Return the text of the items of the listbox"
return _get_multiple_text_items(
self,
win32defines.LB_GETCOUNT,
win32defines.LB_GETTEXTLEN,
win32defines.LB_GETTEXT)
#-----------------------------------------------------------
def Texts(self):
"Return the texts of the control"
texts = [self.WindowText()]
texts.extend(self.ItemTexts())
return texts
# #-----------------------------------------------------------
# def GetProperties(self):
# "Return the properties as a dictionary for the control"
# props = HwndWrapper.HwndWrapper.GetProperties(self)
#
# props['ItemData'] = []
# for i in range(self.ItemCount()):
# props['ItemData'].append(self.ItemData(i))
#
# return props
#-----------------------------------------------------------
def Select(self, item):
"""Select the ListBox item
item can be either a 0 based index of the item to select
or it can be the string that you want to select
"""
self.VerifyActionable()
# Make sure we have an index so if passed in a
# string then find which item it is
index = self._get_item_index(item)
# change the selected item
self.SendMessageTimeout(win32defines.LB_SETCURSEL, index)
# Notify the parent that we have changed
self.NotifyParent(win32defines.LBN_SELCHANGE)
win32functions.WaitGuiThreadIdle(self)
time.sleep(Timings.after_listboxselect_wait)
return self
#-----------------------------------------------------------
def SetItemFocus(self, item):
"Set the ListBox focus to the item at index"
index = self._get_item_index(item)
# if it is a multiple selection dialog
if self.HasStyle(win32defines.LBS_EXTENDEDSEL) or \
self.HasStyle(win32defines.LBS_MULTIPLESEL):
self.SendMessageTimeout(win32defines.LB_SETCARETINDEX, index)
else:
self.SendMessageTimeout(win32defines.LB_SETCURSEL, index)
win32functions.WaitGuiThreadIdle(self)
time.sleep(Timings.after_listboxfocuschange_wait)
# return this control so that actions can be chained.
return self
#-----------------------------------------------------------
def GetItemFocus(self):
"Retrun the index of current selection in a ListBox"
# if it is a multiple selection dialog
if self.HasStyle(win32defines.LBS_EXTENDEDSEL) or \
self.HasStyle(win32defines.LBS_MULTIPLESEL):
return self.SendMessage(win32defines.LB_GETCARETINDEX)
else:
return self.SendMessage(win32defines.LB_GETCURSEL)
#====================================================================
class EditWrapper(HwndWrapper.HwndWrapper):
"Wrap a windows Edit control"
friendlyclassname = "Edit"
windowclasses = [
"Edit",
"TEdit",
"TMemo",
r"WindowsForms\d*\.EDIT\..*",
"ThunderTextBox",
"ThunderRT6TextBox",
]
has_title = False
#-----------------------------------------------------------
def __init__(self, hwnd):
"Initialize the control"
super(EditWrapper, self).__init__(hwnd)
self.writable_props.extend([
'SelectionIndices'])
#-----------------------------------------------------------
def LineCount(self):
"Return how many lines there are in the Edit"
return self.SendMessage(win32defines.EM_GETLINECOUNT)-1
#-----------------------------------------------------------
def LineLength(self, line_index):
"Return how many characters there are in the line"
# need to first get a character index of that line
char_index = self.SendMessage(win32defines.EM_LINEINDEX, line_index)
# now get the length of text on that line
return self.SendMessage (
win32defines.EM_LINELENGTH, char_index, 0)
#-----------------------------------------------------------
def GetLine(self, line_index):
"Return the line specified"
text_len = self.LineLength(line_index)
# create a buffer and set the length at the start of the buffer
text = ctypes.create_unicode_buffer(text_len+3)
text[0] = unichr(text_len)
# retrieve the line itself
self.SendMessage(
win32defines.EM_GETLINE, line_index, ctypes.byref(text))
return text.value
#-----------------------------------------------------------
def Texts(self):
"Get the text of the edit control"
texts = [self.WindowText(), ]
for i in range(0, self.LineCount()+1):
texts.append(self.GetLine(i))
return texts
#-----------------------------------------------------------
def TextBlock(self):
"Get the text of the edit control"
length = self.SendMessage(win32defines.WM_GETTEXTLENGTH)
text = ctypes.create_unicode_buffer(length + 1)
self.SendMessage(win32defines.WM_GETTEXT, length+1, ctypes.byref(text))
#text = text.value.replace("\r\n", "\n")
return text.value
#-----------------------------------------------------------
def SelectionIndices(self):
"The start and end indices of the current selection"
start = ctypes.c_int()
end = ctypes.c_int()
self.SendMessage(
win32defines.EM_GETSEL, ctypes.byref(start), ctypes.byref(end))
return (start.value, end.value)
#-----------------------------------------------------------
def SetWindowText(self, text, append = False):
"""Override SetWindowText for edit controls because it should not be
used for Edit controls.
Edit Controls should either use SetEditText() or TypeKeys() to modify
the contents of the edit control."""
HwndWrapper.HwndWrapper.SetWindowText(self, text, append)
raise UserWarning(
"SetWindowText() should probably not be called for Edit Controls")
#-----------------------------------------------------------
def SetEditText(self, text, pos_start = None, pos_end = None):
"Set the text of the edit control"
self.VerifyActionable()
# allow one or both of pos_start and pos_end to be None
if pos_start is not None or pos_end is not None:
# if only one has been specified - then set the other
# to the current selection start or end
start, end = self.SelectionIndices()
if pos_start is None:
pos_start = start
if pos_end is None:
pos_end = end
# set the selection if either start or end has
# been specified
self.Select(pos_start, pos_end)
else:
self.Select()
# replace the selection with
text = ctypes.c_wchar_p(unicode(text))
self.SendMessageTimeout(win32defines.EM_REPLACESEL, True, text)
win32functions.WaitGuiThreadIdle(self)
time.sleep(Timings.after_editsetedittext_wait)
# return this control so that actions can be chained.
return self
# set SetText as an alias to SetEditText
SetText = SetEditText
#-----------------------------------------------------------
def Select(self, start = 0, end = None):
"Set the edit selection of the edit control"
self.VerifyActionable()
# if we have been asked to select a string
if isinstance(start, basestring):
string_to_select = start
#
start = self.TextBlock().index(string_to_select)
if end is None:
end = start + len(string_to_select)
if end is None:
end = -1
self.SendMessageTimeout(win32defines.EM_SETSEL, start, end)
# give the control a chance to catch up before continuing
win32functions.WaitGuiThreadIdle(self)
time.sleep(Timings.after_editselect_wait)
# return this control so that actions can be chained.
return self
#====================================================================
class StaticWrapper(HwndWrapper.HwndWrapper):
"Wrap a windows Static control"
friendlyclassname = "Static"
windowclasses = [
"Static",
r"WindowsForms\d*\.STATIC\..*",
"TPanel"]
can_be_label = True
def __init__(self, hwnd):
"Initialize the control"
super(StaticWrapper, self).__init__(hwnd)
# if the control is visible - and it shows an image
if self.IsVisible() and (
self.HasStyle(win32defines.SS_ICON) or \
self.HasStyle(win32defines.SS_BITMAP) or \
self.HasStyle(win32defines.SS_CENTERIMAGE) or \
self.HasStyle(win32defines.SS_OWNERDRAW)):
self._NeedsImageProp = True
#====================================================================
# the main reason for this is just to make sure that
# a Dialog is a known class - and we don't need to take
# an image of it (as an unknown control class)
class DialogWrapper(HwndWrapper.HwndWrapper):
"Wrap a dialog"
friendlyclassname = "Dialog"
#windowclasses = ["#32770", ]
can_be_label = True
#-----------------------------------------------------------
def __init__(self, hwnd):
"""Initialize the DialogWrapper
The only extra functionality here is to modify self.friendlyclassname
to make it "Dialog" if the class is "#32770" otherwise to leave it
the same as the window class.
"""
HwndWrapper.HwndWrapper.__init__(self, hwnd)
if self.Class() == "#32770":
self.friendlyclassname = "Dialog"
else:
self.friendlyclassname = self.Class()
#-----------------------------------------------------------
def RunTests(self, tests_to_run = None, ref_controls = None):
"Run the tests on dialog"
# get all the controls
controls = [self] + self.Children()
# add the reference controls
if ref_controls is not None:
matched_flags = controlproperties.SetReferenceControls(
controls, ref_controls)
# todo: allow some checking of how well the controls matched
# matched_flags says how well they matched
# 1 = same number of controls
# 2 = ID's matched
# 4 = control classes matched
# i.e. 1 + 2 + 4 = perfect match
return tests.run_tests(controls, tests_to_run)
#-----------------------------------------------------------
def WriteToXML(self, filename):
"Write the dialog an XML file (requires elementtree)"
controls = [self] + self.Children()
props = [ctrl.GetProperties() for ctrl in controls]
from pywinauto import XMLHelpers
XMLHelpers.WriteDialogToFile(filename, props)
#-----------------------------------------------------------
def ClientAreaRect(self):
"""Return the client area rectangle
From MSDN
The client area of a control is the bounds of the control, minus the
nonclient elements such as scroll bars, borders, title bars, and
menus."""
rect = win32structures.RECT(self.Rectangle())
self.SendMessage(win32defines.WM_NCCALCSIZE, 0, ctypes.byref(rect))
return rect
# #-----------------------------------------------------------
# def ReadControlsFromXML(self, filename):
# from pywinauto import XMLHelpers
# [controlproperties.ControlProps(ctrl) for
# ctrl in XMLHelpers.ReadPropertiesFromFile(handle)]
# #-----------------------------------------------------------
# def AddReference(self, reference):
#
# if len(self.Children() != len(reference)):
# raise "different number of reference controls"
#
# for i, ctrl in enumerate(reference):
# # loop over each of the controls
# # and set the reference
# if isinstance(ctrl, dict):
# ctrl = CtrlProps(ctrl)
#
# self.
# if ctrl.Class() != self.Children()[i+1].Class():
# print "different classes"
#====================================================================
# the main reason for this is just to make sure that
# a Dialog is a known class - and we don't need to take
# an image of it (as an unknown control class)
class PopupMenuWrapper(HwndWrapper.HwndWrapper):
"Wrap a Popup Menu"
friendlyclassname = "PopupMenu"
windowclasses = ["#32768", ]
has_title = False
#-----------------------------------------------------------
def IsDialog(self):
"Return whether it is a dialog"
return True
#-----------------------------------------------------------
def _menu_handle(self):
"Get the menu handle for the popup menu menu"
mbi = win32structures.MENUBARINFO()
mbi.cbSize = ctypes.sizeof(mbi)
ret = win32functions.GetMenuBarInfo(
self,
win32defines.OBJID_CLIENT,
0,
ctypes.byref(mbi))
if not ret:
raise ctypes.WinError()
return mbi.hMenu

@ -1,754 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Change Log &mdash; pywinauto 0.4.2 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.4.2',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="pywinauto 0.4.2 documentation" href="index.html" />
<link rel="next" title="Main user modules" href="code/code.html" />
<link rel="prev" title="PYWINAUTO TODOs" href="TODO.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="code/code.html" title="Main user modules"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="TODO.html" title="PYWINAUTO TODOs"
accesskey="P">previous</a> |</li>
<li><a href="contents.html">pywinauto 0.4.2 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="change-log">
<h1>Change Log<a class="headerlink" href="#change-log" title="Permalink to this headline"></a></h1>
<div class="section" id="various-cleanup-and-bug-fixes">
<h2>0.4.0 Various cleanup and bug fixes.<a class="headerlink" href="#various-cleanup-and-bug-fixes" title="Permalink to this headline"></a></h2>
<p>03-April-2010</p>
<blockquote>
<div><ul class="simple">
<li>Gracefully Handle dir() calls on Application or WindowSpecification objects
(which used hang for a while as these classes would search for windows
matching __members__, __methods__ and __bases__). The code now checks for
any attribute that starts with &#8216;__&#8217; and ends with &#8216;__&#8217; and raises
AttributeError immediately. Thanks to Sebastian Haase for raising this.</li>
<li>Removed the reference to an Application object in WindowSpecification.
It was not used in the class and made the class harder to use.
WindowSpecification is now more useful as a utility class.</li>
<li>Add imports of application.WindowSpecification and application.Application
to pywinauto.__init__.py so that these classes can be used more easily
(without having to directly import pywinauto.application). Thanks again to
Sebastian Haase.</li>
<li>Added a function to empty the clipboard (thanks to Tocer on Sourceforge)</li>
<li>Use &#8216;SendMessageTimeout&#8217; to get the text of a window. (SendMessage will hang
if the application is not processing messages)</li>
<li>Fixed references to PIL.ImageGrab. PIL add&#8217;s it&#8217;s module directly to the
module path, so it should just be referenced by ImageGrab and not
PIL.ImageGrab.</li>
<li>Use AttachThreadInput + PostMessage rather than SendMessageTimeout to send
mouse clicks.</li>
<li>Fix how timeout retry times are calculated in timings.WaitUntil() and
timings.Wait</li>
<li>Fixed some issues with application.Kill_() method, highlighted due to the
changes in the HwndWrapper.Close() method.</li>
<li>Fix writing images to XML. It was broken with updates to PIL that I had not
followed. Changed the method of knowing if it is an image by checking for
various attributes.</li>
<li>Renamed WindowSpecification.(Ww)indow() to ChildWindow() and added
deprecation messages for the other functions.</li>
<li>Improved the tests (fixed test failures which were not pywinauto issues)</li>
</ul>
</div></blockquote>
</div>
<div class="section" id="experimental-new-sendkeys-and-various-fixes">
<h2>0.3.9 Experimental! New Sendkeys, and various fixes<a class="headerlink" href="#experimental-new-sendkeys-and-various-fixes" title="Permalink to this headline"></a></h2>
<p>27-November-2009</p>
<blockquote>
<div><ul class="simple">
<li>Major change this release is that Sendkeys is no longer a requirement!
A replacement that supports Unicode is included with pywinauto. (hopefully
soon to be released as a standalone module). Please note - this is still
quite untested so this release should be treated with some care..</li>
<li>Made sure that default for WindowSpecification.Window_() was to look
for non top level windows. The defaults in find_windows() had been
changed previously and it now needed to be explicitly overridden.</li>
<li>Fixed a missing reference to &#8216;win32defines&#8217; when referencing WAIT_TIMEOUT
another typo of false (changed to False)</li>
<li>Removed the restriction to only get the active windows for the process,
now it will be possible to get the active windows, even if a process is
not specified.
From <a class="reference external" href="http://msdn.microsoft.com/en-us/library/ms633506%28VS.85%29.aspx">http://msdn.microsoft.com/en-us/library/ms633506%28VS.85%29.aspx</a>
it gets the active window for the foreground thread.</li>
<li>Hopefully improved Delphi TreeView and ListView handling (added window
class names as supported window classes to the appropriate classes).</li>
<li>Added support for running UI tests with reference controls. (requried
for some localization tests)</li>
<li>Various PyLint and PEP8 fixes made.</li>
</ul>
</div></blockquote>
</div>
<div class="section" id="collecting-improvements-from-last-2-years">
<h2>0.3.8 Collecting improvements from last 2 years<a class="headerlink" href="#collecting-improvements-from-last-2-years" title="Permalink to this headline"></a></h2>
<p>10-March-2009</p>
<blockquote>
<div><ul class="simple">
<li>Fixed toolbar button pressing - This required for
HwndWrapper.NotifyParent() to be updated (to accept a new
ID parameter)</li>
<li>Fixed a bug wherea listview without a column control would
make pywinauto fail to capture the dialog.</li>
<li>Converted documenation from Pudge generated to Sphinx Generated</li>
<li>Added some baic support for Pager and Progress controls
(no tests yet)</li>
<li>Added some more VB &#8216;edit&#8217; window classes</li>
<li>Added some more VB &#8216;listbox&#8217; window classes</li>
<li>Added some more VB &#8216;button&#8217; window classes</li>
<li>Ensured that return value from ComboBoxWrapper.SelectedIndices
is always a tuple (there was a bug where it would sometimes be
a ctypes array)</li>
<li>Changed default for finding windows to find disabled windows
as well as enabled ones (previous was to find enabled windows only)
(note this may impact scripts that relied on the previous
setting i.e. in cases where two dialogs have the same title!)</li>
<li>Much better handling of InvalidWindowHandle during automation
runs. This could be raised when a closing window is still available
when the automation was called, but is gone half way through
whatever function was called.</li>
<li>Made clicking more robust by adding a tiny wait between each
SendMessageTimeout in _perform_click().</li>
<li>Added attributes <tt class="docutils literal"><span class="pre">can_be_label</span></tt> and <tt class="docutils literal"><span class="pre">has_title</span></tt> to <tt class="docutils literal"><span class="pre">HwndWrapper</span></tt>
and subclasses to specify whether a control can act as a label for
other controls, and whether the title should be used for identifying
the control. If you have created your own HwndWrapper subclasses you
may need to override the defaults.</li>
<li>Added a <tt class="docutils literal"><span class="pre">control_id</span></tt> parameter to find_windows which allows
finding windows based off of their control id&#8217;s</li>
<li>Added a FriendlyClassName method to MenuItem</li>
<li>Split up the functions for button truncation data</li>
<li>Commented out code to get a new font if the font could not
be recovered</li>
<li>Moved code to get the control font from Truncation test to
handleprops</li>
<li>Added a function to get the string representation of the
bug. (need to refactor PrintBugs at some point).</li>
<li>Fixed a variable name (from fname -&gt; font_attrib as fname
was not a defined variable!)</li>
<li>Forced some return values from MissingExtraString test
to be Unicode</li>
<li>Fixed the MiscValues test (converted to Unicode and
removed some extraneous characters)</li>
<li>Updated the path for all unittests</li>
<li>Made two unit tests sligthly more robust and less dependent
on computer/app settings</li>
<li>Updated timing settings for unit tests</li>
<li>Updated the examples to work in dev environment.</li>
</ul>
</div></blockquote>
</div>
<div class="section" id="merge-of-wait-changes-and-various-bug-fixes-improvements">
<h2>0.3.7 Merge of Wait changes and various bug fixes/improvements<a class="headerlink" href="#merge-of-wait-changes-and-various-bug-fixes-improvements" title="Permalink to this headline"></a></h2>
<p>10-April-2007</p>
<ul class="simple">
<li>Added Timings.WaitUntil() and Timings.WaitUntilPasses() which
handle the various wait until something in the code. Also
refactored existing waits to use these two methods.</li>
<li>Fixed a major Handle leak in RemoteMemorBlock class (which is
used extensively for &#8216;Common&#8217; controls. I was using OpenHandle
to open the process handle, but was not calling CloseHandle()
for each corresponding OpenHandle().</li>
<li>Added an active_() method to Application class to return the
active window of the application.</li>
<li>Added an &#8216;active&#8217; option to WindowSpecification.Wait() and
WaitNot().</li>
<li>Some cleanup of the clipboard module. GetFormatName()
was improved and GetData() made a little more robust.</li>
<li>Added an option to findwindows.find_windows() to find only
active windows (e.g. active_only = True). Default is False.</li>
<li>Fixed a bug in the timings.Timings class - timing values are
Now accessed through the class (Timings) and not through the
intance (self).</li>
<li>Updated ElementTree import in XMLHelpers so that it would work
on Python 2.5 (where elementtree is a standard module) as well
as other versions where ElementTree is a separate module.</li>
<li>Enhanced Item selection for ListViews, TreeViews - it is now
possible to pass strings and they will be searched for. More
documentation is required though.</li>
<li>Greatly enhanced Toolbar button clicking, selection, etc.
Though more documentation is required.</li>
<li>Added option to ClickInput() to allow mouse wheel movements
to be made.</li>
<li>menuwrapper.Menu.GetProperties() now returns a dict like all other
GetProperties() methods. This dict for now only has one key
&#8216;MenuItems&#8217; which contains the list of menuitems (which had been
the previous return value).</li>
</ul>
</div>
<div class="section" id="b-changes-not-documented-in-0-3-6-history">
<h2>0.3.6b Changes not documented in 0.3.6 history<a class="headerlink" href="#b-changes-not-documented-in-0-3-6-history" title="Permalink to this headline"></a></h2>
<p>31-July-2006</p>
<ul class="simple">
<li>Fixed a bug in how findbestmatch.FindBestMatches was working.
It would match against text when it should not!</li>
<li>Updated how timings.Timings.Slow() worked, if any time setting
was less then .2 after &#8216;slowing&#8217; then set it to .2</li>
</ul>
</div>
<div class="section" id="scrolling-and-treview-item-clicking-added">
<h2>0.3.6 Scrolling and Treview Item Clicking added<a class="headerlink" href="#scrolling-and-treview-item-clicking-added" title="Permalink to this headline"></a></h2>
<p>28-July-2006</p>
<ul class="simple">
<li>Added parameter to <tt class="docutils literal"><span class="pre">_treeview_item.Rectangle()</span></tt> to have an option
to get the Text rectangle of the item. And defaulted to this.</li>
<li>Added <tt class="docutils literal"><span class="pre">_treeview_item.Click()</span></tt> method to make it easy to click
on tree view items.</li>
<li>Fixed a bug in <tt class="docutils literal"><span class="pre">TreeView.GetItem()</span></tt> that was expanding items
when it shouldn&#8217;t.</li>
<li>Added <tt class="docutils literal"><span class="pre">HwndWrapper.Scroll()</span></tt> method to allow scrolling. This
is a very minimal implementation - and if the scrollbars are
implemented as separate controls (rather then a property of a
control - this will probably not work for you!). It works for
Notepad and Paint - that is all I have tried so far.</li>
<li>Added a call to <tt class="docutils literal"><span class="pre">HwndWrapper.SetFocus()</span></tt> in
<tt class="docutils literal"><span class="pre">_perform_click_input()</span></tt> so that calls to
<tt class="docutils literal"><span class="pre">HwndWrapper.ClickInput()</span></tt> will make sure to click on the
correct window.</li>
</ul>
</div>
<div class="section" id="moved-to-metaclass-control-wrapping">
<h2>0.3.5 Moved to Metaclass control wrapping<a class="headerlink" href="#moved-to-metaclass-control-wrapping" title="Permalink to this headline"></a></h2>
<p>24-May-2006</p>
<ul class="simple">
<li>Moved to a metaclass implementation of control finding. This
removes some cyclic importing that had to be worked around and
other then metaclass magic makes the code a bit simpler.</li>
<li>Some of the sample files would not run - so I updated them
so they would (Thanks to Stefaan Himpe for pointing this out)</li>
<li>Disabled saving application data (it was still being saved in
Application.RecordMatch() even if the rest of the application
data code is disabled. This was causing what appeared to be a
memory leak where pywinauto would keep grabbing more and more
memory (especially for controls that contain a lot of
information). Thanks to Frank Martinez for leading me to this).</li>
<li>Added ListViewWrapper.GetItemRect() to enable retrieving the
rectangle for a particular item in the listview.</li>
<li>Removed references to _ctrl() method within pywinauto as it
was raising a DeprecationWarning internally even if the user
was not using it.</li>
</ul>
</div>
<div class="section" id="fixed-issue-with-latest-ctypes-speed-gains-other-changes">
<h2>0.3.4 Fixed issue with latest ctypes, speed gains, other changes<a class="headerlink" href="#fixed-issue-with-latest-ctypes-speed-gains-other-changes" title="Permalink to this headline"></a></h2>
<p>25-Apr-2006</p>
<ul class="simple">
<li>The latest version of ctypes (0.9.9.6) removed the code generator
I was using some generated code in win32functions.py (stdcall). I
was not using those functions so I just commented them out.</li>
<li>Started the process of renaming methods of the <tt class="docutils literal"><span class="pre">Application</span></tt> and
<tt class="docutils literal"><span class="pre">WindowSpecification</span></tt> classes. I will be converting names to
<tt class="docutils literal"><span class="pre">UppercaseNames_()</span></tt>. The trailing <tt class="docutils literal"><span class="pre">_</span></tt> is to disambiguate the
method names from potential Window titles.</li>
<li>Updated how print_control_identifiers works so that it now always
prints the disambiguated control name. (even for single controls)</li>
<li>Added __hash__ to HwndWrapper so that controls could be dictionary
keys.</li>
<li>Caching various information at various points. For example I cache
how well two pieces of text match. For short scripts this has
little impact - but for larger script it could well have a major
impact.
Also caching information for controls that cannot change
e.g. TopLeveParent, Parent, etc</li>
</ul>
</div>
<div class="section" id="added-some-methods-and-fixed-some-small-bugs">
<h2>0.3.3 Added some methods, and fixed some small bugs<a class="headerlink" href="#added-some-methods-and-fixed-some-small-bugs" title="Permalink to this headline"></a></h2>
<p>19-Apr-2006</p>
<ul class="simple">
<li>Added a wait for the control to be active and configurable
sleeps after &#8216;modifying&#8217; actions (e.g. Select, Deselect, etc)</li>
<li>Fixed Timings.Slow() and Timings.Fast() - they could in certain
circumstances do the opposite! If you had already set a timing
slower or faster then they would set it then they would blindly
ignore that and set their own times. I added functionality that
they will take either the slowest or fastest of the new/current
setting rather then blindly setting to the new value.</li>
<li>Fixed some hidden bugs with HwndWrapper.CloseClick()</li>
<li>Fixed a bug in setup.py that would raise an error when no
argument was specified</li>
<li>Added an argument to HwndWrapper.SendMessageTimeout so that
the wait options could be passed in.</li>
<li>Added HwndWrapper.Close(), Maximize(), Minimize(), Restore()
and GetShowState().</li>
<li>Commented out all deprecated methods (will be removed completely
in some future release).</li>
<li>Added Application.kill_() method - which closes all windows and
kills the application. If the application is asking if you want
to save your changes - you will not be able to click yes or no
and the application will be killed anyway!.</li>
</ul>
</div>
<div class="section" id="fixed-setup-py-and-some-typos">
<h2>0.3.2 Fixed setup.py and some typos<a class="headerlink" href="#fixed-setup-py-and-some-typos" title="Permalink to this headline"></a></h2>
<p>31-Mar-2006</p>
<ul class="simple">
<li>Fixed the spelling of Stefaan Himpe&#8217;s name</li>
<li>Fixed setup.py which was working for creating a distribution but
not for installing it (again thanks to Stefaan for pointing it out!)</li>
</ul>
</div>
<div class="section" id="performance-tune-ups">
<h2>0.3.1 Performance tune-ups<a class="headerlink" href="#performance-tune-ups" title="Permalink to this headline"></a></h2>
<p>30-Mar-2006</p>
<ul class="simple">
<li>Change calculation of distance in findbestmatch.GetNonTextControlName()
so that it does not need to square or get the square root to
find the real distance - as we only need to compare values - not have
the actual distance. (Thanks to Stefaan Himpe)</li>
<li>Compiled regular expression patterns before doing the match to
avoid compiling the regular expression for window that is being
tested (Thanks to Stefaan Himpe)</li>
<li>Made it easier to add your own control tests by adding a file
extra_tests.py which needs to export a ModifyRegisteredTests() method.
Also cleaned up the code a little.</li>
<li>Updated notepad_fast.py to make it easier to profile (adde a method)</li>
<li>Changed WrapHandle to use a cache for classes it has matched - this is
to avoid having to match against all classes constantly.</li>
<li>Changed default timeout in SendMessageTimeout to .001 seconds from .4
seconds this results in a significant speedup. Will need to make this
value modifiable via the timing module/routine.</li>
<li>WaitNot was raising an error if the control was not found - it should
have returned (i.e. success - control is not in any particular state
because it does not exist!).</li>
<li>Added ListViewWrapper.Deselect() per Chistophe Keller&#8217;s suggestion.
While I was at it I added a check on the item value passed in and added
a call to WaitGuiIdle(self) so that the control has a chance to process
the message.</li>
<li>Changed doc templates and moved dependencies into pywinauto
subversion to ensure that all files were availabe at www.openqa.org and
that they are not broken when viewed there.</li>
<li>Moved all timing information into the timings.Timings class. There are
some simple methods for changing the timings.</li>
</ul>
</div>
<div class="section" id="added-application-data-now-useful-for-localization-testing">
<h2>0.3.0 Added Application data - now useful for localization testing<a class="headerlink" href="#added-application-data-now-useful-for-localization-testing" title="Permalink to this headline"></a></h2>
<p>20-Mar-2006</p>
<ul>
<li><p class="first">Added automatic Application data collection which can be used when
running the same test on a different spoken language version. Support
is still preliminary and is expected to change. Please treat as early
Alpha.</p>
<p>If you have a different language version of Windows then you can try
this out by running the notepad_fast.py example with the langauge
argument e.g.</p>
<div class="highlight-python"><pre>examples\notepad_fast.py language</pre>
</div>
<p>This will load the application data from the supplied file
notepad_fast.pkl and use it for finding the right menu items and
controls to select.</p>
</li>
<li><p class="first">Test implementation to make it easier to start using an application.
Previously you needed to write code like</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span> <span class="o">=</span> <span class="n">Application</span><span class="p">()</span><span class="o">.</span><span class="n">connect_</span><span class="p">(</span><span class="n">title</span> <span class="o">=</span> <span class="s">&#39;Find&#39;</span><span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">Find</span><span class="o">.</span><span class="n">Close</span><span class="o">.</span><span class="n">Click</span><span class="p">()</span>
<span class="n">app</span><span class="o">.</span><span class="n">NotePad</span><span class="o">.</span><span class="n">MenuSelect</span><span class="p">(</span><span class="s">&quot;File-&gt;Exit&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>1st change was to implement static methods <tt class="docutils literal"><span class="pre">start()</span></tt> and
<tt class="docutils literal"><span class="pre">connect()</span></tt>. These methods return a new Application instance
so the above code becomes:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span> <span class="o">=</span> <span class="n">Application</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">title</span> <span class="o">=</span> <span class="s">&#39;Find&#39;</span><span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">Find</span><span class="o">.</span><span class="n">Close</span><span class="o">.</span><span class="n">Click</span><span class="p">()</span>
<span class="n">app</span><span class="o">.</span><span class="n">NotePad</span><span class="o">.</span><span class="n">MenuSelect</span><span class="p">(</span><span class="s">&quot;File-&gt;Exit&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>I also wanted to make it easier to start working with a simple
application - that may or may not have only one dialog. To make this
situation easier I made <tt class="docutils literal"><span class="pre">window_()</span></tt> not throw if the application has not
been <tt class="docutils literal"><span class="pre">start()ed</span></tt> or <tt class="docutils literal"><span class="pre">connect()ed</span></tt> first. This leads to simpler code
like:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span> <span class="o">=</span> <span class="n">Application</span><span class="p">()</span>
<span class="n">app</span><span class="o">.</span><span class="n">Find</span><span class="o">.</span><span class="n">Close</span><span class="o">.</span><span class="n">Click</span><span class="p">()</span>
<span class="n">app</span><span class="o">.</span><span class="n">NotePad</span><span class="o">.</span><span class="n">MenuSelect</span><span class="p">(</span><span class="s">&quot;File-&gt;Exit&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>What happens here is that when you execute any of Application.window_(),
Application.__getattr__() or Application.__getitem__() when the
application hasn&#8217;t been connected or started. It looks for the window
that best matches your specification and connects the application to
that process.</p>
<p>This is extra functionality - existing connect_() and
start_() methods still exist</p>
</li>
<li><p class="first">Fixed HwndWrapper.SetFocus() so that it would work even if the window
was not in the foreground. (it now makes the window foreground as well
as giving it focus). This overcomes a restriction in Windows where
you can only change the foreground window if you own the foreground
window.</p>
</li>
<li><p class="first">Changed some 2.4&#8217;isms that an anonymous commenter left on my blog :-)
with these changes pywinauto should run on Python 2.3 (though I haven&#8217;t
done extensive testing).</p>
</li>
<li><p class="first">Commented out controls.common_controls.TabControlWrapper.GetTabState()
and TabStates() as these did not seem to be returning valid values anyway.</p>
</li>
<li><p class="first">Fixed documentation issues were parts of the documentation were not
getting generated to the HTML files.</p>
</li>
<li><p class="first">Fixed issue where MenuSelect would sometimes not work as expected.
Some Menu actions require that the window that owns the menu be active.
Added a call to SetFocus() before selecting a menu item to ensure that
the window was active.</p>
</li>
<li><p class="first">Fixed Bug 1452832 where clipboard was not closed in clipboard.GetData()</p>
</li>
<li><p class="first">Added more unit tests now up to 248 from 207</p>
</li>
</ul>
</div>
<div class="section" id="more-refactoring-more-tests">
<h2>0.2.5 More refactoring, more tests<a class="headerlink" href="#more-refactoring-more-tests" title="Permalink to this headline"></a></h2>
<p>07-Mar-2006</p>
<ul>
<li><p class="first">Added wrapper classes for Menus and MenuItems this enabled cleaner
interaction with Menu&#8217;s. It also gives more functionality - you can now
programmatically Click() on menus, and query if a menu item is checked
or not.</p>
</li>
<li><p class="first">Added application.WindowSpecification.Wait() and WaitNot() methods.
These methods allow you to wait for a control to exist, be visible,
be enabled, be ready (both enabled and visible!) or to wait for the
control to not be in any of these states. WaitReady(),
WaitNotEnabled(), WaitNotVisible() now use these methods. I was able to also
add the missing methods WaitNotReady(), WaitEnabled(), WaitVisible(),
WaitExists(), WaitnotExists(). Please use Wait() and WaitNot() as I have
Deprecated these Wait* methods.</p>
</li>
<li><p class="first">Slightly modified timeout waits for control resolution so that a timed
function more accurately follows the timeout value specified.</p>
</li>
<li><p class="first">Added application.Application.start() and connect() static methods. These
methods are factory methods in that they will return an initialized Application
instance. They work exactly the same as start_() and connect() as they are
implemented in terms of those.</p>
<blockquote>
<div><p>from pywinauto.application import Application
notepad = Application.start(&#8220;notepad&#8221;)
same_notepad = Application.connect(path = &#8220;notepad&#8221;)</p>
</div></blockquote>
</li>
<li><p class="first">Updated the examples to follow changes to the code - and to make them a little
more robust.</p>
</li>
<li><p class="first">Added a new Controls Overview document page which lists all the actions on
all controls.</p>
</li>
<li><p class="first">Added more unit tests now up to 207 from 134 (added 68 tests)</p>
</li>
</ul>
</div>
<div class="section" id="small-release-number-big-changes">
<h2>0.2.1 Small Release number - big changes<a class="headerlink" href="#small-release-number-big-changes" title="Permalink to this headline"></a></h2>
<p>17-Feb-2006</p>
<ul>
<li><p class="first">Quick release to get many changes out there - but this release has
been less tested then I would like for a .3 release.</p>
</li>
<li><p class="first">Allow access to non text controls using the closest Text control.
This closest text control will normally be the static/label associated
with the control. For example in Notepad, Format-&gt;Font dialog, the 1st
combobox can be refered to as &#8220;FontComboBox&#8221; rather than &#8220;ComboBox1&#8221;</p>
</li>
<li><p class="first">Added a new control wrapper - <tt class="docutils literal"><span class="pre">PopupMenuWrapper</span></tt> for context menu&#8217;s
You can now work easily with context menu&#8217;s
e.g.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">Notepad</span><span class="o">.</span><span class="n">Edit</span><span class="o">.</span><span class="n">RightClick</span><span class="p">()</span>
<span class="c"># need to use MenuClick rather then MenuSelect</span>
<span class="n">app</span><span class="o">.</span><span class="n">PopupMenu</span><span class="o">.</span><span class="n">MenuClick</span><span class="p">(</span><span class="s">&quot;Select All&quot;</span><span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">Notepad</span><span class="o">.</span><span class="n">Edit</span><span class="o">.</span><span class="n">RightClick</span><span class="p">()</span>
<span class="n">app</span><span class="o">.</span><span class="n">PopupMenu</span><span class="o">.</span><span class="n">MenuClick</span><span class="p">(</span><span class="s">&quot;Copy&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>I could think of merging the <tt class="docutils literal"><span class="pre">RightClick()</span></tt> and <tt class="docutils literal"><span class="pre">MenuSelect()</span></tt> into one method
<tt class="docutils literal"><span class="pre">ContextMenuSelect()</span></tt> if that makes sense to most people.</p>
</li>
<li><p class="first">Added Support for Up-Down controls</p>
</li>
<li><p class="first">Not all top level windows now have a FriendlyClassName of &#8220;Dialog&#8221;.
I changed this because it made it hard to get windows of a particular
class. For example the main Notepad window has a class name of &#8220;Notepad&#8221;.</p>
<p>This was primarily implemented due to work I did getting the System Tray.</p>
</li>
<li><p class="first">Renamed <tt class="docutils literal"><span class="pre">StatusBarWrapper.PartWidths()</span></tt> to <tt class="docutils literal"><span class="pre">PartRightEdges()</span></tt> as this
is more correct for what it returns.</p>
</li>
<li><p class="first">Changed HwndWrapper.Text() and SetText() to WindowText() and
SetWindowText() respectively to try and make it clearer that it is
the text returned by GetWindowText and not the text that is visible
on the control. This change also suggested that EditWrapper.SetText()
be changed to SetEditText() (though this is not a hard requirement
EditWrapper.SetText() still exists - but may be deprecated.</p>
</li>
<li><p class="first">Added ClickInput, DoubleClickInput, RightClickInput, PressMouseInput
ReleaseMouseInput to HwndWrapper - these use SendInput rather then
WM_LBUTTONDOWN, WM_RBUTTONUP, etc used by Click, DoubleClick etc.</p>
<p>I also added a MenuClick method that allows you to click on menu
items. This means you can now &#8216;physically&#8217; drop menus down.</p>
</li>
<li><p class="first">Some further working with tooltips that need to be cleaned up.</p>
</li>
<li><p class="first">Fixed a bug where coordinates passed to any of the Click operations had
the X and Y coordinates swapped.</p>
</li>
<li><p class="first">Added new MenuItem and Menu classes that are to the most part hidden
but you can get a menu item by doing</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">Notepad</span><span class="o">.</span><span class="n">MenuItem</span><span class="p">(</span><span class="s">&quot;View&quot;</span><span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">Notepad</span><span class="o">.</span><span class="n">MenuItem</span><span class="p">(</span><span class="s">&quot;View-&gt;Status Bar&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>MenuItems have various actions so for example you can use
<tt class="docutils literal"><span class="pre">MenuItem.IsChecked()</span></tt> to check if the menu item is checked.
Among other methods there are <tt class="docutils literal"><span class="pre">Click()</span></tt> and <tt class="docutils literal"><span class="pre">Enabled()</span></tt>.</p>
</li>
<li><p class="first">Modified the &#8216;best match&#8217; algorithm for finding controls.
It now searches a couple of times, and tries to find the best
fit for the text passed to it. The idea here is to make it more
&#8220;Select what I want - not that other thing that looks a bit like
what I want!&#8221;. It is possible this change could mean you need to
use new identifiers in scripts - but in general very little modification
should be necessary.</p>
<p>There was also a change to the algorithm that looked for the closest
text control. It missed some obvious controls in the previous
implementation. It also had a bug for controls above the control
rather than to the left.</p>
</li>
<li><p class="first">Added a new example scripts SaveFromInternetExplorer.py and
SaveFromFirefox.py which show automating downloading of a page
from either of these browsers.</p>
</li>
<li><p class="first">Added yet more unit tests, there are now a total of 134 tests.</p>
</li>
</ul>
</div>
<div class="section" id="significant-refactoring">
<h2>0.2.0 Significant refactoring<a class="headerlink" href="#significant-refactoring" title="Permalink to this headline"></a></h2>
<p>06-Feb-2006</p>
<ul>
<li><p class="first">Changed how windows are searched for (from application)
This chage should not be a significant change for users</p>
</li>
<li><p class="first">Started adding unit tests (and the have already uncovered bugs
that been fixed). They also point to areas of missing functionality
that will be addded with future updates</p>
</li>
<li><p class="first">Changed from property access to Control attributes to function access
If your code was accessing properties of controls then this might be a
significant change! The main reasons for doing this were due to the
inheritability of properties (or lack there-of!) and the additional
scafolding that was required to define them all.</p>
</li>
<li><p class="first">Updated the <tt class="docutils literal"><span class="pre">DialogWrapper.MenuSelect()</span></tt> method to notify the parent
that it needs to initialize the menu&#8217;s before it retrieves the items</p>
</li>
<li><p class="first">Added functionality to associate &#8216;non-text&#8217; controls with the &#8216;text&#8217;
control closest to them. This allows controls to be referenced by:</p>
<div class="highlight-python"><pre>app.dlg.&lt;Nearby_text&gt;&lt;Window_class&gt;</pre>
</div>
<p>e.g. to reference the &#8220;Footer&#8221; edit control in the Page Setup dialog
you could use:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">PageSetup</span><span class="o">.</span><span class="n">FooterEdit</span>
</pre></div>
</div>
</li>
<li><p class="first">Added a MoveWindow method to HwndWrapper</p>
</li>
<li><p class="first">Did some more cleanup (fixing pylint warnings) but still not finished</p>
</li>
<li><p class="first">Added some better support for .NET controls (not to be considered final)</p>
</li>
</ul>
</div>
<div class="section" id="many-changes-few-visible">
<h2>0.1.3 Many changes, few visible<a class="headerlink" href="#many-changes-few-visible" title="Permalink to this headline"></a></h2>
<p>15-Jan-2006</p>
<ul>
<li><p class="first">Wrote doc strings for all modules, classes and functions</p>
</li>
<li><p class="first">Ran pychecker and pylint and fixed some errors/warning</p>
</li>
<li><p class="first">changed</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">_connect</span><span class="p">,</span> <span class="n">_start</span><span class="p">,</span> <span class="n">_window</span><span class="p">,</span> <span class="n">_control</span><span class="p">,</span> <span class="n">_write</span>
</pre></div>
</div>
<p>respectively to</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">connect_</span><span class="p">,</span> <span class="n">start_</span><span class="p">,</span> <span class="n">window_</span><span class="p">,</span> <span class="n">connect_</span><span class="p">,</span> <span class="n">write_</span>
</pre></div>
</div>
<p>If you forget to change <tt class="docutils literal"><span class="pre">_window</span></tt>, <tt class="docutils literal"><span class="pre">_connect</span></tt> and <tt class="docutils literal"><span class="pre">_start</span></tt> then you will probably get the following error.</p>
<div class="highlight-python"><pre>TypeError: '_DynamicAttributes' object is not callable</pre>
</div>
</li>
<li><p class="first">pywinauto is now a package name - you need to import it or its modules</p>
</li>
<li><p class="first">Changes to the code to deal with pywinauto package name</p>
</li>
<li><p class="first">Fixed searching for windows if a Parent is passed in</p>
</li>
<li><p class="first">Added Index to retrieved MenuItem dictionary</p>
</li>
<li><p class="first">Added a check to ensure that a windows Handle is a valid window</p>
</li>
<li><p class="first">Refactored some of the methods in common_controls</p>
</li>
<li><p class="first">Refactored how FriendlyClassName is discovered (and still not really happy!</p>
</li>
</ul>
</div>
<div class="section" id="add-readme-and-rollup-various-changes">
<h2>0.1.2 Add Readme and rollup various changes<a class="headerlink" href="#add-readme-and-rollup-various-changes" title="Permalink to this headline"></a></h2>
<p>15-Jan-2006</p>
<ul class="simple">
<li>Updated Readme (original readme was incorrect)</li>
<li>Added clipboard module</li>
<li>Fixed DrawOutline part of tests.__init__.print_bugs</li>
<li>Added a NotifyParent to HwndWrapper</li>
<li>Make sure that HwndWrapper.ref is initialized to None</li>
<li>Refactored some methods of ComboBox and ListBox</li>
<li>Updated Combo/ListBox selection methods</li>
<li>Removed hardcoded paths from test_application.py</li>
<li>Added section to save the document as UTF-8 in MinimalNotepadTest</li>
<li>Fixed EscapeSpecials and UnEscapeSpecials in XMLHelpers</li>
<li>Made sure that overly large bitmaps do not break XML writing</li>
</ul>
</div>
<div class="section" id="minor-bug-fix-release">
<h2>0.1.1 Minor bug fix release<a class="headerlink" href="#minor-bug-fix-release" title="Permalink to this headline"></a></h2>
<p>12-Jan-2006</p>
<ul class="simple">
<li>Fixed some minor bugs discovered after release</li>
</ul>
</div>
<div class="section" id="initial-release">
<h2>0.1.0 Initial Release<a class="headerlink" href="#initial-release" title="Permalink to this headline"></a></h2>
<p>6-Jan-2006</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="contents.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Change Log</a><ul>
<li><a class="reference internal" href="#various-cleanup-and-bug-fixes">0.4.0 Various cleanup and bug fixes.</a></li>
<li><a class="reference internal" href="#experimental-new-sendkeys-and-various-fixes">0.3.9 Experimental! New Sendkeys, and various fixes</a></li>
<li><a class="reference internal" href="#collecting-improvements-from-last-2-years">0.3.8 Collecting improvements from last 2 years</a></li>
<li><a class="reference internal" href="#merge-of-wait-changes-and-various-bug-fixes-improvements">0.3.7 Merge of Wait changes and various bug fixes/improvements</a></li>
<li><a class="reference internal" href="#b-changes-not-documented-in-0-3-6-history">0.3.6b Changes not documented in 0.3.6 history</a></li>
<li><a class="reference internal" href="#scrolling-and-treview-item-clicking-added">0.3.6 Scrolling and Treview Item Clicking added</a></li>
<li><a class="reference internal" href="#moved-to-metaclass-control-wrapping">0.3.5 Moved to Metaclass control wrapping</a></li>
<li><a class="reference internal" href="#fixed-issue-with-latest-ctypes-speed-gains-other-changes">0.3.4 Fixed issue with latest ctypes, speed gains, other changes</a></li>
<li><a class="reference internal" href="#added-some-methods-and-fixed-some-small-bugs">0.3.3 Added some methods, and fixed some small bugs</a></li>
<li><a class="reference internal" href="#fixed-setup-py-and-some-typos">0.3.2 Fixed setup.py and some typos</a></li>
<li><a class="reference internal" href="#performance-tune-ups">0.3.1 Performance tune-ups</a></li>
<li><a class="reference internal" href="#added-application-data-now-useful-for-localization-testing">0.3.0 Added Application data - now useful for localization testing</a></li>
<li><a class="reference internal" href="#more-refactoring-more-tests">0.2.5 More refactoring, more tests</a></li>
<li><a class="reference internal" href="#small-release-number-big-changes">0.2.1 Small Release number - big changes</a></li>
<li><a class="reference internal" href="#significant-refactoring">0.2.0 Significant refactoring</a></li>
<li><a class="reference internal" href="#many-changes-few-visible">0.1.3 Many changes, few visible</a></li>
<li><a class="reference internal" href="#add-readme-and-rollup-various-changes">0.1.2 Add Readme and rollup various changes</a></li>
<li><a class="reference internal" href="#minor-bug-fix-release">0.1.1 Minor bug fix release</a></li>
<li><a class="reference internal" href="#initial-release">0.1.0 Initial Release</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="TODO.html"
title="previous chapter">PYWINAUTO TODO&#8217;s</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="code/code.html"
title="next chapter">Main user modules</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/HISTORY.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="code/code.html" title="Main user modules"
>next</a> |</li>
<li class="right" >
<a href="TODO.html" title="PYWINAUTO TODOs"
>previous</a> |</li>
<li><a href="contents.html">pywinauto 0.4.2 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010, Mark Mc Mahon.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

@ -1,567 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>How Tos &mdash; pywinauto 0.4.2 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.4.2',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="pywinauto 0.4.2 documentation" href="index.html" />
<link rel="next" title="Methods available to each different control type" href="controls_overview.html" />
<link rel="prev" title="Automating an application" href="getting_started.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="controls_overview.html" title="Methods available to each different control type"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="getting_started.html" title="Automating an application"
accesskey="P">previous</a> |</li>
<li><a href="contents.html">pywinauto 0.4.2 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="how-to-s">
<h1>How To&#8217;s<a class="headerlink" href="#how-to-s" title="Permalink to this headline"></a></h1>
<div class="section" id="how-to-sepcify-an-usable-application-instance">
<h2>How to sepcify an usable Application instance<a class="headerlink" href="#how-to-sepcify-an-usable-application-instance" title="Permalink to this headline"></a></h2>
<p>An <tt class="docutils literal"><span class="pre">Application()</span></tt> instance is the point of contact for all work
with the app you are automating. So the Application instance needs
to be connected to a process. There are two ways of doing this:</p>
<blockquote>
<div><div class="highlight-python"><pre>start_(self, cmd_line, timeout = app_start_timeout):</pre>
</div>
</div></blockquote>
<p>or:</p>
<blockquote>
<div><div class="highlight-python"><pre>connect_(self, **kwargs):</pre>
</div>
</div></blockquote>
<p><tt class="docutils literal"><span class="pre">start_()</span></tt> is used when the application is not running and you
need to start it. Use it in the following way:</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">app</span> <span class="o">=</span> <span class="n">Application</span><span class="p">()</span>
<span class="n">app</span><span class="o">.</span><span class="n">start_</span><span class="p">(</span><span class="s">r&quot;c:\path\to\your\application -a -n -y --arguments&quot;</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p>The timeout parameter is optional, it should only be necessary to use
it if the application takes a long time to start up.</p>
<p><tt class="docutils literal"><span class="pre">connect_()</span></tt> is used when the application to be automated is already
running. To specify a an already runing application you need to specify
one of the following:</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">process:</th><td class="field-body"><p class="first">the process id of the application, e.g.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span> <span class="o">=</span> <span class="n">Application</span><span class="p">()</span>
<span class="n">app</span><span class="o">.</span><span class="n">connect_</span><span class="p">(</span><span class="n">process</span> <span class="o">=</span> <span class="mi">2341</span><span class="p">)</span>
</pre></div>
</div>
</td>
</tr>
<tr class="field-even field"><th class="field-name">handle:</th><td class="field-body"><p class="first">The windows handle of a window of the application, e.g.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span> <span class="o">=</span> <span class="n">Application</span><span class="p">()</span>
<span class="n">app</span><span class="o">.</span><span class="n">connect_</span><span class="p">(</span><span class="n">handle</span> <span class="o">=</span> <span class="mh">0x010f0c</span><span class="p">)</span>
</pre></div>
</div>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">path:</th><td class="field-body"><p class="first">The path of the executable of the process (<tt class="docutils literal"><span class="pre">GetModuleFileNameEx</span></tt>
is used to find the path of each process and compared against
the value passed in) e.g.</p>
<div class="last highlight-python"><div class="highlight"><pre><span class="n">app</span> <span class="o">=</span> <span class="n">Application</span><span class="p">()</span>
<span class="n">app</span><span class="o">.</span><span class="n">connect_</span><span class="p">(</span><span class="n">path</span> <span class="o">=</span> <span class="s">r&quot;c:\windows\system32\notepad.exe&quot;</span><span class="p">)</span>
</pre></div>
</div>
</td>
</tr>
</tbody>
</table>
<p>or any combination of the parameters that specify a window, these get
passed to the <tt class="docutils literal"><span class="pre">findwindows.find_windows()</span></tt> function. e.g.</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">app</span> <span class="o">=</span> <span class="n">Application</span><span class="p">()</span>
<span class="n">app</span><span class="o">.</span><span class="n">connect_</span><span class="p">(</span><span class="n">title_re</span> <span class="o">=</span> <span class="s">&quot;.*Notepad&quot;</span><span class="p">,</span> <span class="n">class_name</span> <span class="o">=</span> <span class="s">&quot;Notepad&quot;</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p><strong>Note</strong>: I have since added static methods Application.start() and
Application.connect() these can be used the same as above - except that
you no longer need to instantiate an Application object first.</p>
<p><strong>Note2</strong>: 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.</p>
</div>
<div class="section" id="how-to-sepcify-a-dialog-of-the-application">
<h2>How to sepcify a dialog of the application<a class="headerlink" href="#how-to-sepcify-a-dialog-of-the-application" title="Permalink to this headline"></a></h2>
<p>Once the application instance knows what application it is connected to
a dialog to work on needs to be specified.</p>
<p>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&#8217;s title. e.g</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">dlg</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">Notepad</span>
</pre></div>
</div>
</div></blockquote>
<p>or equivalently</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">dlg</span> <span class="o">=</span> <span class="n">app</span><span class="p">[</span><span class="s">&#39;Notepad&#39;</span><span class="p">]</span>
</pre></div>
</div>
</div></blockquote>
<p>The next easiest method is to ask for the <tt class="docutils literal"><span class="pre">top_window_()</span></tt> e.g.</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">dlg</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">top_window_</span><span class="p">()</span>
</pre></div>
</div>
</div></blockquote>
<p>This will return the window that has the highest Z-Order of the top-level
windows of the application.</p>
<p><strong>Note</strong>: 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.</p>
<p>If this is not enough control they you can use the same parameters as
can be passed to <tt class="docutils literal"><span class="pre">findwindows.find_windows()</span></tt> e.g.</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">dlg</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">window_</span><span class="p">(</span><span class="n">title_re</span> <span class="o">=</span> <span class="s">&quot;Page Setup&quot;</span><span class="p">,</span> <span class="n">class_name</span> <span class="o">=</span> <span class="s">&quot;#32770&quot;</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p>Finally to have the most control you can use</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">dialogs</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">windows_</span><span class="p">()</span>
</pre></div>
</div>
</div></blockquote>
<p>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 <tt class="docutils literal"><span class="pre">handleprops</span></tt>
module select the dialog you want. Once you have the handle you need
then use</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">Application</span><span class="o">.</span><span class="n">window_</span><span class="p">(</span><span class="n">handle</span> <span class="o">=</span> <span class="n">win</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p><strong>Note</strong>: 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</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">window_</span><span class="p">(</span><span class="n">title_re</span> <span class="o">=</span> <span class="s">&quot;.*Part of Title.*&quot;</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
</div>
<div class="section" id="how-to-specify-a-control-on-a-dialog">
<h2>How to specify a control on a dialog<a class="headerlink" href="#how-to-specify-a-control-on-a-dialog" title="Permalink to this headline"></a></h2>
<p>There are a number of ways to specify a control, the simplest are</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">dlg</span><span class="o">.</span><span class="n">control</span>
<span class="n">app</span><span class="p">[</span><span class="s">&#39;dlg&#39;</span><span class="p">][</span><span class="s">&#39;control&#39;</span><span class="p">]</span>
</pre></div>
</div>
</div></blockquote>
<p>The 2nd is better for non English OS&#8217;s where you need to pass unicode
strings e.g. app[u&#8217;your dlg title&#8217;][u&#8217;your ctrl title&#8217;]</p>
<p>The code builds up multiple identifiers for each control from the following:</p>
<blockquote>
<div><ul class="simple">
<li>title</li>
<li>friendly class</li>
<li>title + friendly class</li>
</ul>
</div></blockquote>
<p>If the control&#8217;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</p>
<blockquote>
<div><ul class="simple">
<li>friendly class</li>
<li>closest text + friendly class</li>
</ul>
</div></blockquote>
<p>Once a set of identifiers has been created for all controls in the dialog
we disambiguate them.</p>
<p>use the <cite>WindowSpecification.print_control_identifiers()</cite> method</p>
<dl class="docutils">
<dt>e.g.</dt>
<dd><div class="first last highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">YourDialog</span><span class="o">.</span><span class="n">print_control_identifiers</span><span class="p">()</span>
</pre></div>
</div>
</dd>
<dt>Sample output</dt>
<dd><div class="first last highlight-python"><pre>Button - Paper (L1075, T394, R1411, B485)
'PaperGroupBox' 'Paper' 'GroupBox'
Static - Si&amp;ze: (L1087, T420, R1141, B433)
'SizeStatic' 'Static' 'Size'
ComboBox - (L1159, T418, R1399, B439)
'ComboBox' 'SizeComboBox'
Static - &amp;Source: (L1087, T454, R1141, B467)
'Source' 'Static' 'SourceStatic'
ComboBox - (L1159, T449, R1399, B470)
'ComboBox' 'SourceComboBox'
Button - Orientation (L1075, T493, R1171, B584)
'GroupBox' 'Orientation' 'OrientationGroupBox'
Button - P&amp;ortrait (L1087, T514, R1165, B534)
'Portrait' 'RadioButton' 'PortraitRadioButton'
Button - L&amp;andscape (L1087, T548, R1165, B568)
'RadioButton' 'LandscapeRadioButton' 'Landscape'
Button - Margins (inches) (L1183, T493, R1411, B584)
'Marginsinches' 'MarginsinchesGroupBox' 'GroupBox'
Static - &amp;Left: (L1195, T519, R1243, B532)
'LeftStatic' 'Static' 'Left'
Edit - (L1243, T514, R1285, B534)
'Edit' 'LeftEdit'
Static - &amp;Right: (L1309, T519, R1357, B532)
'Right' 'Static' 'RightStatic'
Edit - (L1357, T514, R1399, B534)
'Edit' 'RightEdit'
Static - &amp;Top: (L1195, T550, R1243, B563)
'Top' 'Static' 'TopStatic'
Edit - (L1243, T548, R1285, B568)
'Edit' 'TopEdit'
Static - &amp;Bottom: (L1309, T550, R1357, B563)
'BottomStatic' 'Static' 'Bottom'
Edit - (L1357, T548, R1399, B568)
'Edit' 'BottomEdit'
Static - &amp;Header: (L1075, T600, R1119, B613)
'Header' 'Static' 'HeaderStatic'
Edit - (L1147, T599, R1408, B619)
'Edit' 'TopEdit'
Static - &amp;Footer: (L1075, T631, R1119, B644)
'FooterStatic' 'Static' 'Footer'
Edit - (L1147, T630, R1408, B650)
'Edit' 'FooterEdit'
Button - OK (L1348, T664, R1423, B687)
'Button' 'OK' 'OKButton'
Button - Cancel (L1429, T664, R1504, B687)
'Cancel' 'Button' 'CancelButton'
Button - &amp;Printer... (L1510, T664, R1585, B687)
'Button' 'Printer' 'PrinterButton'
Button - Preview (L1423, T394, R1585, B651)
'Preview' 'GroupBox' 'PreviewGroupBox'
Static - (L1458, T456, R1549, B586)
'PreviewStatic' 'Static'
Static - (L1549, T464, R1557, B594)
'PreviewStatic' 'Static'
Static - (L1466, T586, R1557, B594)
'Static' 'BottomStatic'</pre>
</div>
</dd>
</dl>
<p>This exmple has been taken from test_application.py</p>
<p><strong>Note</strong> The identifiers printed by this method have been run through
the process that makes the identifier unique. So if you have 2 edit boxes,
they will both have &#8220;Edit&#8221; listed in their identifiers. In reality though
the first one can be refered to as &#8220;Edit&#8221;, &#8220;Edit0&#8221;, &#8220;Edit1&#8221; and the 2nd
should be refered to as &#8220;Edit2&#8221;</p>
<p><strong>Note</strong> You do not have to be exact!. Say we take an instance from the
example above</p>
<blockquote>
<div><div class="highlight-python"><pre>Button - Margins (inches) (L1183, T493, R1411, B584)
'Marginsinches' 'MarginsinchesGroupBox' 'GroupBox'</pre>
</div>
</div></blockquote>
<p>Let&#8217;s say that you don&#8217;t like any of these</p>
<blockquote>
<div><ul class="simple">
<li><tt class="docutils literal"><span class="pre">GroupBox</span></tt> - too generic, it could be any group box</li>
<li><tt class="docutils literal"><span class="pre">Marginsinches</span></tt> and <tt class="docutils literal"><span class="pre">MarginsinchesGroupBox</span></tt> - these just don&#8217;
look right, it would be nicer to leave out the &#8216;inches&#8217; part</li>
</ul>
</div></blockquote>
<p>Well you CAN! The code does a best match on the identifer you use against
all the available identifiers in the dialog.</p>
<p>For example if you break into the debugger you can see how different
identifiers can be used</p>
<blockquote>
<div><div class="highlight-python"><pre>(Pdb) print app.PageSetup.Margins.Text()
Margins (inches)
(Pdb) print app.PageSetup.MarginsGroupBox.Text()
Margins (inches)</pre>
</div>
</div></blockquote>
<p>And this will also cater for typos. Though you still have to be careful
as if there are 2 similar identifiers in the dialog the typo you have
used might be more similar to another control then the one you were
thinking of.</p>
</div>
<div class="section" id="how-to-use-pywinauto-with-application-languages-other-than-english">
<h2>How to use pywinauto with application languages other than English<a class="headerlink" href="#how-to-use-pywinauto-with-application-languages-other-than-english" title="Permalink to this headline"></a></h2>
<p>Because Python does not support unicode identifiers in code
you cannot use attribute access to reference a control so
you would either have to use item access or make an explicit
calls to <tt class="docutils literal"><span class="pre">window_()</span></tt>.</p>
<p>So instead of writing</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">dialog_ident</span><span class="o">.</span><span class="n">control_ident</span><span class="o">.</span><span class="n">Click</span><span class="p">()</span>
</pre></div>
</div>
</div></blockquote>
<p>You would have to write</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="p">[</span><span class="s">&#39;dialog_ident&#39;</span><span class="p">][</span><span class="s">&#39;control_ident&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">Click</span><span class="p">()</span>
</pre></div>
</div>
</div></blockquote>
<p>Or use <tt class="docutils literal"><span class="pre">window_()</span></tt> explictly</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">window_</span><span class="p">(</span><span class="n">title_re</span> <span class="o">=</span> <span class="s">&quot;NonAsciiCharacters&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">window_</span><span class="p">(</span><span class="n">title</span> <span class="o">=</span> <span class="s">&quot;MoreNonAsciiCharacters&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">Click</span><span class="p">()</span>
</pre></div>
</div>
</div></blockquote>
<p>To see an example of this see <tt class="docutils literal"><span class="pre">examples\MiscExamples.py.GetInfo()</span></tt></p>
</div>
<div class="section" id="how-to-deal-with-controls-that-do-not-respond-as-expected-e-g-ownerdraw-controls">
<h2>How to deal with controls that do not respond as expected (e.g. OwnerDraw Controls)<a class="headerlink" href="#how-to-deal-with-controls-that-do-not-respond-as-expected-e-g-ownerdraw-controls" title="Permalink to this headline"></a></h2>
<p>Some controls (especially Ownerdrawn controls) do not respond to events as
expected. For example if you look at any HLP file and go to the Index Tab (click
&#8216;Search&#8217; button) you will see a listbox. Running Spy or Winspector on this
will show you that it is indeed a list box - but it is ownerdrawn. This means
that the developer has told Windows that they will override how items are displayed
and do it themselves. And in this case they have made it so that strings cannot be
retrieved :-(.</p>
<p>So what problems does this cause?</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">HelpTopics</span><span class="o">.</span><span class="n">ListBox</span><span class="o">.</span><span class="n">Texts</span><span class="p">()</span> <span class="c"># 1</span>
<span class="n">app</span><span class="o">.</span><span class="n">HelpTopics</span><span class="o">.</span><span class="n">ListBox</span><span class="o">.</span><span class="n">Select</span><span class="p">(</span><span class="s">&quot;ItemInList&quot;</span><span class="p">)</span> <span class="c"># 2</span>
</pre></div>
</div>
</div></blockquote>
<ol class="arabic simple">
<li>Will return a list of empty strings, all this means is that pywinauto has not
been able to get the strings in the listbox</li>
<li>This will fail with an IndexError because the Select(string) method of a ListBox
looks for the item in the Texts to know the index of the item that it should select.</li>
</ol>
<p>The following workaround will work on this control</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">HelpTopics</span><span class="o">.</span><span class="n">ListBox</span><span class="o">.</span><span class="n">Select</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p>This will select the 2nd item in the listbox, because it is not a string lookup
it works correctly.</p>
<p>Unfortunately not even this will always work. The developer can make it so that the
control does not respond to standard events like Select. In this case the only way
you can select items in the listbox is by using the keyboard simulation of TypeKeys().</p>
<p>This allows you to send any keystrokes to a control. So to select the 3rd item you
would use</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">Helptopics</span><span class="o">.</span><span class="n">ListBox1</span><span class="o">.</span><span class="n">TypeKeys</span><span class="p">(</span><span class="s">&quot;{HOME}{DOWN 2}{ENTER}&quot;</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">{HOME}</span></tt> will make sure that the first item is highlighted.</li>
<li><tt class="docutils literal"><span class="pre">{DOWN</span> <span class="pre">2}</span></tt> will then move the highlight down 2 items</li>
<li><tt class="docutils literal"><span class="pre">{ENTER}</span></tt> will select the highlighted item</li>
</ul>
<p>If your application made extensive use of a similar control type then you could
make using it easier by deriving a new class from ListBox, that could use extra
knowledge about your particular application. For example in the WinHelp example
evertime an item is highlighted in the list view, it&#8217;s text is inserted into the
Edit control above the list, and you CAN get the text of the item from there e.g.</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="c"># print the text of the item currently selected in the list box</span>
<span class="c"># (as long as you are not typing into the Edit control!)</span>
<span class="k">print</span> <span class="n">app</span><span class="o">.</span><span class="n">HelpTopics</span><span class="o">.</span><span class="n">Edit</span><span class="o">.</span><span class="n">Texts</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span>
</pre></div>
</div>
</div></blockquote>
</div>
<div class="section" id="how-to-access-the-system-tray-aka-systray-aka-notification-area">
<h2>How to Access the System Tray (aka SysTray, aka &#8216;Notification Area&#8217;)<a class="headerlink" href="#how-to-access-the-system-tray-aka-systray-aka-notification-area" title="Permalink to this headline"></a></h2>
<p>Near the clock are icons representing running applications, this area is
normally referred to as the &#8220;System Tray&#8221;. There are actually many different
windows/controls in this area. The control that contains the icons is actually
a toolbar. It is in a Pager control, in within a window with a class TrayNotifyWnd,
which is in yet another window with a class Shell_TrayWnd and all these windows
are part of the running Explorer instance. Thankfully you don&#8217;t need to remeber
all that :-).</p>
<p>The things that are important to remember is that you are looking for a
window in the &#8220;Explorer.exe&#8221; application with the class &#8220;Shell_TrayWnd&#8221; that has
a Toolbar control with a title &#8220;Notification Area&#8221;.</p>
<p>One way to get this is to do the following</p>
<blockquote>
<div><div class="highlight-python"><pre>imprt pywinauto.application
app = pywinauto.application.Application().connect_(path = "explorer")
systray_icons = app.ShellTrayWnd.NotificationAreaToolbar</pre>
</div>
</div></blockquote>
<p>The taskbar module provides very preliminary access to the System Tray.</p>
<p>It defines the following variables:</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">explorer_app:</th><td class="field-body">defines an Application() object connected to the running
explorer. You probably don&#8217;t need to use this your self
very much.</td>
</tr>
<tr class="field-even field"><th class="field-name">TaskBar:</th><td class="field-body">The handle to the task bar (the bar containing Start Button,
the QuickLaunch icons, running tasks, etc</td>
</tr>
<tr class="field-odd field"><th class="field-name">StartButton:</th><td class="field-body">&#8220;Start me up&#8221; :-) I think you might know what this is!</td>
</tr>
<tr class="field-even field"><th class="field-name">QuickLaunch:</th><td class="field-body">The Toolbar with the quick launch icons</td>
</tr>
<tr class="field-odd field"><th class="field-name">SystemTray:</th><td class="field-body">The window that contains the Clock and System Tray Icons</td>
</tr>
<tr class="field-even field"><th class="field-name">Clock:</th><td class="field-body">The clock</td>
</tr>
<tr class="field-odd field"><th class="field-name" colspan="2">SystemTrayIcons:</th></tr>
<tr class="field-odd field"><td>&nbsp;</td><td class="field-body">The toolbar representing the system tray icons</td>
</tr>
<tr class="field-even field"><th class="field-name" colspan="2">RunningApplications:</th></tr>
<tr class="field-even field"><td>&nbsp;</td><td class="field-body">The toolbar representing the running applications</td>
</tr>
</tbody>
</table>
<p>I have also provided 2 functions in the module that can be used to click on
system tray icons:</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name" colspan="2"><tt class="docutils literal"><span class="pre">ClickSystemTrayIcon(button)</span></tt>:</th></tr>
<tr class="field-odd field"><td>&nbsp;</td><td class="field-body">You can use this to left click a visible icon
in the system tray. I had to specifically say
visible icon as there may be many invisible
icons that obviously cannot be clicked. Button
can be any integer. If you specify 3 then it will
find and click the 3rd visible button. (very little
error checking is performed and this method will
more then likely be moved/renamed in the futures.</td>
</tr>
<tr class="field-even field"><th class="field-name" colspan="2"><tt class="docutils literal"><span class="pre">RightClickSystemTrayIcon(button)</span></tt>:</th></tr>
<tr class="field-even field"><td>&nbsp;</td><td class="field-body">Similar to <tt class="docutils literal"><span class="pre">ClickSytemTrayIcon</span></tt> but
performs a right click.</td>
</tr>
</tbody>
</table>
<p>Often when you click/right click on an icon - you get a popup menu. The thing to
remember at this point is that the popup menu is part of the application being
automated not part of explorer.</p>
<p>e.g.</p>
<blockquote>
<div><div class="highlight-python"><div class="highlight"><pre><span class="c"># connect to outlook</span>
<span class="n">outlook</span> <span class="o">=</span> <span class="n">Application</span><span class="p">()</span><span class="o">.</span><span class="n">connect_</span><span class="p">(</span><span class="n">path</span> <span class="o">=</span> <span class="s">&#39;outlook.exe&#39;</span><span class="p">)</span>
<span class="c"># click on Outlook&#39;s icon</span>
<span class="n">taskbar</span><span class="o">.</span><span class="n">ClickSystemTrayIcon</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="c"># Select an item in the popup menu</span>
<span class="n">outlook</span><span class="o">.</span><span class="n">PopupMenu</span><span class="o">.</span><span class="n">MenuClick</span><span class="p">(</span><span class="s">&quot;Cancel Server Request&quot;</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="contents.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">How To&#8217;s</a><ul>
<li><a class="reference internal" href="#how-to-sepcify-an-usable-application-instance">How to sepcify an usable Application instance</a></li>
<li><a class="reference internal" href="#how-to-sepcify-a-dialog-of-the-application">How to sepcify a dialog of the application</a></li>
<li><a class="reference internal" href="#how-to-specify-a-control-on-a-dialog">How to specify a control on a dialog</a></li>
<li><a class="reference internal" href="#how-to-use-pywinauto-with-application-languages-other-than-english">How to use pywinauto with application languages other than English</a></li>
<li><a class="reference internal" href="#how-to-deal-with-controls-that-do-not-respond-as-expected-e-g-ownerdraw-controls">How to deal with controls that do not respond as expected (e.g. OwnerDraw Controls)</a></li>
<li><a class="reference internal" href="#how-to-access-the-system-tray-aka-systray-aka-notification-area">How to Access the System Tray (aka SysTray, aka &#8216;Notification Area&#8217;)</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="getting_started.html"
title="previous chapter">Automating an application</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="controls_overview.html"
title="next chapter">Methods available to each different control type</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/HowTo.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="controls_overview.html" title="Methods available to each different control type"
>next</a> |</li>
<li class="right" >
<a href="getting_started.html" title="Automating an application"
>previous</a> |</li>
<li><a href="contents.html">pywinauto 0.4.2 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010, Mark Mc Mahon.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

@ -1,294 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PYWINAUTO TODOs &mdash; pywinauto 0.4.2 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.4.2',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="pywinauto 0.4.2 documentation" href="index.html" />
<link rel="next" title="Change Log" href="HISTORY.html" />
<link rel="prev" title="Dev Notes" href="dev_notes.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="HISTORY.html" title="Change Log"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="dev_notes.html" title="Dev Notes"
accesskey="P">previous</a> |</li>
<li><a href="contents.html">pywinauto 0.4.2 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="pywinauto-todo-s">
<h1>PYWINAUTO TODO&#8217;s<a class="headerlink" href="#pywinauto-todo-s" title="Permalink to this headline"></a></h1>
<ul>
<li><p class="first">Make sure to add documentation strings for all undocumented methods/functions</p>
</li>
<li><p class="first">Check coverage of the tests and work to increase it.</p>
</li>
<li><p class="first">Add tests for SendInput click methods</p>
</li>
<li><p class="first">Implement findbestmatch using FuzzyDict.</p>
</li>
<li><p class="first">Find a way of doing application data in a better way. Currently if someone
even adds a call to print_control_identifiers() it will break the matching
algorithm!</p>
</li>
<li><p class="first">Need to move the checking if a control is a Ownerdrawn/bitmap control out
of __init__ methods and into it&#8217;s own method something like
IsNormallyRendered() (Why?)</p>
</li>
<li><p class="first">Give example how to work with Tray Window</p>
</li>
<li><p class="first">Fix ToolbarWrapper.PressButton() which doesn&#8217;t seem to work (found wile working
on IE example script)</p>
</li>
<li><p class="first">Maybe supply an option so that scripts can be run by using:</p>
<div class="highlight-python"><pre>pywinauto.exe yourscript.py</pre>
</div>
<p>This would work by creating a Py2exe wrapper that would import the script
(and optionally call a particular function?)</p>
<p>This way pywinauto could be made available to people without python
installed (whether this is a big requirement or not I don&#8217;t know
because the automation language is python anyway!.</p>
</li>
<li><p class="first">Message traps - how to handle unwanted message boxes popping up?</p>
<ol class="loweralpha simple">
<li>Wait for an Exception then handle it there</li>
<li>set a trap waiting for a specific dialog</li>
<li>on calls to window specification, if we fail to find our window then we can
run quickly through the available specified traps to see if any of them apply
- then if they do we can run the associated actions - then try our original
dialog again</li>
</ol>
</li>
<li><p class="first">Handle adding reference controls (in that they should be the controls used
for finding windows)</p>
</li>
<li><p class="first">Find the reference name of a variable e.g so that in Dialog._write() we
can know the variable name that called the _write on (this we don&#8217;t have
to repeat the XML file name!)</p>
</li>
<li><p class="first">If we remove the delay after a button click in controlactions then
trying to close two dialogs in a row might fail because the first
dialog hasn&#8217;t closed yet and the 2nd may have similar title and
same closing button e.g PageSetup.OK.Click(), PageSetup2.OK.Click().
A possible solution to this might be to keep a cache of windows in the
application and no two different dialog identifiers (PageSetup and PageSetup2
in this case) can have the same handle - so returning the handle of PageSetup
when we call PageSetup2 would fail (and we would do our usual waiting until
it succeeds or times out).</p>
</li>
<li><p class="first">Investigate using any of the following</p>
<blockquote>
<div><ul class="simple">
<li>BringWindowToTop: probably necessary before image capture</li>
<li>GetTopWindow: maybe to re-set top window after capture?</li>
<li>EnumThreadWindows</li>
<li>GetGUIThreadInfo</li>
</ul>
</div></blockquote>
</li>
<li><p class="first">Make it easy to work with context(right click) menu&#8217;s</p>
</li>
<li><p class="first">Further support .NET controls and download/create a test .NET application</p>
</li>
<li><p class="first">Look at supporting the Sytem Tray (e.g. right click on an icon)</p>
</li>
<li><p class="first">supply SystemTray class (singleton probably)</p>
</li>
<li><p class="first">Look at clicking and text input - maybe use SendInput</p>
</li>
<li><p class="first">Support Up-Down controls and other common controls</p>
</li>
<li><p class="first">Find out whether control.item.action() or control.action(item) is better</p>
</li>
<li><p class="first">Create a Recorder to visually create tests</p>
</li>
</ul>
<p><strong>LOW PRIORITY</strong></p>
<ul>
<li><p class="first">Create a class that makes it easy to deal with a single window (e.g. no
application)</p>
</li>
<li><p class="first">Allow apps to be started in a different thread so we don&#8217;t lock up</p>
<ul class="simple">
<li>this is being done already - the problem is that some messages cannot
be sent across processes if they have pointers (so we need to send a
synchronous message which waits for the other process to respond
before returning)</li>
<li>But I guess it would be possible to create a thread for sending
those messages?</li>
</ul>
</li>
<li><p class="first">Liberate the code from HwndWrapper - there is very little this add&#8217;s beyond
what is available in handleprops. The main reason this is required is for
the FriendlyClassName. So I need to look to see if this can be moved
elsewhere.</p>
<p>Doing this might flatten the heirarchy quite a bit and reduce the
dependencies on the various packages</p>
</li>
<li><p class="first">Need to make Menu items into classes so instead of Dlg.MenuSelect we should
be doing</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">dlg</span><span class="o">.</span><span class="n">Menu</span><span class="p">(</span><span class="s">&quot;blah-&gt;blah&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">Select</span><span class="p">()</span>
</pre></div>
</div>
<p>or even</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">dlg</span><span class="o">.</span><span class="n">Menu</span><span class="o">.</span><span class="n">Blah</span><span class="o">.</span><span class="n">Blah</span><span class="o">.</span><span class="n">Select</span><span class="p">()</span>
</pre></div>
</div>
</li>
</ul>
<blockquote>
<div><p>To do this we need to change how menu&#8217;s are retrieved - rather than get all
menuitems at the start - then we just get the requested level.</p>
<p>This would also enable things like</p>
<div class="highlight-python"><pre>dlg.Menu.Blah.Blah.IsChecked() IsEnabled(), etc</pre>
</div>
</div></blockquote>
<div class="section" id="closed-in-some-way-or-the-other">
<h2>CLOSED (in some way or the other)<a class="headerlink" href="#closed-in-some-way-or-the-other" title="Permalink to this headline"></a></h2>
<ul>
<li><p class="first">Allow delay after click to be removed. The main reason that this is needed
at the moment is because if you close a dialog and then try an action on
the parent immediately it may not yet be active - so the delay is
needed to allow it to become active.
To fix this we may need to add more magic around calling actions on dialogs
e.g.
on an attribute access for an ActionDialog do the following:</p>
<blockquote>
<div><ul class="simple">
<li>Check if it is an Action</li>
<li>If it is not enabled then wait a little bit</li>
<li>If it is then wait a little bit and try again</li>
<li>repeat that until success or timeout</li>
</ul>
</div></blockquote>
<p>The main thing that needs to be resolved is that you don&#8217;t want two of these
waits happening at once (so a wait in a function at 1 level, and another wait
in a function called by the other one - because this would mean there would
be a VERY long delay while the timeout of the nested function was reached
the number of times the calling func tried to succeed!)</p>
</li>
<li><p class="first">Add referencing by closest static (or surrounding group box?)</p>
</li>
<li><p class="first">Need to modularize the methods of the common_controls because at the moment
they are much too monolithic.</p>
</li>
<li><p class="first">Finish example of saving a page from IE</p>
</li>
<li><p class="first">Document that I have not been able to figure out how to reliably check
if a menu item is enabled or not before selecting it. (Probably FIXED NOW!)</p>
<p>For Example in Media Player if you try and click the View-&gt;Choose Columns
menu item when it is not enabled it crashes Media Player. Theoretically
MF_DISABLED and MF_GRAYED should be used - but I found that these are not
updated (at least for Media Player) until they are dropped down.</p>
</li>
<li><p class="first">Implement an opional timing/config module so that all timing can be
customized</p>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="contents.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">PYWINAUTO TODO&#8217;s</a><ul>
<li><a class="reference internal" href="#closed-in-some-way-or-the-other">CLOSED (in some way or the other)</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="dev_notes.html"
title="previous chapter">Dev Notes</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="HISTORY.html"
title="next chapter">Change Log</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/TODO.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="HISTORY.html" title="Change Log"
>next</a> |</li>
<li class="right" >
<a href="dev_notes.html" title="Dev Notes"
>previous</a> |</li>
<li><a href="contents.html">pywinauto 0.4.2 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2010, Mark Mc Mahon.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

@ -1,540 +0,0 @@
/*
* basic.css
* ~~~~~~~~~
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox input[type="text"] {
width: 170px;
}
div.sphinxsidebar #searchbox input[type="submit"] {
width: 30px;
}
img {
border: 0;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- general body styles --------------------------------------------------- */
a.headerlink {
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.field-list ul {
padding-left: 1em;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
img.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
background-color: #ffe;
width: 40%;
float: right;
}
p.sidebar-title {
font-weight: bold;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
border: 0;
border-collapse: collapse;
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.field-list td, table.field-list th {
border: 0 !important;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
dl {
margin-bottom: 15px;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dt:target, .highlighted {
background-color: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.refcount {
color: #060;
}
.optional {
font-size: 1.3em;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
tt.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
tt.descclassname {
background-color: transparent;
}
tt.xref, a tt {
background-color: transparent;
font-weight: bold;
}
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

@ -1,256 +0,0 @@
/*
* default.css_t
* ~~~~~~~~~~~~~
*
* Sphinx stylesheet -- default theme.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: sans-serif;
font-size: 100%;
background-color: #11303d;
color: #000;
margin: 0;
padding: 0;
}
div.document {
background-color: #1c4e63;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 230px;
}
div.body {
background-color: #ffffff;
color: #000000;
padding: 0 20px 30px 20px;
}
div.footer {
color: #ffffff;
width: 100%;
padding: 9px 0 9px 0;
text-align: center;
font-size: 75%;
}
div.footer a {
color: #ffffff;
text-decoration: underline;
}
div.related {
background-color: #133f52;
line-height: 30px;
color: #ffffff;
}
div.related a {
color: #ffffff;
}
div.sphinxsidebar {
}
div.sphinxsidebar h3 {
font-family: 'Trebuchet MS', sans-serif;
color: #ffffff;
font-size: 1.4em;
font-weight: normal;
margin: 0;
padding: 0;
}
div.sphinxsidebar h3 a {
color: #ffffff;
}
div.sphinxsidebar h4 {
font-family: 'Trebuchet MS', sans-serif;
color: #ffffff;
font-size: 1.3em;
font-weight: normal;
margin: 5px 0 0 0;
padding: 0;
}
div.sphinxsidebar p {
color: #ffffff;
}
div.sphinxsidebar p.topless {
margin: 5px 10px 10px 10px;
}
div.sphinxsidebar ul {
margin: 10px;
padding: 0;
color: #ffffff;
}
div.sphinxsidebar a {
color: #98dbcc;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
/* -- hyperlink styles ------------------------------------------------------ */
a {
color: #355f7c;
text-decoration: none;
}
a:visited {
color: #355f7c;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* -- body styles ----------------------------------------------------------- */
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: 'Trebuchet MS', sans-serif;
background-color: #f2f2f2;
font-weight: normal;
color: #20435c;
border-bottom: 1px solid #ccc;
margin: 20px -20px 10px -20px;
padding: 3px 0 3px 10px;
}
div.body h1 { margin-top: 0; font-size: 200%; }
div.body h2 { font-size: 160%; }
div.body h3 { font-size: 140%; }
div.body h4 { font-size: 120%; }
div.body h5 { font-size: 110%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
}
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
div.body p, div.body dd, div.body li {
text-align: justify;
line-height: 130%;
}
div.admonition p.admonition-title + p {
display: inline;
}
div.admonition p {
margin-bottom: 5px;
}
div.admonition pre {
margin-bottom: 5px;
}
div.admonition ul, div.admonition ol {
margin-bottom: 5px;
}
div.note {
background-color: #eee;
border: 1px solid #ccc;
}
div.seealso {
background-color: #ffc;
border: 1px solid #ff6;
}
div.topic {
background-color: #eee;
}
div.warning {
background-color: #ffe4e4;
border: 1px solid #f66;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre {
padding: 5px;
background-color: #eeffcc;
color: #333333;
line-height: 120%;
border: 1px solid #ac9;
border-left: none;
border-right: none;
}
tt {
background-color: #ecf0f3;
padding: 0 1px 0 1px;
font-size: 0.95em;
}
th {
background-color: #ede;
}
.warning tt {
background: #efc2c2;
}
.note tt {
background: #d6d6d6;
}
.viewcode-back {
font-family: sans-serif;
}
div.viewcode-block:target {
background-color: #f4debf;
border-top: 1px solid #ac9;
border-bottom: 1px solid #ac9;
}

@ -1,247 +0,0 @@
/*
* doctools.js
* ~~~~~~~~~~~
*
* Sphinx JavaScript utilities for all documentation.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* select a different prefix for underscore
*/
$u = _.noConflict();
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
"dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
"profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {};
}
*/
/**
* small helper function to urldecode strings
*/
jQuery.urldecode = function(x) {
return decodeURIComponent(x).replace(/\+/g, ' ');
}
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s == 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};
/**
* small function to check if an array contains
* a given item.
*/
jQuery.contains = function(arr, item) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == item)
return true;
}
return false;
};
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node) {
if (node.nodeType == 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
var span = document.createElement("span");
span.className = className;
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this);
});
}
}
return this.each(function() {
highlight(this);
});
};
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated == 'undefined')
return string;
return (typeof translated == 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated == 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
*/
addContextElements : function() {
$('div[id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
},
/**
* workaround a firefox stupidity
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlighted');
});
}, 10);
$('<p class="highlight-link"><a href="javascript:Documentation.' +
'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
.appendTo($('#searchbox'));
}
},
/**
* init the domain index toggle buttons
*/
initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) == 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('#searchbox .highlight-link').fadeOut(300);
$('span.highlighted').removeClass('highlighted');
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this == '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 B

@ -1,154 +0,0 @@
/*!
* jQuery JavaScript Library v1.4.2
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Sat Feb 13 22:33:48 2010 -0500
*/
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 B

@ -1,62 +0,0 @@
.highlight .hll { background-color: #ffffcc }
.highlight { background: #eeffcc; }
.highlight .c { color: #408090; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #007020; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #007020 } /* Comment.Preproc */
.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #333333 } /* Generic.Output */
.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0044DD } /* Generic.Traceback */
.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #007020 } /* Keyword.Pseudo */
.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #902000 } /* Keyword.Type */
.highlight .m { color: #208050 } /* Literal.Number */
.highlight .s { color: #4070a0 } /* Literal.String */
.highlight .na { color: #4070a0 } /* Name.Attribute */
.highlight .nb { color: #007020 } /* Name.Builtin */
.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.highlight .no { color: #60add5 } /* Name.Constant */
.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #007020 } /* Name.Exception */
.highlight .nf { color: #06287e } /* Name.Function */
.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #bb60d5 } /* Name.Variable */
.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #208050 } /* Literal.Number.Float */
.highlight .mh { color: #208050 } /* Literal.Number.Hex */
.highlight .mi { color: #208050 } /* Literal.Number.Integer */
.highlight .mo { color: #208050 } /* Literal.Number.Oct */
.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
.highlight .sc { color: #4070a0 } /* Literal.String.Char */
.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
.highlight .sx { color: #c65d09 } /* Literal.String.Other */
.highlight .sr { color: #235388 } /* Literal.String.Regex */
.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
.highlight .ss { color: #517918 } /* Literal.String.Symbol */
.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */

@ -1,560 +0,0 @@
/*
* searchtools.js_t
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilties for the full-text search.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
* words. the first one is used to find the occurance, the
* latter for highlighting it.
*/
jQuery.makeSearchSummary = function(text, keywords, hlwords) {
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
var i = textLower.indexOf(this.toLowerCase());
if (i > -1)
start = i;
});
start = Math.max(start - 120, 0);
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<div class="context"></div>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlighted');
});
return rv;
}
/**
* Porter Stemmer
*/
var Stemmer = function() {
var step2list = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
};
var step3list = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
};
var c = "[^aeiou]"; // consonant
var v = "[aeiouy]"; // vowel
var C = c + "[^aeiouy]*"; // consonant sequence
var V = v + "[aeiou]*"; // vowel sequence
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
var s_v = "^(" + C + ")?" + v; // vowel in stem
this.stemWord = function (w) {
var stem;
var suffix;
var firstch;
var origword = w;
if (w.length < 3)
return w;
var re;
var re2;
var re3;
var re4;
firstch = w.substr(0,1);
if (firstch == "y")
w = firstch.toUpperCase() + w.substr(1);
// Step 1a
re = /^(.+?)(ss|i)es$/;
re2 = /^(.+?)([^s])s$/;
if (re.test(w))
w = w.replace(re,"$1$2");
else if (re2.test(w))
w = w.replace(re2,"$1$2");
// Step 1b
re = /^(.+?)eed$/;
re2 = /^(.+?)(ed|ing)$/;
if (re.test(w)) {
var fp = re.exec(w);
re = new RegExp(mgr0);
if (re.test(fp[1])) {
re = /.$/;
w = w.replace(re,"");
}
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1];
re2 = new RegExp(s_v);
if (re2.test(stem)) {
w = stem;
re2 = /(at|bl|iz)$/;
re3 = new RegExp("([^aeiouylsz])\\1$");
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re2.test(w))
w = w + "e";
else if (re3.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
else if (re4.test(w))
w = w + "e";
}
}
// Step 1c
re = /^(.+?)y$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(s_v);
if (re.test(stem))
w = stem + "i";
}
// Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step2list[suffix];
}
// Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step3list[suffix];
}
// Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
re2 = /^(.+?)(s|t)(ion)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
if (re.test(stem))
w = stem;
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1] + fp[2];
re2 = new RegExp(mgr1);
if (re2.test(stem))
w = stem;
}
// Step 5
re = /^(.+?)e$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
re2 = new RegExp(meq1);
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
w = stem;
}
re = /ll$/;
re2 = new RegExp(mgr1);
if (re.test(w) && re2.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
// and turn initial Y back to y
if (firstch == "y")
w = firstch.toLowerCase() + w.substr(1);
return w;
}
}
/**
* Search Module
*/
var Search = {
_index : null,
_queued_query : null,
_pulse_status : -1,
init : function() {
var params = $.getQueryParameters();
if (params.q) {
var query = params.q[0];
$('input[name="q"]')[0].value = query;
this.performSearch(query);
}
},
loadIndex : function(url) {
$.ajax({type: "GET", url: url, data: null, success: null,
dataType: "script", cache: true});
},
setIndex : function(index) {
var q;
this._index = index;
if ((q = this._queued_query) !== null) {
this._queued_query = null;
Search.query(q);
}
},
hasIndex : function() {
return this._index !== null;
},
deferQuery : function(query) {
this._queued_query = query;
},
stopPulse : function() {
this._pulse_status = 0;
},
startPulse : function() {
if (this._pulse_status >= 0)
return;
function pulse() {
Search._pulse_status = (Search._pulse_status + 1) % 4;
var dotString = '';
for (var i = 0; i < Search._pulse_status; i++)
dotString += '.';
Search.dots.text(dotString);
if (Search._pulse_status > -1)
window.setTimeout(pulse, 500);
};
pulse();
},
/**
* perform a search for something
*/
performSearch : function(query) {
// create the required interface elements
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p style="display: none"></p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
this.startPulse();
// index already loaded, the browser was quick!
if (this.hasIndex())
this.query(query);
else
this.deferQuery(query);
},
query : function(query) {
var stopwords = ["and","then","into","it","as","are","in","if","for","no","there","their","was","is","be","to","that","but","they","not","such","with","by","a","on","these","of","will","this","near","the","or","at"];
// Stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = query.split(/\s+/);
var objectterms = [];
for (var i = 0; i < tmp.length; i++) {
if (tmp[i] != "") {
objectterms.push(tmp[i].toLowerCase());
}
if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) ||
tmp[i] == "") {
// skip this "word"
continue;
}
// stem the word
var word = stemmer.stemWord(tmp[i]).toLowerCase();
// select the correct list
if (word[0] == '-') {
var toAppend = excluded;
word = word.substr(1);
}
else {
var toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
}
// only add if not already in the list
if (!$.contains(toAppend, word))
toAppend.push(word);
};
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
// console.debug('SEARCH: searching for:');
// console.info('required: ', searchterms);
// console.info('excluded: ', excluded);
// prepare search
var filenames = this._index.filenames;
var titles = this._index.titles;
var terms = this._index.terms;
var fileMap = {};
var files = null;
// different result priorities
var importantResults = [];
var objectResults = [];
var regularResults = [];
var unimportantResults = [];
$('#search-progress').empty();
// lookup as object
for (var i = 0; i < objectterms.length; i++) {
var others = [].concat(objectterms.slice(0,i),
objectterms.slice(i+1, objectterms.length))
var results = this.performObjectSearch(objectterms[i], others);
// Assume first word is most likely to be the object,
// other words more likely to be in description.
// Therefore put matches for earlier words first.
// (Results are eventually used in reverse order).
objectResults = results[0].concat(objectResults);
importantResults = results[1].concat(importantResults);
unimportantResults = results[2].concat(unimportantResults);
}
// perform the search on the required terms
for (var i = 0; i < searchterms.length; i++) {
var word = searchterms[i];
// no match but word was a required one
if ((files = terms[word]) == null)
break;
if (files.length == undefined) {
files = [files];
}
// create the mapping
for (var j = 0; j < files.length; j++) {
var file = files[j];
if (file in fileMap)
fileMap[file].push(word);
else
fileMap[file] = [word];
}
}
// now check if the files don't contain excluded terms
for (var file in fileMap) {
var valid = true;
// check if all requirements are matched
if (fileMap[file].length != searchterms.length)
continue;
// ensure that none of the excluded terms is in the
// search result.
for (var i = 0; i < excluded.length; i++) {
if (terms[excluded[i]] == file ||
$.contains(terms[excluded[i]] || [], file)) {
valid = false;
break;
}
}
// if we have still a valid result we can add it
// to the result list
if (valid)
regularResults.push([filenames[file], titles[file], '', null]);
}
// delete unused variables in order to not waste
// memory until list is retrieved completely
delete filenames, titles, terms;
// now sort the regular results descending by title
regularResults.sort(function(a, b) {
var left = a[1].toLowerCase();
var right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
});
// combine all results
var results = unimportantResults.concat(regularResults)
.concat(objectResults).concat(importantResults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li style="display:none"></li>');
if (DOCUMENTATION_OPTIONS.FILE_SUFFIX == '') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
dirname = dirname.substring(0, dirname.length-6);
} else if (dirname == 'index/') {
dirname = '';
}
listItem.append($('<a/>').attr('href',
DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
highlightstring + item[2]).html(item[1]));
} else {
// normal html builders
listItem.append($('<a/>').attr('href',
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
highlightstring + item[2]).html(item[1]));
}
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
$.get(DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' +
item[0] + '.txt', function(data) {
if (data != '') {
listItem.append($.makeSearchSummary(data, searchterms, hlterms));
Search.output.append(listItem);
}
listItem.slideDown(5, function() {
displayNextItem();
});
}, "text");
} else {
// no source available, just display title
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount)
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
else
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
Search.status.fadeIn(500);
}
}
displayNextItem();
},
performObjectSearch : function(object, otherterms) {
var filenames = this._index.filenames;
var objects = this._index.objects;
var objnames = this._index.objnames;
var titles = this._index.titles;
var importantResults = [];
var objectResults = [];
var unimportantResults = [];
for (var prefix in objects) {
for (var name in objects[prefix]) {
var fullname = (prefix ? prefix + '.' : '') + name;
if (fullname.toLowerCase().indexOf(object) > -1) {
var match = objects[prefix][name];
var objname = objnames[match[1]][2];
var title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
if (otherterms.length > 0) {
var haystack = (prefix + ' ' + name + ' ' +
objname + ' ' + title).toLowerCase();
var allfound = true;
for (var i = 0; i < otherterms.length; i++) {
if (haystack.indexOf(otherterms[i]) == -1) {
allfound = false;
break;
}
}
if (!allfound) {
continue;
}
}
var descr = objname + _(', in ') + title;
anchor = match[3];
if (anchor == '')
anchor = fullname;
else if (anchor == '-')
anchor = objnames[match[1]][1] + '-' + fullname;
result = [filenames[match[0]], fullname, '#'+anchor, descr];
switch (match[2]) {
case 1: objectResults.push(result); break;
case 0: importantResults.push(result); break;
case 2: unimportantResults.push(result); break;
}
}
}
}
// sort results descending
objectResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
importantResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
unimportantResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
return [importantResults, objectResults, unimportantResults]
}
}
$(document).ready(function() {
Search.init();
});

@ -1,151 +0,0 @@
/*
* sidebar.js
* ~~~~~~~~~~
*
* This script makes the Sphinx sidebar collapsible.
*
* .sphinxsidebar contains .sphinxsidebarwrapper. This script adds
* in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton
* used to collapse and expand the sidebar.
*
* When the sidebar is collapsed the .sphinxsidebarwrapper is hidden
* and the width of the sidebar and the margin-left of the document
* are decreased. When the sidebar is expanded the opposite happens.
* This script saves a per-browser/per-session cookie used to
* remember the position of the sidebar among the pages.
* Once the browser is closed the cookie is deleted and the position
* reset to the default (expanded).
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
$(function() {
// global elements used by the functions.
// the 'sidebarbutton' element is defined as global after its
// creation, in the add_sidebar_button function
var bodywrapper = $('.bodywrapper');
var sidebar = $('.sphinxsidebar');
var sidebarwrapper = $('.sphinxsidebarwrapper');
// for some reason, the document has no sidebar; do not run into errors
if (!sidebar.length) return;
// original margin-left of the bodywrapper and width of the sidebar
// with the sidebar expanded
var bw_margin_expanded = bodywrapper.css('margin-left');
var ssb_width_expanded = sidebar.width();
// margin-left of the bodywrapper and width of the sidebar
// with the sidebar collapsed
var bw_margin_collapsed = '.8em';
var ssb_width_collapsed = '.8em';
// colors used by the current theme
var dark_color = $('.related').css('background-color');
var light_color = $('.document').css('background-color');
function sidebar_is_collapsed() {
return sidebarwrapper.is(':not(:visible)');
}
function toggle_sidebar() {
if (sidebar_is_collapsed())
expand_sidebar();
else
collapse_sidebar();
}
function collapse_sidebar() {
sidebarwrapper.hide();
sidebar.css('width', ssb_width_collapsed);
bodywrapper.css('margin-left', bw_margin_collapsed);
sidebarbutton.css({
'margin-left': '0',
'height': bodywrapper.height()
});
sidebarbutton.find('span').text('»');
sidebarbutton.attr('title', _('Expand sidebar'));
document.cookie = 'sidebar=collapsed';
}
function expand_sidebar() {
bodywrapper.css('margin-left', bw_margin_expanded);
sidebar.css('width', ssb_width_expanded);
sidebarwrapper.show();
sidebarbutton.css({
'margin-left': ssb_width_expanded-12,
'height': bodywrapper.height()
});
sidebarbutton.find('span').text('«');
sidebarbutton.attr('title', _('Collapse sidebar'));
document.cookie = 'sidebar=expanded';
}
function add_sidebar_button() {
sidebarwrapper.css({
'float': 'left',
'margin-right': '0',
'width': ssb_width_expanded - 28
});
// create the button
sidebar.append(
'<div id="sidebarbutton"><span>&laquo;</span></div>'
);
var sidebarbutton = $('#sidebarbutton');
light_color = sidebarbutton.css('background-color');
// find the height of the viewport to center the '<<' in the page
var viewport_height;
if (window.innerHeight)
viewport_height = window.innerHeight;
else
viewport_height = $(window).height();
sidebarbutton.find('span').css({
'display': 'block',
'margin-top': (viewport_height - sidebar.position().top - 20) / 2
});
sidebarbutton.click(toggle_sidebar);
sidebarbutton.attr('title', _('Collapse sidebar'));
sidebarbutton.css({
'color': '#FFFFFF',
'border-left': '1px solid ' + dark_color,
'font-size': '1.2em',
'cursor': 'pointer',
'height': bodywrapper.height(),
'padding-top': '1px',
'margin-left': ssb_width_expanded - 12
});
sidebarbutton.hover(
function () {
$(this).css('background-color', dark_color);
},
function () {
$(this).css('background-color', light_color);
}
);
}
function set_position_from_cookie() {
if (!document.cookie)
return;
var items = document.cookie.split(';');
for(var k=0; k<items.length; k++) {
var key_val = items[k].split('=');
var key = key_val[0];
if (key == 'sidebar') {
var value = key_val[1];
if ((value == 'collapsed') && (!sidebar_is_collapsed()))
collapse_sidebar();
else if ((value == 'expanded') && (sidebar_is_collapsed()))
expand_sidebar();
}
}
}
add_sidebar_button();
var sidebarbutton = $('#sidebarbutton');
set_position_from_cookie();
});

@ -1,23 +0,0 @@
// Underscore.js 0.5.5
// (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the terms of the MIT license.
// Portions of Underscore are inspired by or borrowed from Prototype.js,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore/
(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e<f;e++)c.call(d,
a[e],e,a);else{var g=b.keys(a);f=g.length;for(e=0;e<f;e++)c.call(d,a[g[e]],g[e],a)}}catch(h){if(h!=m)throw h;}return a};b.map=function(a,c,d){if(a&&b.isFunction(a.map))return a.map(c,d);var e=[];b.each(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(a&&b.isFunction(a.reduce))return a.reduce(b.bind(d,e),c);b.each(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(a&&b.isFunction(a.reduceRight))return a.reduceRight(b.bind(d,e),c);
var f=b.clone(b.toArray(a)).reverse();b.each(f,function(g,h){c=d.call(e,c,g,h,a)});return c};b.detect=function(a,c,d){var e;b.each(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.select=function(a,c,d){if(a&&b.isFunction(a.filter))return a.filter(c,d);var e=[];b.each(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];b.each(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.all=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.every))return a.every(c,
d);var e=true;b.each(a,function(f,g,h){(e=e&&c.call(d,f,g,h))||b.breakLoop()});return e};b.any=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.some))return a.some(c,d);var e=false;b.each(a,function(f,g,h){if(e=c.call(d,f,g,h))b.breakLoop()});return e};b.include=function(a,c){if(b.isArray(a))return b.indexOf(a,c)!=-1;var d=false;b.each(a,function(e){if(d=e===c)b.breakLoop()});return d};b.invoke=function(a,c){var d=b.rest(arguments,2);return b.map(a,function(e){return(c?e[c]:e).apply(e,d)})};b.pluck=
function(a,c){return b.map(a,function(d){return d[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,
function(e,f,g){return{value:e,criteria:c.call(d,e,f,g)}}).sort(function(e,f){e=e.criteria;f=f.criteria;return e<f?-1:e>f?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?(e=g+1):(f=g)}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return k.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=function(a,c,d){return c&&!d?k.call(a,
0,c):a[0]};b.rest=function(a,c,d){return k.call(a,b.isUndefined(c)||d?1:c)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.select(a,function(c){return!!c})};b.flatten=function(a){return b.reduce(a,[],function(c,d){if(b.isArray(d))return c.concat(b.flatten(d));c.push(d);return c})};b.without=function(a){var c=b.rest(arguments);return b.select(a,function(d){return!b.include(c,d)})};b.uniq=function(a,c){return b.reduce(a,[],function(d,e,f){if(0==f||(c===true?b.last(d)!=e:!b.include(d,
e)))d.push(e);return d})};b.intersect=function(a){var c=b.rest(arguments);return b.select(b.uniq(a),function(d){return b.all(c,function(e){return b.indexOf(e,d)>=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e<c;e++)d[e]=b.pluck(a,String(e));return d};b.indexOf=function(a,c){if(a.indexOf)return a.indexOf(c);for(var d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,c){if(a.lastIndexOf)return a.lastIndexOf(c);for(var d=
a.length;d--;)if(a[d]===c)return d;return-1};b.range=function(a,c,d){var e=b.toArray(arguments),f=e.length<=1;a=f?0:e[0];c=f?e[0]:e[1];d=e[2]||1;e=Math.ceil((c-a)/d);if(e<=0)return[];e=new Array(e);f=a;for(var g=0;1;f+=d){if((d>0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)});
return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length);
var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false;
if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length==
0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&&
a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g,
" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments);
o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 B

@ -1,808 +0,0 @@
/*
* websupport.js
* ~~~~~~~~~~~~~
*
* sphinx.websupport utilties for all documentation.
*
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
(function($) {
$.fn.autogrow = function() {
return this.each(function() {
var textarea = this;
$.fn.autogrow.resize(textarea);
$(textarea)
.focus(function() {
textarea.interval = setInterval(function() {
$.fn.autogrow.resize(textarea);
}, 500);
})
.blur(function() {
clearInterval(textarea.interval);
});
});
};
$.fn.autogrow.resize = function(textarea) {
var lineHeight = parseInt($(textarea).css('line-height'), 10);
var lines = textarea.value.split('\n');
var columns = textarea.cols;
var lineCount = 0;
$.each(lines, function() {
lineCount += Math.ceil(this.length / columns) || 1;
});
var height = lineHeight * (lineCount + 1);
$(textarea).css('height', height);
};
})(jQuery);
(function($) {
var comp, by;
function init() {
initEvents();
initComparator();
}
function initEvents() {
$('a.comment-close').live("click", function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
});
$('a.vote').live("click", function(event) {
event.preventDefault();
handleVote($(this));
});
$('a.reply').live("click", function(event) {
event.preventDefault();
openReply($(this).attr('id').substring(2));
});
$('a.close-reply').live("click", function(event) {
event.preventDefault();
closeReply($(this).attr('id').substring(2));
});
$('a.sort-option').live("click", function(event) {
event.preventDefault();
handleReSort($(this));
});
$('a.show-proposal').live("click", function(event) {
event.preventDefault();
showProposal($(this).attr('id').substring(2));
});
$('a.hide-proposal').live("click", function(event) {
event.preventDefault();
hideProposal($(this).attr('id').substring(2));
});
$('a.show-propose-change').live("click", function(event) {
event.preventDefault();
showProposeChange($(this).attr('id').substring(2));
});
$('a.hide-propose-change').live("click", function(event) {
event.preventDefault();
hideProposeChange($(this).attr('id').substring(2));
});
$('a.accept-comment').live("click", function(event) {
event.preventDefault();
acceptComment($(this).attr('id').substring(2));
});
$('a.delete-comment').live("click", function(event) {
event.preventDefault();
deleteComment($(this).attr('id').substring(2));
});
$('a.comment-markup').live("click", function(event) {
event.preventDefault();
toggleCommentMarkupBox($(this).attr('id').substring(2));
});
}
/**
* Set comp, which is a comparator function used for sorting and
* inserting comments into the list.
*/
function setComparator() {
// If the first three letters are "asc", sort in ascending order
// and remove the prefix.
if (by.substring(0,3) == 'asc') {
var i = by.substring(3);
comp = function(a, b) { return a[i] - b[i]; };
} else {
// Otherwise sort in descending order.
comp = function(a, b) { return b[by] - a[by]; };
}
// Reset link styles and format the selected sort option.
$('a.sel').attr('href', '#').removeClass('sel');
$('a.by' + by).removeAttr('href').addClass('sel');
}
/**
* Create a comp function. If the user has preferences stored in
* the sortBy cookie, use those, otherwise use the default.
*/
function initComparator() {
by = 'rating'; // Default to sort by rating.
// If the sortBy cookie is set, use that instead.
if (document.cookie.length > 0) {
var start = document.cookie.indexOf('sortBy=');
if (start != -1) {
start = start + 7;
var end = document.cookie.indexOf(";", start);
if (end == -1) {
end = document.cookie.length;
by = unescape(document.cookie.substring(start, end));
}
}
}
setComparator();
}
/**
* Show a comment div.
*/
function show(id) {
$('#ao' + id).hide();
$('#ah' + id).show();
var context = $.extend({id: id}, opts);
var popup = $(renderTemplate(popupTemplate, context)).hide();
popup.find('textarea[name="proposal"]').hide();
popup.find('a.by' + by).addClass('sel');
var form = popup.find('#cf' + id);
form.submit(function(event) {
event.preventDefault();
addComment(form);
});
$('#s' + id).after(popup);
popup.slideDown('fast', function() {
getComments(id);
});
}
/**
* Hide a comment div.
*/
function hide(id) {
$('#ah' + id).hide();
$('#ao' + id).show();
var div = $('#sc' + id);
div.slideUp('fast', function() {
div.remove();
});
}
/**
* Perform an ajax request to get comments for a node
* and insert the comments into the comments tree.
*/
function getComments(id) {
$.ajax({
type: 'GET',
url: opts.getCommentsURL,
data: {node: id},
success: function(data, textStatus, request) {
var ul = $('#cl' + id);
var speed = 100;
$('#cf' + id)
.find('textarea[name="proposal"]')
.data('source', data.source);
if (data.comments.length === 0) {
ul.html('<li>No comments yet.</li>');
ul.data('empty', true);
} else {
// If there are comments, sort them and put them in the list.
var comments = sortComments(data.comments);
speed = data.comments.length * 100;
appendComments(comments, ul);
ul.data('empty', false);
}
$('#cn' + id).slideUp(speed + 200);
ul.slideDown(speed);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem retrieving the comments.');
},
dataType: 'json'
});
}
/**
* Add a comment via ajax and insert the comment into the comment tree.
*/
function addComment(form) {
var node_id = form.find('input[name="node"]').val();
var parent_id = form.find('input[name="parent"]').val();
var text = form.find('textarea[name="comment"]').val();
var proposal = form.find('textarea[name="proposal"]').val();
if (text == '') {
showError('Please enter a comment.');
return;
}
// Disable the form that is being submitted.
form.find('textarea,input').attr('disabled', 'disabled');
// Send the comment to the server.
$.ajax({
type: "POST",
url: opts.addCommentURL,
dataType: 'json',
data: {
node: node_id,
parent: parent_id,
text: text,
proposal: proposal
},
success: function(data, textStatus, error) {
// Reset the form.
if (node_id) {
hideProposeChange(node_id);
}
form.find('textarea')
.val('')
.add(form.find('input'))
.removeAttr('disabled');
var ul = $('#cl' + (node_id || parent_id));
if (ul.data('empty')) {
$(ul).empty();
ul.data('empty', false);
}
insertComment(data.comment);
var ao = $('#ao' + node_id);
ao.find('img').attr({'src': opts.commentBrightImage});
if (node_id) {
// if this was a "root" comment, remove the commenting box
// (the user can get it back by reopening the comment popup)
$('#ca' + node_id).slideUp();
}
},
error: function(request, textStatus, error) {
form.find('textarea,input').removeAttr('disabled');
showError('Oops, there was a problem adding the comment.');
}
});
}
/**
* Recursively append comments to the main comment list and children
* lists, creating the comment tree.
*/
function appendComments(comments, ul) {
$.each(comments, function() {
var div = createCommentDiv(this);
ul.append($(document.createElement('li')).html(div));
appendComments(this.children, div.find('ul.comment-children'));
// To avoid stagnating data, don't store the comments children in data.
this.children = null;
div.data('comment', this);
});
}
/**
* After adding a new comment, it must be inserted in the correct
* location in the comment tree.
*/
function insertComment(comment) {
var div = createCommentDiv(comment);
// To avoid stagnating data, don't store the comments children in data.
comment.children = null;
div.data('comment', comment);
var ul = $('#cl' + (comment.node || comment.parent));
var siblings = getChildren(ul);
var li = $(document.createElement('li'));
li.hide();
// Determine where in the parents children list to insert this comment.
for(i=0; i < siblings.length; i++) {
if (comp(comment, siblings[i]) <= 0) {
$('#cd' + siblings[i].id)
.parent()
.before(li.html(div));
li.slideDown('fast');
return;
}
}
// If we get here, this comment rates lower than all the others,
// or it is the only comment in the list.
ul.append(li.html(div));
li.slideDown('fast');
}
function acceptComment(id) {
$.ajax({
type: 'POST',
url: opts.acceptCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
$('#cm' + id).fadeOut('fast');
$('#cd' + id).removeClass('moderate');
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem accepting the comment.');
}
});
}
function deleteComment(id) {
$.ajax({
type: 'POST',
url: opts.deleteCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
var div = $('#cd' + id);
if (data == 'delete') {
// Moderator mode: remove the comment and all children immediately
div.slideUp('fast', function() {
div.remove();
});
return;
}
// User mode: only mark the comment as deleted
div
.find('span.user-id:first')
.text('[deleted]').end()
.find('div.comment-text:first')
.text('[deleted]').end()
.find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
.remove();
var comment = div.data('comment');
comment.username = '[deleted]';
comment.text = '[deleted]';
div.data('comment', comment);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem deleting the comment.');
}
});
}
function showProposal(id) {
$('#sp' + id).hide();
$('#hp' + id).show();
$('#pr' + id).slideDown('fast');
}
function hideProposal(id) {
$('#hp' + id).hide();
$('#sp' + id).show();
$('#pr' + id).slideUp('fast');
}
function showProposeChange(id) {
$('#pc' + id).hide();
$('#hc' + id).show();
var textarea = $('#pt' + id);
textarea.val(textarea.data('source'));
$.fn.autogrow.resize(textarea[0]);
textarea.slideDown('fast');
}
function hideProposeChange(id) {
$('#hc' + id).hide();
$('#pc' + id).show();
var textarea = $('#pt' + id);
textarea.val('').removeAttr('disabled');
textarea.slideUp('fast');
}
function toggleCommentMarkupBox(id) {
$('#mb' + id).toggle();
}
/** Handle when the user clicks on a sort by link. */
function handleReSort(link) {
var classes = link.attr('class').split(/\s+/);
for (var i=0; i<classes.length; i++) {
if (classes[i] != 'sort-option') {
by = classes[i].substring(2);
}
}
setComparator();
// Save/update the sortBy cookie.
var expiration = new Date();
expiration.setDate(expiration.getDate() + 365);
document.cookie= 'sortBy=' + escape(by) +
';expires=' + expiration.toUTCString();
$('ul.comment-ul').each(function(index, ul) {
var comments = getChildren($(ul), true);
comments = sortComments(comments);
appendComments(comments, $(ul).empty());
});
}
/**
* Function to process a vote when a user clicks an arrow.
*/
function handleVote(link) {
if (!opts.voting) {
showError("You'll need to login to vote.");
return;
}
var id = link.attr('id');
if (!id) {
// Didn't click on one of the voting arrows.
return;
}
// If it is an unvote, the new vote value is 0,
// Otherwise it's 1 for an upvote, or -1 for a downvote.
var value = 0;
if (id.charAt(1) != 'u') {
value = id.charAt(0) == 'u' ? 1 : -1;
}
// The data to be sent to the server.
var d = {
comment_id: id.substring(2),
value: value
};
// Swap the vote and unvote links.
link.hide();
$('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
.show();
// The div the comment is displayed in.
var div = $('div#cd' + d.comment_id);
var data = div.data('comment');
// If this is not an unvote, and the other vote arrow has
// already been pressed, unpress it.
if ((d.value !== 0) && (data.vote === d.value * -1)) {
$('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
$('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
}
// Update the comments rating in the local data.
data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
data.vote = d.value;
div.data('comment', data);
// Change the rating text.
div.find('.rating:first')
.text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
// Send the vote information to the server.
$.ajax({
type: "POST",
url: opts.processVoteURL,
data: d,
error: function(request, textStatus, error) {
showError('Oops, there was a problem casting that vote.');
}
});
}
/**
* Open a reply form used to reply to an existing comment.
*/
function openReply(id) {
// Swap out the reply link for the hide link
$('#rl' + id).hide();
$('#cr' + id).show();
// Add the reply li to the children ul.
var div = $(renderTemplate(replyTemplate, {id: id})).hide();
$('#cl' + id)
.prepend(div)
// Setup the submit handler for the reply form.
.find('#rf' + id)
.submit(function(event) {
event.preventDefault();
addComment($('#rf' + id));
closeReply(id);
})
.find('input[type=button]')
.click(function() {
closeReply(id);
});
div.slideDown('fast', function() {
$('#rf' + id).find('textarea').focus();
});
}
/**
* Close the reply form opened with openReply.
*/
function closeReply(id) {
// Remove the reply div from the DOM.
$('#rd' + id).slideUp('fast', function() {
$(this).remove();
});
// Swap out the hide link for the reply link
$('#cr' + id).hide();
$('#rl' + id).show();
}
/**
* Recursively sort a tree of comments using the comp comparator.
*/
function sortComments(comments) {
comments.sort(comp);
$.each(comments, function() {
this.children = sortComments(this.children);
});
return comments;
}
/**
* Get the children comments from a ul. If recursive is true,
* recursively include childrens' children.
*/
function getChildren(ul, recursive) {
var children = [];
ul.children().children("[id^='cd']")
.each(function() {
var comment = $(this).data('comment');
if (recursive)
comment.children = getChildren($(this).find('#cl' + comment.id), true);
children.push(comment);
});
return children;
}
/** Create a div to display a comment in. */
function createCommentDiv(comment) {
if (!comment.displayed && !opts.moderator) {
return $('<div class="moderate">Thank you! Your comment will show up '
+ 'once it is has been approved by a moderator.</div>');
}
// Prettify the comment rating.
comment.pretty_rating = comment.rating + ' point' +
(comment.rating == 1 ? '' : 's');
// Make a class (for displaying not yet moderated comments differently)
comment.css_class = comment.displayed ? '' : ' moderate';
// Create a div for this comment.
var context = $.extend({}, opts, comment);
var div = $(renderTemplate(commentTemplate, context));
// If the user has voted on this comment, highlight the correct arrow.
if (comment.vote) {
var direction = (comment.vote == 1) ? 'u' : 'd';
div.find('#' + direction + 'v' + comment.id).hide();
div.find('#' + direction + 'u' + comment.id).show();
}
if (opts.moderator || comment.text != '[deleted]') {
div.find('a.reply').show();
if (comment.proposal_diff)
div.find('#sp' + comment.id).show();
if (opts.moderator && !comment.displayed)
div.find('#cm' + comment.id).show();
if (opts.moderator || (opts.username == comment.username))
div.find('#dc' + comment.id).show();
}
return div;
}
/**
* A simple template renderer. Placeholders such as <%id%> are replaced
* by context['id'] with items being escaped. Placeholders such as <#id#>
* are not escaped.
*/
function renderTemplate(template, context) {
var esc = $(document.createElement('div'));
function handle(ph, escape) {
var cur = context;
$.each(ph.split('.'), function() {
cur = cur[this];
});
return escape ? esc.text(cur || "").html() : cur;
}
return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
return handle(arguments[2], arguments[1] == '%' ? true : false);
});
}
/** Flash an error message briefly. */
function showError(message) {
$(document.createElement('div')).attr({'class': 'popup-error'})
.append($(document.createElement('div'))
.attr({'class': 'error-message'}).text(message))
.appendTo('body')
.fadeIn("slow")
.delay(2000)
.fadeOut("slow");
}
/** Add a link the user uses to open the comments popup. */
$.fn.comment = function() {
return this.each(function() {
var id = $(this).attr('id').substring(1);
var count = COMMENT_METADATA[id];
var title = count + ' comment' + (count == 1 ? '' : 's');
var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
var addcls = count == 0 ? ' nocomment' : '';
$(this)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-open' + addcls,
id: 'ao' + id
})
.append($(document.createElement('img')).attr({
src: image,
alt: 'comment',
title: title
}))
.click(function(event) {
event.preventDefault();
show($(this).attr('id').substring(2));
})
)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-close hidden',
id: 'ah' + id
})
.append($(document.createElement('img')).attr({
src: opts.closeCommentImage,
alt: 'close',
title: 'close'
}))
.click(function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
})
);
});
};
var opts = {
processVoteURL: '/_process_vote',
addCommentURL: '/_add_comment',
getCommentsURL: '/_get_comments',
acceptCommentURL: '/_accept_comment',
deleteCommentURL: '/_delete_comment',
commentImage: '/static/_static/comment.png',
closeCommentImage: '/static/_static/comment-close.png',
loadingImage: '/static/_static/ajax-loader.gif',
commentBrightImage: '/static/_static/comment-bright.png',
upArrow: '/static/_static/up.png',
downArrow: '/static/_static/down.png',
upArrowPressed: '/static/_static/up-pressed.png',
downArrowPressed: '/static/_static/down-pressed.png',
voting: false,
moderator: false
};
if (typeof COMMENT_OPTIONS != "undefined") {
opts = jQuery.extend(opts, COMMENT_OPTIONS);
}
var popupTemplate = '\
<div class="sphinx-comments" id="sc<%id%>">\
<p class="sort-options">\
Sort by:\
<a href="#" class="sort-option byrating">best rated</a>\
<a href="#" class="sort-option byascage">newest</a>\
<a href="#" class="sort-option byage">oldest</a>\
</p>\
<div class="comment-header">Comments</div>\
<div class="comment-loading" id="cn<%id%>">\
loading comments... <img src="<%loadingImage%>" alt="" /></div>\
<ul id="cl<%id%>" class="comment-ul"></ul>\
<div id="ca<%id%>">\
<p class="add-a-comment">Add a comment\
(<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
<div class="comment-markup-box" id="mb<%id%>">\
reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
<tt>``code``</tt>, \
code blocks: <tt>::</tt> and an indented block after blank line</div>\
<form method="post" id="cf<%id%>" class="comment-form" action="">\
<textarea name="comment" cols="80"></textarea>\
<p class="propose-button">\
<a href="#" id="pc<%id%>" class="show-propose-change">\
Propose a change &#9657;\
</a>\
<a href="#" id="hc<%id%>" class="hide-propose-change">\
Propose a change &#9663;\
</a>\
</p>\
<textarea name="proposal" id="pt<%id%>" cols="80"\
spellcheck="false"></textarea>\
<input type="submit" value="Add comment" />\
<input type="hidden" name="node" value="<%id%>" />\
<input type="hidden" name="parent" value="" />\
</form>\
</div>\
</div>';
var commentTemplate = '\
<div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
<div class="vote">\
<div class="arrow">\
<a href="#" id="uv<%id%>" class="vote" title="vote up">\
<img src="<%upArrow%>" />\
</a>\
<a href="#" id="uu<%id%>" class="un vote" title="vote up">\
<img src="<%upArrowPressed%>" />\
</a>\
</div>\
<div class="arrow">\
<a href="#" id="dv<%id%>" class="vote" title="vote down">\
<img src="<%downArrow%>" id="da<%id%>" />\
</a>\
<a href="#" id="du<%id%>" class="un vote" title="vote down">\
<img src="<%downArrowPressed%>" />\
</a>\
</div>\
</div>\
<div class="comment-content">\
<p class="tagline comment">\
<span class="user-id"><%username%></span>\
<span class="rating"><%pretty_rating%></span>\
<span class="delta"><%time.delta%></span>\
</p>\
<div class="comment-text comment"><#text#></div>\
<p class="comment-opts comment">\
<a href="#" class="reply hidden" id="rl<%id%>">reply &#9657;</a>\
<a href="#" class="close-reply" id="cr<%id%>">reply &#9663;</a>\
<a href="#" id="sp<%id%>" class="show-proposal">proposal &#9657;</a>\
<a href="#" id="hp<%id%>" class="hide-proposal">proposal &#9663;</a>\
<a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
<span id="cm<%id%>" class="moderation hidden">\
<a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
</span>\
</p>\
<pre class="proposal" id="pr<%id%>">\
<#proposal_diff#>\
</pre>\
<ul class="comment-children" id="cl<%id%>"></ul>\
</div>\
<div class="clearleft"></div>\
</div>\
</div>';
var replyTemplate = '\
<li>\
<div class="reply-div" id="rd<%id%>">\
<form id="rf<%id%>">\
<textarea name="comment" cols="80"></textarea>\
<input type="submit" value="Add reply" />\
<input type="button" value="Cancel" />\
<input type="hidden" name="parent" value="<%id%>" />\
<input type="hidden" name="node" value="" />\
</form>\
</div>\
</li>';
$(document).ready(function() {
init();
});
})(jQuery);
$(document).ready(function() {
// add comment anchors for all paragraphs that are commentable
$('.sphinx-has-comment').comment();
// highlight search words in search results
$("div.context").each(function() {
var params = $.getQueryParameters();
var terms = (params.q) ? params.q[0].split(/\s+/) : [];
var result = $(this);
$.each(terms, function() {
result.highlightText(this.toLowerCase(), 'highlighted');
});
});
// directly open comment window if requested
var anchor = document.location.hash;
if (anchor.substring(0, 9) == '#comment-') {
$('#ao' + anchor.substring(9)).click();
document.location.hash = '#s' + anchor.substring(9);
}
});

@ -1,747 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>pywinauto.controls.HwndWrapper &mdash; pywinauto v0.3.9 documentation</title>
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.3.9',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="top" title="pywinauto v0.3.9 documentation" href="../index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="../contents.html">pywinauto v0.3.9 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="pywinauto-controls-hwndwrapper">
<h1>pywinauto.controls.HwndWrapper<a class="headerlink" href="#pywinauto-controls-hwndwrapper" title="Permalink to this headline"></a></h1>
<blockquote>
<span class="target" id="module-pywinauto.controls.HwndWrapper"></span><p>Basic wrapping of Windows controls</p>
<dl class="exception">
<dt id="pywinauto.controls.HwndWrapper.ControlNotEnabled">
<em class="property">exception </em><tt class="descclassname">pywinauto.controls.HwndWrapper.</tt><tt class="descname">ControlNotEnabled</tt><a class="headerlink" href="#pywinauto.controls.HwndWrapper.ControlNotEnabled" title="Permalink to this definition"></a></dt>
<dd><p>Raised when a control is not enabled</p>
</dd></dl>
<dl class="exception">
<dt id="pywinauto.controls.HwndWrapper.ControlNotVisible">
<em class="property">exception </em><tt class="descclassname">pywinauto.controls.HwndWrapper.</tt><tt class="descname">ControlNotVisible</tt><a class="headerlink" href="#pywinauto.controls.HwndWrapper.ControlNotVisible" title="Permalink to this definition"></a></dt>
<dd><p>Raised when a control is nto visible</p>
</dd></dl>
<dl class="function">
<dt id="pywinauto.controls.HwndWrapper.GetDialogPropsFromHandle">
<tt class="descclassname">pywinauto.controls.HwndWrapper.</tt><tt class="descname">GetDialogPropsFromHandle</tt><big>(</big><em>hwnd</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.GetDialogPropsFromHandle" title="Permalink to this definition"></a></dt>
<dd><p>Get the properties of all the controls as a list of dictionaries</p>
</dd></dl>
<dl class="class">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper">
<em class="property">class </em><tt class="descclassname">pywinauto.controls.HwndWrapper.</tt><tt class="descname">HwndWrapper</tt><big>(</big><em>hwnd</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper" title="Permalink to this definition"></a></dt>
<dd><p>Default wrapper for controls.</p>
<p>All other wrappers are derived from this.</p>
<p>This class wraps a lot of functionality of underlying windows API
features for working with windows.</p>
<p>Most of the methods apply to every single window type. For example
you can Click() on any window.</p>
<p>Most of the methods of this class are simple wrappers around
API calls and as such they try do the simplest thing possible.</p>
<p>A HwndWrapper object can be passed directly to a ctypes wrapped
C function - and it will get converted to a Long with the value of
it&#8217;s handle (see ctypes, _as_parameter_)</p>
<p>Initialize the control</p>
<ul class="simple">
<li><strong>hwnd</strong> is either a valid window handle or it can be an
instance or subclass of HwndWrapper.</li>
</ul>
<p>If the handle is not valid then an InvalidWindowHandle error
is raised.</p>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.CaptureAsImage">
<tt class="descname">CaptureAsImage</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.CaptureAsImage" title="Permalink to this definition"></a></dt>
<dd><p>Return a PIL image of the control</p>
<p>See PIL documentation to know what you can do with the resulting
image</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Children">
<tt class="descname">Children</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Children" title="Permalink to this definition"></a></dt>
<dd><p>Return the children of this control as a list</p>
<p>It returns a list of HwndWrapper (or subclass) instances, it
returns an empty list if there are no children.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Class">
<tt class="descname">Class</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Class" title="Permalink to this definition"></a></dt>
<dd><p>Return the class name of the window</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Click">
<tt class="descname">Click</tt><big>(</big><em>button='left'</em>, <em>pressed=''</em>, <em>coords=(0</em>, <em>0)</em>, <em>double=False</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Click" title="Permalink to this definition"></a></dt>
<dd><p>Simulates a mouse click on the control</p>
<p>This method sends WM_* messages to the control, to do a more
&#8216;realistic&#8217; mouse click use ClickInput() which uses SendInput() API
to perform the click.</p>
<p>This method does not require that the control be visible on the screen
(i.e. is can be hidden beneath another window and it will still work.)</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.ClickInput">
<tt class="descname">ClickInput</tt><big>(</big><em>button='left'</em>, <em>coords=(None</em>, <em>None)</em>, <em>double=False</em>, <em>wheel_dist=0</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.ClickInput" title="Permalink to this definition"></a></dt>
<dd><p>Click at the specified coordinates</p>
<ul class="simple">
<li><strong>button</strong> The mouse button to click. One of &#8216;left&#8217;, &#8216;right&#8217;,
&#8216;middle&#8217; or &#8216;x&#8217; (Default: &#8216;left&#8217;)</li>
<li><strong>coords</strong> The coordinates to click at.(Default: center of control)</li>
<li><strong>double</strong> Whether to perform a double click or not (Default: False)</li>
<li><strong>wheel_dist</strong> The distance to move the mouse week (default: 0)</li>
</ul>
<dl class="docutils">
<dt>NOTES: </dt>
<dd><p class="first">This is different from Click in that it requires the control to
be visible on the screen but performs a more realistic &#8216;click&#8217;
simulation.</p>
<p class="last">This method is also vulnerable if the mouse if moved by the user
as that could easily move the mouse off the control before the
Click has finished.</p>
</dd>
</dl>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.ClientRect">
<tt class="descname">ClientRect</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.ClientRect" title="Permalink to this definition"></a></dt>
<dd><p>Returns the client rectangle of window</p>
<p>The client rectangle is the window rectangle minus any borders that
are not available to the control for drawing.</p>
<p>Both top and left are always 0 for this method.</p>
<p>This method returns a RECT structure, Which has attributes - top,
left, right, bottom. and has methods width() and height().
See win32structures.RECT for more information.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.ClientRects">
<tt class="descname">ClientRects</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.ClientRects" title="Permalink to this definition"></a></dt>
<dd><p>Return the client rect for each item in this control</p>
<p>It is a list of rectangles for the control. It is frequently over-ridden
to extract all rectangles from a control with multiple items.</p>
<p>It is always a list with one or more rectangles:</p>
<blockquote>
<ul class="simple">
<li>First elemtent is the client rectangle of the control</li>
<li>Subsequent elements contain the client rectangle of any items of
the control (e.g. items in a listbox/combobox, tabs in a
tabcontrol)</li>
</ul>
</blockquote>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Close">
<tt class="descname">Close</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Close" title="Permalink to this definition"></a></dt>
<dd><p>Close the window</p>
<p>Code modified from <a class="reference external" href="http://msdn.microsoft.com/msdnmag/issues/02/08/CQA/">http://msdn.microsoft.com/msdnmag/issues/02/08/CQA/</a></p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.CloseClick">
<tt class="descname">CloseClick</tt><big>(</big><em>button='left'</em>, <em>pressed=''</em>, <em>coords=(0</em>, <em>0)</em>, <em>double=False</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.CloseClick" title="Permalink to this definition"></a></dt>
<dd><p>Peform a click action that should make the window go away</p>
<p>The only difference from Click is that there are extra delays
before and after the click action.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.ContextHelpID">
<tt class="descname">ContextHelpID</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.ContextHelpID" title="Permalink to this definition"></a></dt>
<dd><p>Return the Context Help ID of the window</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.ControlCount">
<tt class="descname">ControlCount</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.ControlCount" title="Permalink to this definition"></a></dt>
<dd><p>Return the number of children of this control</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.ControlID">
<tt class="descname">ControlID</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.ControlID" title="Permalink to this definition"></a></dt>
<dd><p>Return the ID of the window</p>
<p>Only controls have a valid ID - dialogs usually have no ID assigned.</p>
<p>The ID usually identified the control in the window - but there can
be duplicate ID&#8217;s for example lables in a dialog may have duplicate
ID&#8217;s.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.DebugMessage">
<tt class="descname">DebugMessage</tt><big>(</big><em>text</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.DebugMessage" title="Permalink to this definition"></a></dt>
<dd><p>Write some debug text over the window</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.DoubleClick">
<tt class="descname">DoubleClick</tt><big>(</big><em>button='left'</em>, <em>pressed=''</em>, <em>coords=(0</em>, <em>0)</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.DoubleClick" title="Permalink to this definition"></a></dt>
<dd><p>Perform a double click action</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.DoubleClickInput">
<tt class="descname">DoubleClickInput</tt><big>(</big><em>button='left'</em>, <em>coords=(None</em>, <em>None)</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.DoubleClickInput" title="Permalink to this definition"></a></dt>
<dd><p>Double click at the specified coordinates</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.DragMouse">
<tt class="descname">DragMouse</tt><big>(</big><em>button='left'</em>, <em>pressed=''</em>, <em>press_coords=(0</em>, <em>0)</em>, <em>release_coords=(0</em>, <em>0)</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.DragMouse" title="Permalink to this definition"></a></dt>
<dd><p>Drag the mouse</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.DrawOutline">
<tt class="descname">DrawOutline</tt><big>(</big><em>colour='green'</em>, <em>thickness=2</em>, <em>fill=1</em>, <em>rect=None</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.DrawOutline" title="Permalink to this definition"></a></dt>
<dd><p>Draw an outline around the window</p>
<ul class="simple">
<li><strong>colour</strong> can be either an integer or one of &#8216;red&#8217;, &#8216;green&#8217;, &#8216;blue&#8217;
(default &#8216;green&#8217;)</li>
<li><strong>thickness</strong> thickness of rectangle (default 2)</li>
<li><strong>fill</strong> how to fill in the rectangle (default BS_NULL)</li>
<li><strong>rect</strong> the coordinates of the rectangle to draw (defaults to
the rectangle of the control.</li>
</ul>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.ExStyle">
<tt class="descname">ExStyle</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.ExStyle" title="Permalink to this definition"></a></dt>
<dd><p>Returns the Extended style of window</p>
<p>Return value is a long.</p>
<p>Combination of WS_* and specific control specific styles.
See HwndWrapper.HasStyle() to easily check if the window has a
particular style.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Font">
<tt class="descname">Font</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Font" title="Permalink to this definition"></a></dt>
<dd><p>Return the font of the window</p>
<p>The font of the window is used to draw the text of that window.
It is a structure which has attributes for Font name, height, width
etc.</p>
<p>See win32structures.LOGFONTW for more information.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Fonts">
<tt class="descname">Fonts</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Fonts" title="Permalink to this definition"></a></dt>
<dd><p>Return the font for each item in this control</p>
<p>It is a list of fonts for the control. It is frequently over-ridden
to extract all fonts from a control with multiple items.</p>
<p>It is always a list with one or more fonts:</p>
<blockquote>
<ul class="simple">
<li>First elemtent is the control font</li>
<li>Subsequent elements contain the font of any items of
the control (e.g. items in a listbox/combobox, tabs in a
tabcontrol)</li>
</ul>
</blockquote>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.FriendlyClassName">
<tt class="descname">FriendlyClassName</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.FriendlyClassName" title="Permalink to this definition"></a></dt>
<dd><p>Return the friendly class name for the control</p>
<p>This differs from the class of the control in some cases.
Class() is the actual &#8216;Registered&#8217; window class of the control
while FriendlyClassName() is hopefully something that will make
more sense to the user.</p>
<p>For example Checkboxes are implemented as Buttons - so the class
of a CheckBox is &#8220;Button&#8221; - but the friendly class is &#8220;CheckBox&#8221;</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.GetFocus">
<tt class="descname">GetFocus</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.GetFocus" title="Permalink to this definition"></a></dt>
<dd><p>Return the control in the process of this window that has the Focus</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.GetProperties">
<tt class="descname">GetProperties</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.GetProperties" title="Permalink to this definition"></a></dt>
<dd><p>Return the properties of the control as a dictionary</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.GetShowState">
<tt class="descname">GetShowState</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.GetShowState" title="Permalink to this definition"></a></dt>
<dd><p>Get the show state and Maximized/minimzed/restored state</p>
<p>Returns a value that is a union of the following</p>
<ul class="simple">
<li>SW_HIDE the window is hidden.</li>
<li>SW_MAXIMIZE the window is maximized</li>
<li>SW_MINIMIZE the window is minimized</li>
<li>SW_RESTORE the window is in the &#8216;restored&#8217;
state (neither minimized or maximized)</li>
<li>SW_SHOW The window is not hidden</li>
</ul>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.HasExStyle">
<tt class="descname">HasExStyle</tt><big>(</big><em>exstyle</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.HasExStyle" title="Permalink to this definition"></a></dt>
<dd><p>Return True if the control has the specified extended sytle</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.HasStyle">
<tt class="descname">HasStyle</tt><big>(</big><em>style</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.HasStyle" title="Permalink to this definition"></a></dt>
<dd><p>Return True if the control has the specified sytle</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.IsChild">
<tt class="descname">IsChild</tt><big>(</big><em>parent</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.IsChild" title="Permalink to this definition"></a></dt>
<dd><p>Return True if this window is a child of &#8216;parent&#8217;.</p>
<p>A window is a child of another window when it is a direct of the
other window. A window is a direct descendant of a given
window if the parent window is the the chain of parent windows
for the child window.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.IsDialog">
<tt class="descname">IsDialog</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.IsDialog" title="Permalink to this definition"></a></dt>
<dd><p>Return true if the control is a top level window</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.IsEnabled">
<tt class="descname">IsEnabled</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.IsEnabled" title="Permalink to this definition"></a></dt>
<dd><p>Whether the window is enabled or not</p>
<p>Checks that both the Top Level Parent (probably dialog) that
owns this window and the window itself are both enabled.</p>
<p>If you want to wait for a control to become enabled (or wait
for it to become disabled) use <tt class="docutils literal"><span class="pre">Application.Wait('visible')</span></tt> or
<tt class="docutils literal"><span class="pre">Application.WaitNot('visible')</span></tt>.</p>
<p>If you want to raise an exception immediately if a window is
not enabled then you can use the HwndWrapper.VerifyEnabled().
HwndWrapper.VerifyReady() raises if the window is not both
visible and enabled.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.IsUnicode">
<tt class="descname">IsUnicode</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.IsUnicode" title="Permalink to this definition"></a></dt>
<dd><p>Whether the window is unicode or not</p>
<p>A window is Unicode if it was registered by the Wide char version
of RegisterClass(Ex).</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.IsVisible">
<tt class="descname">IsVisible</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.IsVisible" title="Permalink to this definition"></a></dt>
<dd><p>Whether the window is visible or not</p>
<p>Checks that both the Top Level Parent (probably dialog) that
owns this window and the window itself are both visible.</p>
<p>If you want to wait for a control to become visible (or wait
for it to become hidden) use <tt class="docutils literal"><span class="pre">Application.Wait('visible')</span></tt> or
<tt class="docutils literal"><span class="pre">Application.WaitNot('visible')</span></tt>.</p>
<p>If you want to raise an exception immediately if a window is
not visible then you can use the HwndWrapper.VerifyVisible().
HwndWrapper.VerifyActionable() raises if the window is not both
visible and enabled.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Maximize">
<tt class="descname">Maximize</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Maximize" title="Permalink to this definition"></a></dt>
<dd><p>Maximize the window</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Menu">
<tt class="descname">Menu</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Menu" title="Permalink to this definition"></a></dt>
<dd><p>Return the menu of the control</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.MenuItem">
<tt class="descname">MenuItem</tt><big>(</big><em>path</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.MenuItem" title="Permalink to this definition"></a></dt>
<dd><p>Return the menu item specifed by path</p>
<p>Path can be a string in the form &#8220;MenuItem-&gt;MenuItem-&gt;MenuItem...&#8221;
where each MenuItem is the text of an item at that level of the menu.
E.g.</p>
<div class="highlight-python"><pre>File-&gt;Export-&gt;ExportAsPNG</pre>
</div>
<p>spaces are not important so you could also have written...</p>
<div class="highlight-python"><pre>File -&gt; Export -&gt; Export As PNG</pre>
</div>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.MenuItems">
<tt class="descname">MenuItems</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.MenuItems" title="Permalink to this definition"></a></dt>
<dd><p>Return the menu items for the dialog</p>
<p>If there are no menu items then return an empty list</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.MenuSelect">
<tt class="descname">MenuSelect</tt><big>(</big><em>path</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.MenuSelect" title="Permalink to this definition"></a></dt>
<dd><p>Select the menuitem specifed in path</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Minimize">
<tt class="descname">Minimize</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Minimize" title="Permalink to this definition"></a></dt>
<dd><p>Minimize the window</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.MoveMouse">
<tt class="descname">MoveMouse</tt><big>(</big><em>pressed='left'</em>, <em>coords=(0</em>, <em>0)</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.MoveMouse" title="Permalink to this definition"></a></dt>
<dd><p>Move the mouse</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.MoveWindow">
<tt class="descname">MoveWindow</tt><big>(</big><em>x=None</em>, <em>y=None</em>, <em>width=None</em>, <em>height=None</em>, <em>repaint=True</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.MoveWindow" title="Permalink to this definition"></a></dt>
<dd><p>Move the window to the new coordinates</p>
<ul class="simple">
<li><strong>x</strong> Specifies the new left position of the window.
Defaults to the current left position of the window.</li>
<li><strong>y</strong> Specifies the new top position of the window.
Defaults to the current top position of the window.</li>
<li><strong>width</strong> Specifies the new width of the window. Defaults to the
current width of the window.</li>
<li><strong>height</strong> Specifies the new height of the window. Default to the
current height of the window.</li>
<li><strong>repaint</strong> Whether the window should be repainted or not.
Defaults to True</li>
</ul>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.NotifyParent">
<tt class="descname">NotifyParent</tt><big>(</big><em>message</em>, <em>controlID=None</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.NotifyParent" title="Permalink to this definition"></a></dt>
<dd><p>Send the notification message to parent of this control</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Owner">
<tt class="descname">Owner</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Owner" title="Permalink to this definition"></a></dt>
<dd><p>Return the owner window for the window if it exists</p>
<p>Returns None if there is no owner</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Parent">
<tt class="descname">Parent</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Parent" title="Permalink to this definition"></a></dt>
<dd><p>Return the parent of this control</p>
<p>Note that the parent of a control is not necesarily a dialog or
other main window. A group box may be the parent of some radio
buttons for example.</p>
<p>To get the main (or top level) window then use
HwndWrapper.TopLevelParent().</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.PopupWindow">
<tt class="descname">PopupWindow</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.PopupWindow" title="Permalink to this definition"></a></dt>
<dd><p>Return any owned Popups</p>
<p>Please do not use in production code yet - not tested fully</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.PostMessage">
<tt class="descname">PostMessage</tt><big>(</big><em>message</em>, <em>wparam=0</em>, <em>lparam=0</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.PostMessage" title="Permalink to this definition"></a></dt>
<dd><p>Post a message to the control message queue and return</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.PressMouse">
<tt class="descname">PressMouse</tt><big>(</big><em>button='left'</em>, <em>pressed=''</em>, <em>coords=(0</em>, <em>0)</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.PressMouse" title="Permalink to this definition"></a></dt>
<dd><p>Press the mouse button</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.PressMouseInput">
<tt class="descname">PressMouseInput</tt><big>(</big><em>button='left'</em>, <em>coords=(None</em>, <em>None)</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.PressMouseInput" title="Permalink to this definition"></a></dt>
<dd><p>Press a mouse button using SendInput</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.ProcessID">
<tt class="descname">ProcessID</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.ProcessID" title="Permalink to this definition"></a></dt>
<dd><p>Return the ID of process that owns this window</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Rectangle">
<tt class="descname">Rectangle</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Rectangle" title="Permalink to this definition"></a></dt>
<dd><p>Return the rectangle of window</p>
<p>The rectangle is the rectangle of the control on the screen,
coordinates are given from the top left of the screen.</p>
<p>This method returns a RECT structure, Which has attributes - top,
left, right, bottom. and has methods width() and height().
See win32structures.RECT for more information.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.ReleaseMouse">
<tt class="descname">ReleaseMouse</tt><big>(</big><em>button='left'</em>, <em>pressed=''</em>, <em>coords=(0</em>, <em>0)</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.ReleaseMouse" title="Permalink to this definition"></a></dt>
<dd><p>Release the mouse button</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.ReleaseMouseInput">
<tt class="descname">ReleaseMouseInput</tt><big>(</big><em>button='left'</em>, <em>coords=(None</em>, <em>None)</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.ReleaseMouseInput" title="Permalink to this definition"></a></dt>
<dd><p>Release the mouse button</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Restore">
<tt class="descname">Restore</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Restore" title="Permalink to this definition"></a></dt>
<dd><p>Restore the window</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.RightClick">
<tt class="descname">RightClick</tt><big>(</big><em>pressed=''</em>, <em>coords=(0</em>, <em>0)</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.RightClick" title="Permalink to this definition"></a></dt>
<dd><p>Perform a right click action</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.RightClickInput">
<tt class="descname">RightClickInput</tt><big>(</big><em>coords=(None</em>, <em>None)</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.RightClickInput" title="Permalink to this definition"></a></dt>
<dd><p>Right click at the specified coords</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Scroll">
<tt class="descname">Scroll</tt><big>(</big><em>direction</em>, <em>amount</em>, <em>count=1</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Scroll" title="Permalink to this definition"></a></dt>
<dd><p>Ask the control to scroll itself</p>
<p>direction can be any of &#8220;up&#8221;, &#8220;down&#8221;, &#8220;left&#8221;, &#8220;right&#8221;
amount can be one of &#8220;line&#8221;, &#8220;page&#8221;, &#8220;end&#8221;
count (optional) the number of times to scroll</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.SendMessage">
<tt class="descname">SendMessage</tt><big>(</big><em>message</em>, <em>wparam=0</em>, <em>lparam=0</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.SendMessage" title="Permalink to this definition"></a></dt>
<dd><p>Send a message to the control and wait for it to return</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.SendMessageTimeout">
<tt class="descname">SendMessageTimeout</tt><big>(</big><em>message</em>, <em>wparam=0</em>, <em>lparam=0</em>, <em>timeout=None</em>, <em>timeoutflags=0</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.SendMessageTimeout" title="Permalink to this definition"></a></dt>
<dd><p>Send a message to the control and wait for it to return or to timeout</p>
<p>If no timeout is given then a default timeout of .4 of a second will
be used.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.SetApplicationData">
<tt class="descname">SetApplicationData</tt><big>(</big><em>appdata</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.SetApplicationData" title="Permalink to this definition"></a></dt>
<dd><p>Application data is data from a previous run of the software</p>
<p>It is essential for running scripts written for one spoke language
on a different spoken langauge</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.SetFocus">
<tt class="descname">SetFocus</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.SetFocus" title="Permalink to this definition"></a></dt>
<dd><p>Set the focus to this control</p>
<p>Bring the window to the foreground first if necessary.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.SetWindowText">
<tt class="descname">SetWindowText</tt><big>(</big><em>text</em>, <em>append=False</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.SetWindowText" title="Permalink to this definition"></a></dt>
<dd><p>Set the text of the window</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Style">
<tt class="descname">Style</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Style" title="Permalink to this definition"></a></dt>
<dd><p>Returns the style of window</p>
<p>Return value is a long.</p>
<p>Combination of WS_* and specific control specific styles.
See HwndWrapper.HasStyle() to easily check if the window has a
particular style.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.Texts">
<tt class="descname">Texts</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.Texts" title="Permalink to this definition"></a></dt>
<dd><p>Return the text for each item of this control&#8221;</p>
<p>It is a list of strings for the control. It is frequently over-ridden
to extract all strings from a control with multiple items.</p>
<p>It is always a list with one or more strings:</p>
<blockquote>
<ul class="simple">
<li>First elemtent is the window text of the control</li>
<li>Subsequent elements contain the text of any items of the
control (e.g. items in a listbox/combobox, tabs in a tabcontrol)</li>
</ul>
</blockquote>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.TopLevelParent">
<tt class="descname">TopLevelParent</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.TopLevelParent" title="Permalink to this definition"></a></dt>
<dd><p>Return the top level window of this control</p>
<p>The TopLevel parent is different from the parent in that the Parent
is the window that owns this window - but it may not be a dialog/main
window. For example most Comboboxes have an Edit. The ComboBox is the
parent of the Edit control.</p>
<p>This will always return a valid window handle (if the control has
no top level parent then the control itself is returned - as it is
a top level window already!)</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.TypeKeys">
<tt class="descname">TypeKeys</tt><big>(</big><em>keys</em>, <em>pause=None</em>, <em>with_spaces=False</em>, <em>with_tabs=False</em>, <em>with_newlines=False</em>, <em>turn_off_numlock=True</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.TypeKeys" title="Permalink to this definition"></a></dt>
<dd><p>Type keys to the window using SendKeys</p>
<p>This uses the SendKeys python module from
<a class="reference external" href="http://www.rutherfurd.net/python/sendkeys/">http://www.rutherfurd.net/python/sendkeys/</a> .This is the best place
to find documentation on what to use for the <tt class="docutils literal"><span class="pre">keys</span></tt></p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.UserData">
<tt class="descname">UserData</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.UserData" title="Permalink to this definition"></a></dt>
<dd><p>Extra data associted with the window</p>
<p>This value is a long value that has been associated with the window
and rarely has useful data (or at least data that you know the use
of).</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.VerifyActionable">
<tt class="descname">VerifyActionable</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.VerifyActionable" title="Permalink to this definition"></a></dt>
<dd><p>Verify that the control is both visible and enabled</p>
<p>Raise either ControlNotEnalbed or ControlNotVisible if not
enabled or visible respectively.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.VerifyEnabled">
<tt class="descname">VerifyEnabled</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.VerifyEnabled" title="Permalink to this definition"></a></dt>
<dd><p>Verify that the control is enabled</p>
<p>Check first if the control&#8217;s parent is enabled (skip if no parent),
then check if control itself is enabled.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.VerifyVisible">
<tt class="descname">VerifyVisible</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.VerifyVisible" title="Permalink to this definition"></a></dt>
<dd><p>Verify that the control is visible</p>
<p>Check first if the control&#8217;s parent is visible. (skip if no parent),
then check if control itself is visible.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.controls.HwndWrapper.HwndWrapper.WindowText">
<tt class="descname">WindowText</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.HwndWrapper.WindowText" title="Permalink to this definition"></a></dt>
<dd><p>Window text of the control</p>
<p>Quite a few contorls have other text that is visible, for example
Edit controls usually have an empty string for WindowText but still
have text displayed in the edit window.</p>
</dd></dl>
</dd></dl>
<dl class="exception">
<dt id="pywinauto.controls.HwndWrapper.InvalidWindowHandle">
<em class="property">exception </em><tt class="descclassname">pywinauto.controls.HwndWrapper.</tt><tt class="descname">InvalidWindowHandle</tt><big>(</big><em>hwnd</em><big>)</big><a class="headerlink" href="#pywinauto.controls.HwndWrapper.InvalidWindowHandle" title="Permalink to this definition"></a></dt>
<dd><p>Raised when an invalid handle is passed to HwndWrapper</p>
<p>Initialise the RuntimError parent with the mesage</p>
</dd></dl>
</blockquote>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/code/HwndWrapper.py.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="../contents.html">pywinauto v0.3.9 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Mark Mc Mahon.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.5.
</div>
</body>
</html>

@ -1,117 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>pywinauto.XMLHelpers &mdash; pywinauto v0.3.9 documentation</title>
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.3.9',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="top" title="pywinauto v0.3.9 documentation" href="../index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="../contents.html">pywinauto v0.3.9 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="pywinauto-xmlhelpers">
<h1>pywinauto.XMLHelpers<a class="headerlink" href="#pywinauto-xmlhelpers" title="Permalink to this headline"></a></h1>
<blockquote>
<span class="target" id="module-pywinauto.XMLHelpers"></span><p>Module containing operations for reading and writing dialogs as XML</p>
<dl class="function">
<dt id="pywinauto.XMLHelpers.ReadPropertiesFromFile">
<tt class="descclassname">pywinauto.XMLHelpers.</tt><tt class="descname">ReadPropertiesFromFile</tt><big>(</big><em>filename</em><big>)</big><a class="headerlink" href="#pywinauto.XMLHelpers.ReadPropertiesFromFile" title="Permalink to this definition"></a></dt>
<dd><p>Return an list of controls from XML file filename</p>
</dd></dl>
<dl class="function">
<dt id="pywinauto.XMLHelpers.WriteDialogToFile">
<tt class="descclassname">pywinauto.XMLHelpers.</tt><tt class="descname">WriteDialogToFile</tt><big>(</big><em>filename</em>, <em>props</em><big>)</big><a class="headerlink" href="#pywinauto.XMLHelpers.WriteDialogToFile" title="Permalink to this definition"></a></dt>
<dd><p>Write the props to the file</p>
<p>props can be either a dialog of a dictionary</p>
</dd></dl>
<dl class="exception">
<dt id="pywinauto.XMLHelpers.XMLParsingError">
<em class="property">exception </em><tt class="descclassname">pywinauto.XMLHelpers.</tt><tt class="descname">XMLParsingError</tt><a class="headerlink" href="#pywinauto.XMLHelpers.XMLParsingError" title="Permalink to this definition"></a></dt>
<dd><p>Wrap parsing Exceptions</p>
</dd></dl>
</blockquote>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/code/XMLHelpers.py.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="../contents.html">pywinauto v0.3.9 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Mark Mc Mahon.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.5.
</div>
</body>
</html>

@ -1,120 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>pywinauto.tests.allcontrols &mdash; pywinauto v0.3.9 documentation</title>
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.3.9',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="top" title="pywinauto v0.3.9 documentation" href="../index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="../contents.html">pywinauto v0.3.9 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="pywinauto-tests-allcontrols">
<h1>pywinauto.tests.allcontrols<a class="headerlink" href="#pywinauto-tests-allcontrols" title="Permalink to this headline"></a></h1>
<blockquote>
<span class="target" id="module-pywinauto.tests.allcontrols"></span><p>Get All Controls Test</p>
<p><strong>What is checked</strong>
This test does no actual testing it just returns each control.</p>
<p><strong>How is it checked</strong>
A loop over all the controls in the dialog is made and each control added to
the list of bugs</p>
<p><strong>When is a bug reported</strong>
For each control.</p>
<p><strong>Bug Extra Information</strong>
There is no extra information associated with this bug type</p>
<p><strong>Is Reference dialog needed</strong>
No,but if available the reference control will be returned with the localised
control.</p>
<p><strong>False positive bug reports</strong>
Not possible</p>
<p><strong>Test Identifier</strong>
The identifier for this test/bug is &#8220;AllControls&#8221;</p>
<dl class="function">
<dt id="pywinauto.tests.allcontrols.AllControlsTest">
<tt class="descclassname">pywinauto.tests.allcontrols.</tt><tt class="descname">AllControlsTest</tt><big>(</big><em>windows</em><big>)</big><a class="headerlink" href="#pywinauto.tests.allcontrols.AllControlsTest" title="Permalink to this definition"></a></dt>
<dd><p>Returns just one bug for each control</p>
</dd></dl>
</blockquote>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/code/allcontrols.py.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="../contents.html">pywinauto v0.3.9 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Mark Mc Mahon.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.5.
</div>
</body>
</html>

@ -1,471 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>pywinauto.application &mdash; pywinauto v0.3.9 documentation</title>
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.3.9',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="top" title="pywinauto v0.3.9 documentation" href="../index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="../contents.html">pywinauto v0.3.9 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="pywinauto-application">
<h1>pywinauto.application<a class="headerlink" href="#pywinauto-application" title="Permalink to this headline"></a></h1>
<blockquote>
<span class="target" id="module-pywinauto.application"></span><p>The application module is the main one that users will user first.</p>
<p>When starting to automate and application you must initialize an instance
of the Application class. Then you must <a class="reference internal" href="pywinauto.application.html#pywinauto.application.Application.Start" title="pywinauto.application.Application.Start"><tt class="xref py py-func docutils literal"><span class="pre">Application.Start()</span></tt></a> that
application or <a class="reference internal" href="pywinauto.application.html#pywinauto.application.Application.Connect" title="pywinauto.application.Application.Connect"><tt class="xref py py-func docutils literal"><span class="pre">Application.Connect()</span></tt></a> to a running instance of that
application.</p>
<p>Once you have an Application instance you can access dialogs in that
application either by using one of the methods below.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">dlg</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">YourDialogTitle</span>
<span class="n">dlg</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">ChildWindow</span><span class="p">(</span><span class="n">title</span> <span class="o">=</span> <span class="s">&quot;your title&quot;</span><span class="p">,</span> <span class="n">classname</span> <span class="o">=</span> <span class="s">&quot;your class&quot;</span><span class="p">,</span> <span class="o">...</span><span class="p">)</span>
<span class="n">dlg</span> <span class="o">=</span> <span class="n">app</span><span class="p">[</span><span class="s">&#39;Your Dialog Title&#39;</span><span class="p">]</span>
</pre></div>
</div>
<p>Similarly once you have a dialog you can get a control from that dialog
in almost exactly the same ways.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">ctrl</span> <span class="o">=</span> <span class="n">dlg</span><span class="o">.</span><span class="n">YourControlTitle</span>
<span class="n">ctrl</span> <span class="o">=</span> <span class="n">dlg</span><span class="o">.</span><span class="n">ChildWindow</span><span class="p">(</span><span class="n">title</span> <span class="o">=</span> <span class="s">&quot;Your control&quot;</span><span class="p">,</span> <span class="n">classname</span> <span class="o">=</span> <span class="s">&quot;Button&quot;</span><span class="p">,</span> <span class="o">...</span><span class="p">)</span>
<span class="n">ctrl</span> <span class="o">=</span> <span class="n">dlg</span><span class="p">[</span><span class="s">&quot;Your control&quot;</span><span class="p">]</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">For attribute access of controls and dialogs you do not have to
have the title of the control exactly, it does a best match of the
avialable dialogs or controls.</p>
</div>
<div class="admonition-see-also admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last"><a class="reference internal" href="pywinauto.findwindows.html#pywinauto.findwindows.find_windows" title="pywinauto.findwindows.find_windows"><tt class="xref py py-func docutils literal"><span class="pre">pywinauto.findwindows.find_windows()</span></tt></a> for the keyword arguments that
can be passed to both <tt class="xref py py-func docutils literal"><span class="pre">Application.Window()</span></tt> and
<tt class="xref py py-func docutils literal"><span class="pre">WindowSpecification.Window()</span></tt></p>
</div>
<dl class="class">
<dt id="pywinauto.application.Application">
<em class="property">class </em><tt class="descclassname">pywinauto.application.</tt><tt class="descname">Application</tt><big>(</big><em>datafilename=None</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p>
<p>Represents an application</p>
<p>Set the attributes</p>
<dl class="staticmethod">
<dt id="pywinauto.application.Application.Connect">
<em class="property">static </em><tt class="descname">Connect</tt><big>(</big><em>*args</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.Connect" title="Permalink to this definition"></a></dt>
<dd><p>Convenience static method that calls connect</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.Connect_">
<tt class="descname">Connect_</tt><big>(</big><em>**kwargs</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.Connect_" title="Permalink to this definition"></a></dt>
<dd><p>Connects to an already running process</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.GetMatchHistoryItem">
<tt class="descname">GetMatchHistoryItem</tt><big>(</big><em>index</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.GetMatchHistoryItem" title="Permalink to this definition"></a></dt>
<dd><p>Should not be used - part of application data implementation</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.Kill_">
<tt class="descname">Kill_</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.application.Application.Kill_" title="Permalink to this definition"></a></dt>
<dd><p>Try and kill the application</p>
<p>Dialogs may pop up asking to save data - but the application
will be killed anyway - you will not be able to click the buttons.
this should only be used</p>
</dd></dl>
<dl class="staticmethod">
<dt id="pywinauto.application.Application.Start">
<em class="property">static </em><tt class="descname">Start</tt><big>(</big><em>*args</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.Start" title="Permalink to this definition"></a></dt>
<dd><p>Convenience static method that calls start</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.Start_">
<tt class="descname">Start_</tt><big>(</big><em>cmd_line</em>, <em>timeout=None</em>, <em>retry_interval=None</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.Start_" title="Permalink to this definition"></a></dt>
<dd><p>Starts the application giving in cmd_line</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.Window_">
<tt class="descname">Window_</tt><big>(</big><em>**kwargs</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.Window_" title="Permalink to this definition"></a></dt>
<dd><p>Return a window of the application</p>
<p>You can specify the same parameters as findwindows.find_windows.
It will add the process parameter to ensure that the window is from
the current process.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.Windows_">
<tt class="descname">Windows_</tt><big>(</big><em>**kwargs</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.Windows_" title="Permalink to this definition"></a></dt>
<dd><p>Return list of wrapped windows of the top level windows of
the application</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.WriteAppData">
<tt class="descname">WriteAppData</tt><big>(</big><em>filename</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.WriteAppData" title="Permalink to this definition"></a></dt>
<dd><p>Should not be used - part of application data implementation</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.active_">
<tt class="descname">active_</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.application.Application.active_" title="Permalink to this definition"></a></dt>
<dd><p>Return the active window of the application</p>
</dd></dl>
<dl class="staticmethod">
<dt id="pywinauto.application.Application.connect">
<em class="property">static </em><tt class="descname">connect</tt><big>(</big><em>*args</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.connect" title="Permalink to this definition"></a></dt>
<dd><p>Convenience static method that calls connect</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.connect_">
<tt class="descname">connect_</tt><big>(</big><em>**kwargs</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.connect_" title="Permalink to this definition"></a></dt>
<dd><p>Connects to an already running process</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.kill_">
<tt class="descname">kill_</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.application.Application.kill_" title="Permalink to this definition"></a></dt>
<dd><p>Try and kill the application</p>
<p>Dialogs may pop up asking to save data - but the application
will be killed anyway - you will not be able to click the buttons.
this should only be used</p>
</dd></dl>
<dl class="staticmethod">
<dt id="pywinauto.application.Application.start">
<em class="property">static </em><tt class="descname">start</tt><big>(</big><em>*args</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.start" title="Permalink to this definition"></a></dt>
<dd><p>Convenience static method that calls start</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.start_">
<tt class="descname">start_</tt><big>(</big><em>cmd_line</em>, <em>timeout=None</em>, <em>retry_interval=None</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.start_" title="Permalink to this definition"></a></dt>
<dd><p>Starts the application giving in cmd_line</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.top_window_">
<tt class="descname">top_window_</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.application.Application.top_window_" title="Permalink to this definition"></a></dt>
<dd><p>Return the current top window of the application</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.window_">
<tt class="descname">window_</tt><big>(</big><em>**kwargs</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.window_" title="Permalink to this definition"></a></dt>
<dd><p>Return a window of the application</p>
<p>You can specify the same parameters as findwindows.find_windows.
It will add the process parameter to ensure that the window is from
the current process.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.Application.windows_">
<tt class="descname">windows_</tt><big>(</big><em>**kwargs</em><big>)</big><a class="headerlink" href="#pywinauto.application.Application.windows_" title="Permalink to this definition"></a></dt>
<dd><p>Return list of wrapped windows of the top level windows of
the application</p>
</dd></dl>
</dd></dl>
<dl class="class">
<dt id="pywinauto.application.WindowSpecification">
<em class="property">class </em><tt class="descclassname">pywinauto.application.</tt><tt class="descname">WindowSpecification</tt><big>(</big><em>search_criteria</em><big>)</big><a class="headerlink" href="#pywinauto.application.WindowSpecification" title="Permalink to this definition"></a></dt>
<dd><p>A specificiation for finding a window or control</p>
<p>Windows are resolved when used.
You can also wait for existance or non existance of a window</p>
<p>Initailize the class</p>
<ul class="simple">
<li><strong>search_criteria</strong> the criteria to match a dialog</li>
</ul>
<dl class="method">
<dt id="pywinauto.application.WindowSpecification.__getitem__">
<tt class="descname">__getitem__</tt><big>(</big><em>key</em><big>)</big><a class="headerlink" href="#pywinauto.application.WindowSpecification.__getitem__" title="Permalink to this definition"></a></dt>
<dd><p>Allow access to dialogs/controls through item access</p>
<p>This allows:</p>
<div class="highlight-python"><pre>app.['DialogTitle']['ControlTextClass']</pre>
</div>
<p>to be used to access dialogs and controls.</p>
<p>Both this and <a class="reference internal" href="pywinauto.application.html#pywinauto.application.WindowSpecification.__getattr__" title="pywinauto.application.WindowSpecification.__getattr__"><tt class="xref py py-func docutils literal"><span class="pre">__getattr__()</span></tt></a> use the rules outlined in the
HowTo document.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.WindowSpecification.__getattr__">
<tt class="descname">__getattr__</tt><big>(</big><em>attr</em><big>)</big><a class="headerlink" href="#pywinauto.application.WindowSpecification.__getattr__" title="Permalink to this definition"></a></dt>
<dd><p>Attribute access for this class</p>
<p>If we already have criteria for both dialog and control then
resolve the control and return the requested attribute.</p>
<p>If we have only criteria for the dialog but the attribute
requested is an attribute of DialogWrapper then resolve the
dialog and return the requested attribute.</p>
<p>Otherwise delegate functionality to <a class="reference internal" href="pywinauto.application.html#pywinauto.application.WindowSpecification.__getitem__" title="pywinauto.application.WindowSpecification.__getitem__"><tt class="xref py py-func docutils literal"><span class="pre">__getitem__()</span></tt></a> - which
sets the appropriate criteria for the control.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.WindowSpecification.ChildWindow">
<tt class="descname">ChildWindow</tt><big>(</big><em>**criteria</em><big>)</big><a class="headerlink" href="#pywinauto.application.WindowSpecification.ChildWindow" title="Permalink to this definition"></a></dt>
<dd><p>Add criteria for a control</p>
<p>When this window specification is resolved then this will be used
to match against a control.</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.WindowSpecification.Exists">
<tt class="descname">Exists</tt><big>(</big><em>timeout=None</em>, <em>retry_interval=None</em><big>)</big><a class="headerlink" href="#pywinauto.application.WindowSpecification.Exists" title="Permalink to this definition"></a></dt>
<dd><p>Check if the window exists</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.WindowSpecification.PrintControlIdentifiers">
<tt class="descname">PrintControlIdentifiers</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.application.WindowSpecification.PrintControlIdentifiers" title="Permalink to this definition"></a></dt>
<dd><p>Prints the &#8216;identifiers&#8217;</p>
<p>If you pass in a control then it just prints the identifiers
for that control</p>
<p>If you pass in a dialog then it prints the identiferis for all
controls in the dialog</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Note :</th><td class="field-body">The identifiers printed by this method have not been made
unique. So if you have 2 edit boxes, they will both have &#8220;Edit&#8221;
listed in their identifiers. In reality though the first one
can be refered to as &#8220;Edit&#8221;, &#8220;Edit0&#8221;, &#8220;Edit1&#8221; and the 2nd
should be refered to as &#8220;Edit2&#8221;.</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.WindowSpecification.Wait">
<tt class="descname">Wait</tt><big>(</big><em>wait_for</em>, <em>timeout=None</em>, <em>retry_interval=None</em><big>)</big><a class="headerlink" href="#pywinauto.application.WindowSpecification.Wait" title="Permalink to this definition"></a></dt>
<dd><p>Wait for the window to be in a particular state</p>
<ul>
<li><p class="first"><strong>wait_for</strong> The state to wait for the window to be in. It can be any
of the following states</p>
<blockquote>
<ul class="simple">
<li>&#8216;exists&#8217; means that the window is a valid handle</li>
<li>&#8216;visible&#8217; means that the window is not hidden</li>
<li>&#8216;enabled&#8217; means that the window is not disabled</li>
<li>&#8216;ready&#8217; means that the window is visible and enabled</li>
<li>&#8216;active&#8217; means that the window is visible and enabled</li>
</ul>
</blockquote>
</li>
<li><p class="first"><strong>timeout</strong> Raise an error if the window is not in the appropriate
state after this number of seconds.</p>
</li>
<li><p class="first"><strong>retry_interval</strong> How long to sleep between each retry</p>
</li>
</ul>
<p>An example to wait until the dialog
exists, is ready, enabled and visible</p>
<blockquote>
self.Dlg.Wait(&#8220;exists enabled visible ready&#8221;)</blockquote>
<div class="admonition-see-also admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last"><a class="reference internal" href="pywinauto.application.html#pywinauto.application.WindowSpecification.WaitNot" title="pywinauto.application.WindowSpecification.WaitNot"><tt class="xref py py-func docutils literal"><span class="pre">WindowSpecification.WaitNot()</span></tt></a></p>
</div>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.WindowSpecification.WaitNot">
<tt class="descname">WaitNot</tt><big>(</big><em>wait_for_not</em>, <em>timeout=None</em>, <em>retry_interval=None</em><big>)</big><a class="headerlink" href="#pywinauto.application.WindowSpecification.WaitNot" title="Permalink to this definition"></a></dt>
<dd><p>Wait for the window to not be in a particular state</p>
<ul>
<li><p class="first"><strong>wait_for</strong> The state to wait for the window to not be in. It can be any
of the following states</p>
<blockquote>
<ul class="simple">
<li>&#8216;exists&#8217; means that the window is a valid handle</li>
<li>&#8216;visible&#8217; means that the window is not hidden</li>
<li>&#8216;enabled&#8217; means that the window is not disabled</li>
<li>&#8216;ready&#8217; means that the window is visible and enabled</li>
<li>&#8216;active&#8217; means that the window is visible and enabled</li>
</ul>
</blockquote>
</li>
<li><p class="first"><strong>timeout</strong> Raise an error if the window is sill in the
state after this number of seconds.(Optional)</p>
</li>
<li><p class="first"><strong>wiat_interval</strong> How long to sleep between each retry (Optional)</p>
</li>
</ul>
<p>e.g. self.Dlg.WaitNot(&#8220;exists enabled visible ready&#8221;)</p>
<div class="admonition-see-also admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last"><a class="reference internal" href="pywinauto.application.html#pywinauto.application.WindowSpecification.Wait" title="pywinauto.application.WindowSpecification.Wait"><tt class="xref py py-func docutils literal"><span class="pre">WindowSpecification.Wait()</span></tt></a></p>
</div>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.WindowSpecification.WrapperObject">
<tt class="descname">WrapperObject</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.application.WindowSpecification.WrapperObject" title="Permalink to this definition"></a></dt>
<dd><p>Allow the calling code to get the HwndWrapper object</p>
</dd></dl>
<dl class="method">
<dt id="pywinauto.application.WindowSpecification.print_control_identifiers">
<tt class="descname">print_control_identifiers</tt><big>(</big><big>)</big><a class="headerlink" href="#pywinauto.application.WindowSpecification.print_control_identifiers" title="Permalink to this definition"></a></dt>
<dd><p>Prints the &#8216;identifiers&#8217;</p>
<p>If you pass in a control then it just prints the identifiers
for that control</p>
<p>If you pass in a dialog then it prints the identiferis for all
controls in the dialog</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Note :</th><td class="field-body">The identifiers printed by this method have not been made
unique. So if you have 2 edit boxes, they will both have &#8220;Edit&#8221;
listed in their identifiers. In reality though the first one
can be refered to as &#8220;Edit&#8221;, &#8220;Edit0&#8221;, &#8220;Edit1&#8221; and the 2nd
should be refered to as &#8220;Edit2&#8221;.</td>
</tr>
</tbody>
</table>
</dd></dl>
</dd></dl>
<dl class="function">
<dt id="pywinauto.application.process_from_module">
<tt class="descclassname">pywinauto.application.</tt><tt class="descname">process_from_module</tt><big>(</big><em>module</em><big>)</big><a class="headerlink" href="#pywinauto.application.process_from_module" title="Permalink to this definition"></a></dt>
<dd><p>Return the running process with path module</p>
</dd></dl>
<dl class="function">
<dt id="pywinauto.application.process_module">
<tt class="descclassname">pywinauto.application.</tt><tt class="descname">process_module</tt><big>(</big><em>process_id</em><big>)</big><a class="headerlink" href="#pywinauto.application.process_module" title="Permalink to this definition"></a></dt>
<dd><p>Return the string module name of this process</p>
</dd></dl>
</blockquote>
<div class="section" id="exceptions">
<h2>Exceptions<a class="headerlink" href="#exceptions" title="Permalink to this headline"></a></h2>
<blockquote>
<dl class="class">
<dt id="pywinauto.application.AppNotConnected">
<em class="property">class </em><tt class="descclassname">pywinauto.application.</tt><tt class="descname">AppNotConnected</tt><a class="headerlink" href="#pywinauto.application.AppNotConnected" title="Permalink to this definition"></a></dt>
<dd><p>Application has been connected to a process yet</p>
</dd></dl>
<dl class="class">
<dt id="pywinauto.application.AppStartError">
<em class="property">class </em><tt class="descclassname">pywinauto.application.</tt><tt class="descname">AppStartError</tt><a class="headerlink" href="#pywinauto.application.AppStartError" title="Permalink to this definition"></a></dt>
<dd><p>There was a problem starting the Application</p>
</dd></dl>
<dl class="class">
<dt id="pywinauto.application.AssertValidProcess">
<em class="property">class </em><tt class="descclassname">pywinauto.application.</tt><tt class="descname">AssertValidProcess</tt><a class="headerlink" href="#pywinauto.application.AssertValidProcess" title="Permalink to this definition"></a></dt>
<dd><p>Raise ProcessNotFound error if process_id is not a valid process id</p>
</dd></dl>
<dl class="class">
<dt id="pywinauto.application.ProcessNotFoundError">
<em class="property">class </em><tt class="descclassname">pywinauto.application.</tt><tt class="descname">ProcessNotFoundError</tt><a class="headerlink" href="#pywinauto.application.ProcessNotFoundError" title="Permalink to this definition"></a></dt>
<dd><p>Could not find that process</p>
</dd></dl>
</blockquote>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">pywinauto.application</a><ul>
<li><a class="reference internal" href="#exceptions">Exceptions</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/code/application.py.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="../contents.html">pywinauto v0.3.9 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Mark Mc Mahon.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.5.
</div>
</body>
</html>

@ -1,140 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>pywinauto.tests.asianhotkey &mdash; pywinauto v0.3.9 documentation</title>
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.3.9',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="top" title="pywinauto v0.3.9 documentation" href="../index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="../contents.html">pywinauto v0.3.9 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="pywinauto-tests-asianhotkey">
<h1>pywinauto.tests.asianhotkey<a class="headerlink" href="#pywinauto-tests-asianhotkey" title="Permalink to this headline"></a></h1>
<blockquote>
<span class="target" id="module-pywinauto.tests.asianhotkey"></span><p>Asian Hotkey Format Test</p>
<p><strong>What is checked</strong></p>
<p>This test checks whether the format for shortcuts/hotkeys follows the
standards for localised Windows applications. This format is
{localised text}({uppercase hotkey})
so for example if the English control is
&#8220;&amp;Help&#8221;
the localised control for Asian languages should be
&#8220;LocHelp(H)&#8221;</p>
<p><strong>How is it checked</strong></p>
<p>After checking whether this control displays hotkeys it examines the 1st
string of the control to make sure that the format is correct.
If the reference control is available then it also makes sure that the
hotkey character is the same as the reference.
Controls with a title of less than 4 characters are ignored. This has been
done to avoid false positive bug reports for strings like &#8220;&amp;X:&#8221;.</p>
<p><strong>When is a bug reported</strong></p>
<p>A bug is reported when a control has a hotkey and it is not in the correct
format.
Also if the reference control is available a bug will be reported if the
hotkey character is not the same as used in the reference</p>
<p><strong>Bug Extra Information</strong></p>
<p>This test produces 2 different types of bug:
BugType: &#8220;AsianHotkeyFormat&#8221;
There is no extra information associated with this bug type</p>
<p><strong>BugType: &#8220;AsianHotkeyDiffRef&#8221;</strong></p>
<p>There is no extra information associated with this bug type</p>
<p><strong>Is Reference dialog needed</strong></p>
<p>The reference dialog is not needed.
If it is unavailable then only bugs of type &#8220;AsianHotkeyFormat&#8221; will be
reported, bug of type &#8220;AsianHotkeyDiffRef&#8221; will not be found.</p>
<p><strong>False positive bug reports</strong></p>
<p>There should be very few false positive bug reports when testing Asian
software. If a string is very short (eg &#8220;&amp;Y:&#8221;) but is padded with spaces
then it will get reported.</p>
<p><strong>Test Identifier</strong></p>
<p>The identifier for this test/bug is &#8220;AsianHotkeyTests&#8221;</p>
<dl class="function">
<dt id="pywinauto.tests.asianhotkey.AsianHotkeyTest">
<tt class="descclassname">pywinauto.tests.asianhotkey.</tt><tt class="descname">AsianHotkeyTest</tt><big>(</big><em>windows</em><big>)</big><a class="headerlink" href="#pywinauto.tests.asianhotkey.AsianHotkeyTest" title="Permalink to this definition"></a></dt>
<dd><p>Return the repeated hotkey errors</p>
</dd></dl>
</blockquote>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/code/asianhotkey.py.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li><a href="../contents.html">pywinauto v0.3.9 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Mark Mc Mahon.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.5.
</div>
</body>
</html>

@ -1,120 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>pywinauto.tests.changedtext &mdash; pywinauto v0.3.9 documentation</title>
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '0.3.9',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="top" title="pywinauto v0.3.9 documentation" href="../index.html" />
<link rel="up" title="Main user modules" href="code.html" />
<link rel="next" title="pywinauto.tests.missalignmen2t" href="missalignmen2t.py.html" />
<link rel="prev" title="pywinauto.fuzzydict" href="pywinauto.fuzzydict.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="missalignmen2t.py.html" title="pywinauto.tests.missalignmen2t"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="pywinauto.fuzzydict.html" title="pywinauto.fuzzydict"
accesskey="P">previous</a> |</li>
<li><a href="../contents.html">pywinauto v0.3.9 documentation</a> &raquo;</li>
<li><a href="code.html" accesskey="U">Main user modules</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="pywinauto-tests-changedtext">
<h1>pywinauto.tests.changedtext<a class="headerlink" href="#pywinauto-tests-changedtext" title="Permalink to this headline"></a></h1>
<blockquote>
</blockquote>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="pywinauto.fuzzydict.html"
title="previous chapter">pywinauto.fuzzydict</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="missalignmen2t.py.html"
title="next chapter">pywinauto.tests.missalignmen2t</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/code/changedtext.py.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="../search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="missalignmen2t.py.html" title="pywinauto.tests.missalignmen2t"
>next</a> |</li>
<li class="right" >
<a href="pywinauto.fuzzydict.html" title="pywinauto.fuzzydict"
>previous</a> |</li>
<li><a href="../contents.html">pywinauto v0.3.9 documentation</a> &raquo;</li>
<li><a href="code.html" >Main user modules</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Mark Mc Mahon.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.5.
</div>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More