Compare commits
No commits in common. "master" and "wiki" have entirely different histories.
@ -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
|
167
LICENSE.txt
@ -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!
|
30
MANIFEST.in
@ -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.
|
87
Readme.txt
@ -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")
|
||||
|
||||
|
||||
|
174
doc_src/TODO.txt
@ -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:
|
||||
|
210
doc_src/conf.py
@ -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()
|
31
makedocs.bat
@ -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
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
|
@ -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
|
||||
#
|
||||
#
|
@ -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()
|
@ -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 — 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 TODO’s" 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 TODO’s"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li><a href="contents.html">pywinauto 0.4.2 documentation</a> »</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 ‘__’ and ends with ‘__’ 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 ‘SendMessageTimeout’ 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’s it’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 ‘win32defines’ 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 ‘edit’ window classes</li>
|
||||
<li>Added some more VB ‘listbox’ window classes</li>
|
||||
<li>Added some more VB ‘button’ 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’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 -> 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 ‘Common’ 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 ‘active’ 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
|
||||
‘MenuItems’ 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 ‘slowing’ 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’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 ‘modifying’ 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’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’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">'Find'</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">"File->Exit"</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">'Find'</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">"File->Exit"</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">"File->Exit"</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’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’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).</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’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(“notepad”)
|
||||
same_notepad = Application.connect(path = “notepad”)</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->Font dialog, the 1st
|
||||
combobox can be refered to as “FontComboBox” rather than “ComboBox1”</p>
|
||||
</li>
|
||||
<li><p class="first">Added a new control wrapper - <tt class="docutils literal"><span class="pre">PopupMenuWrapper</span></tt> for context menu’s
|
||||
You can now work easily with context menu’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">"Select All"</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">"Copy"</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 “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”.</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 ‘physically’ 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">"View"</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">"View->Status Bar"</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 ‘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.</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’s before it retrieves the items</p>
|
||||
</li>
|
||||
<li><p class="first">Added functionality to associate ‘non-text’ controls with the ‘text’
|
||||
control closest to them. This allows controls to be referenced by:</p>
|
||||
<div class="highlight-python"><pre>app.dlg.<Nearby_text><Window_class></pre>
|
||||
</div>
|
||||
<p>e.g. to reference the “Footer” 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’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 TODO’s"
|
||||
>previous</a> |</li>
|
||||
<li><a href="contents.html">pywinauto 0.4.2 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© 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 To’s — 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> »</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’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"c:\path\to\your\application -a -n -y --arguments"</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"c:\windows\system32\notepad.exe"</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">".*Notepad"</span><span class="p">,</span> <span class="n">class_name</span> <span class="o">=</span> <span class="s">"Notepad"</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’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">'Notepad'</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">"Page Setup"</span><span class="p">,</span> <span class="n">class_name</span> <span class="o">=</span> <span class="s">"#32770"</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">".*Part of Title.*"</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">'dlg'</span><span class="p">][</span><span class="s">'control'</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div></blockquote>
|
||||
<p>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’]</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’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&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'</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 “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”</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’s say that you don’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’
|
||||
look right, it would be nicer to leave out the ‘inches’ 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">'dialog_ident'</span><span class="p">][</span><span class="s">'control_ident'</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">"NonAsciiCharacters"</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">"MoreNonAsciiCharacters"</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
|
||||
‘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 :-(.</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">"ItemInList"</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">"{HOME}{DOWN 2}{ENTER}"</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’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 ‘Notification Area’)<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 “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 :-).</p>
|
||||
<p>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”.</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’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">“Start me up” :-) 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> </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> </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> </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> </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">'outlook.exe'</span><span class="p">)</span>
|
||||
|
||||
<span class="c"># click on Outlook'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">"Cancel Server Request"</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’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 ‘Notification Area’)</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> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© 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 TODO’s — 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> »</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’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’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’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’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’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’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’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’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’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">"blah->blah"</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’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’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->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’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> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© Copyright 2010, Mark Mc Mahon.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
BIN
pywinauto/docs/_static/ajax-loader.gif
vendored
Before Width: | Height: | Size: 673 B |
540
pywinauto/docs/_static/basic.css
vendored
@ -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;
|
||||
}
|
||||
}
|
BIN
pywinauto/docs/_static/comment-bright.png
vendored
Before Width: | Height: | Size: 3.4 KiB |
BIN
pywinauto/docs/_static/comment-close.png
vendored
Before Width: | Height: | Size: 3.5 KiB |
BIN
pywinauto/docs/_static/comment.png
vendored
Before Width: | Height: | Size: 3.4 KiB |
256
pywinauto/docs/_static/default.css
vendored
@ -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;
|
||||
}
|
247
pywinauto/docs/_static/doctools.js
vendored
@ -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();
|
||||
});
|
BIN
pywinauto/docs/_static/down-pressed.png
vendored
Before Width: | Height: | Size: 368 B |
BIN
pywinauto/docs/_static/down.png
vendored
Before Width: | Height: | Size: 363 B |
BIN
pywinauto/docs/_static/file.png
vendored
Before Width: | Height: | Size: 392 B |
154
pywinauto/docs/_static/jquery.js
vendored
@ -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);
|
BIN
pywinauto/docs/_static/minus.png
vendored
Before Width: | Height: | Size: 199 B |
BIN
pywinauto/docs/_static/plus.png
vendored
Before Width: | Height: | Size: 199 B |
62
pywinauto/docs/_static/pygments.css
vendored
@ -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 */
|
560
pywinauto/docs/_static/searchtools.js
vendored
@ -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();
|
||||
});
|
151
pywinauto/docs/_static/sidebar.js
vendored
@ -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>«</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();
|
||||
});
|
23
pywinauto/docs/_static/underscore.js
vendored
@ -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}})();
|
BIN
pywinauto/docs/_static/up-pressed.png
vendored
Before Width: | Height: | Size: 372 B |
BIN
pywinauto/docs/_static/up.png
vendored
Before Width: | Height: | Size: 363 B |
808
pywinauto/docs/_static/websupport.js
vendored
@ -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 ▹\
|
||||
</a>\
|
||||
<a href="#" id="hc<%id%>" class="hide-propose-change">\
|
||||
Propose a change ▿\
|
||||
</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 ▹</a>\
|
||||
<a href="#" class="close-reply" id="cr<%id%>">reply ▿</a>\
|
||||
<a href="#" id="sp<%id%>" class="show-proposal">proposal ▹</a>\
|
||||
<a href="#" id="hp<%id%>" class="hide-proposal">proposal ▿</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 — 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> »</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’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
|
||||
‘realistic’ 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 ‘left’, ‘right’,
|
||||
‘middle’ or ‘x’ (Default: ‘left’)</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 ‘click’
|
||||
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’s for example lables in a dialog may have duplicate
|
||||
ID’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 ‘red’, ‘green’, ‘blue’
|
||||
(default ‘green’)</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 ‘Registered’ 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 “Button” - but the friendly class is “CheckBox”</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 ‘restored’
|
||||
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 ‘parent’.</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 “MenuItem->MenuItem->MenuItem...”
|
||||
where each MenuItem is the text of an item at that level of the menu.
|
||||
E.g.</p>
|
||||
<div class="highlight-python"><pre>File->Export->ExportAsPNG</pre>
|
||||
</div>
|
||||
<p>spaces are not important so you could also have written...</p>
|
||||
<div class="highlight-python"><pre>File -> Export -> 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 “up”, “down”, “left”, “right”
|
||||
amount can be one of “line”, “page”, “end”
|
||||
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”</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’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’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> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© 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 — 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> »</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> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© 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 — 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> »</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 “AllControls”</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> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© 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 — 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> »</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">"your title"</span><span class="p">,</span> <span class="n">classname</span> <span class="o">=</span> <span class="s">"your class"</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">'Your Dialog Title'</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">"Your control"</span><span class="p">,</span> <span class="n">classname</span> <span class="o">=</span> <span class="s">"Button"</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">"Your control"</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 ‘identifiers’</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 “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”.</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>‘exists’ means that the window is a valid handle</li>
|
||||
<li>‘visible’ means that the window is not hidden</li>
|
||||
<li>‘enabled’ means that the window is not disabled</li>
|
||||
<li>‘ready’ means that the window is visible and enabled</li>
|
||||
<li>‘active’ 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(“exists enabled visible ready”)</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>‘exists’ means that the window is a valid handle</li>
|
||||
<li>‘visible’ means that the window is not hidden</li>
|
||||
<li>‘enabled’ means that the window is not disabled</li>
|
||||
<li>‘ready’ means that the window is visible and enabled</li>
|
||||
<li>‘active’ 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(“exists enabled visible ready”)</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 ‘identifiers’</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 “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”.</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> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© 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 — 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> »</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
|
||||
“&Help”
|
||||
the localised control for Asian languages should be
|
||||
“LocHelp(H)”</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 “&X:”.</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: “AsianHotkeyFormat”
|
||||
There is no extra information associated with this bug type</p>
|
||||
<p><strong>BugType: “AsianHotkeyDiffRef”</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 “AsianHotkeyFormat” will be
|
||||
reported, bug of type “AsianHotkeyDiffRef” 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 “&Y:”) 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 “AsianHotkeyTests”</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> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© 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 — 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> »</li>
|
||||
<li><a href="code.html" accesskey="U">Main user modules</a> »</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> »</li>
|
||||
<li><a href="code.html" >Main user modules</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© Copyright 2009, Mark Mc Mahon.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.5.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|