# Upgrade pywinauto to 0.6.8 (Fixed some big bug with int convert to long fails) + Some Docs fixes in Pypi

dev-linux
Ivan Maslov 4 years ago
parent a4aa6136de
commit b578600c09

@ -9,6 +9,7 @@
# }
# }
# }
# USAGE in .py
# inRequest.
# inRequest.OpenRPA["DefUserRoleAccessAsk"](["Orchestrator","RDPActive","Controls"]) - return True or False

@ -1,18 +1,25 @@
Metadata-Version: 2.1
Name: pyOpenRPA
Version: 1.1.12
Version: 1.1.13
Summary: First open source RPA platform for business
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
Author: Ivan Maslov
Author-email: Ivan.Maslov@unicodelabs.ru
License: MIT
Keywords: OpenRPA RPA Robot Automation Robotization
Keywords: OpenRPA RPA Robot Automation Robotization OpenSource
Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: MIT License
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Home Automation
Description-Content-Type: text/markdown
Requires-Dist: pywinauto (>=0.6.6)
Requires-Dist: pywinauto (>=0.6.8)
Requires-Dist: WMI (>=1.4.9)
Requires-Dist: pillow (>=6.0.0)
Requires-Dist: keyboard (>=0.13.3)
@ -50,17 +57,17 @@ Resources\WPy64-3720\python-3.7.2.amd64\python.exe
# Module GUI activity List:
############################
Новая версия
Новая версия
############################
Получить список элементов, который удовлетворяет условиям через расширенный движок поиска
Получить список элементов, который удовлетворяет условиям через расширенный движок поиска
[
{
"index":<Позиция элемента в родительском объекте>,
"depth_start" - глубина, с которой начинается поиск (по умолчанию 1)
"depth_end" - глубина, до которой ведется поиск (по умолчанию 1)
"class_name" - наименование класса, который требуется искать
"title" - наименование заголовка
"rich_text" - наименование rich_text
"index":<Позиция элемента в родительском объекте>,
"depth_start" - глубина, с которой начинается поиск (по умолчанию 1)
"depth_end" - глубина, до которой ведется поиск (по умолчанию 1)
"class_name" - наименование класса, который требуется искать
"title" - наименование заголовка
"rich_text" - наименование rich_text
}
]

@ -1,8 +1,8 @@
pyOpenRPA-1.1.12.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.1.12.dist-info/METADATA,sha256=QQ3aid4fLcFpJ0aWDRyYrVf1EMWi3cYocTyqvmHwJ90,3542
pyOpenRPA-1.1.12.dist-info/RECORD,,
pyOpenRPA-1.1.12.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.1.12.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA-1.1.13.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.1.13.dist-info/METADATA,sha256=rjIGRZpHzGWnt9LvY4CqdNByJhS4FqqdMUdzP_2BWmk,3352
pyOpenRPA-1.1.13.dist-info/RECORD,,
pyOpenRPA-1.1.13.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.1.13.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/.idea/inspectionProfiles/profiles_settings.xml,sha256=YXLFmX7rPNGcnKK1uX1uKYPN0fpgskYNe7t0BV7cqkY,174
pyOpenRPA/.idea/misc.xml,sha256=ySjeaQ1DfqxaRTlFGT_3zW5r9mWuwxoAK_AX4QiuAZM,203
pyOpenRPA/.idea/modules.xml,sha256=Q__U1JIA2cjxbLRXAv-SfYY00fZA0TNlpkkbY4s3ncg,277
@ -300,6 +300,6 @@ pyOpenRPA/Tools/Terminator.py,sha256=VcjX3gFXiCGu3MMCidhrTNsmC9wsAqfjRJdTSU9fLnU
pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/__pycache__/Terminator.cpython-37.pyc,,
pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=4A8Uettbe_avfR459RgVJNkUxs-2hHjTgSVKpVOFjKw,175
pyOpenRPA/__init__.py,sha256=MLl4coStn9rfw3D3uxDlH6uWJFlRPjAXs2Scbs-T3KA,175
pyOpenRPA/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/test.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

@ -3,7 +3,7 @@ r"""
The OpenRPA package (from UnicodeLabs)
"""
__version__ = 'v1.1.12'
__version__ = 'v1.1.13'
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from .Core import Robot

@ -1,13 +0,0 @@
At it's simplest it allows you to send mouse and keyboard
actions to windows dialogs and controls, but It has support for more complex
controls also.
Useful links
-------------
- Home page: http://pywinauto.github.io/
- Docs Intro: https://pywinauto.readthedocs.io/en/latest/
- Getting Started Guide: https://pywinauto.readthedocs.io/en/latest/getting_started.html
- StackOverflow tag: https://stackoverflow.com/questions/tagged/pywinauto

@ -1 +0,0 @@
{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: Microsoft :: Windows", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Testing", "Topic :: Software Development :: User Interfaces", "Topic :: Software Development :: Quality Assurance"], "extensions": {"python.details": {"contacts": [{"email": "pywinauto-users@lists.sourceforge.net", "name": "Mark Mc Mahon and Contributors", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "http://pywinauto.github.io/"}}}, "extras": [], "generator": "bdist_wheel (0.29.0)", "keywords": ["windows", "gui", "automation", "GuiAuto", "testing", "test", "desktop", "mouse", "keyboard"], "license": "BSD 3-clause", "metadata_version": "2.0", "name": "pywinauto", "platform": "win32", "run_requires": [{"requires": ["comtypes", "six"]}], "summary": "A set of Python modules to automate the Microsoft Windows GUI", "version": "0.6.6"}

@ -0,0 +1,27 @@
Copyright (c) 2017, Mark Mc Mahon and Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of pywinauto nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -1,6 +1,6 @@
Metadata-Version: 2.0
Metadata-Version: 2.1
Name: pywinauto
Version: 0.6.6
Version: 0.6.8
Summary: A set of Python modules to automate the Microsoft Windows GUI
Home-page: http://pywinauto.github.io/
Author: Mark Mc Mahon and Contributors
@ -23,9 +23,9 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Dist: comtypes
Requires-Dist: six
Requires-Dist: comtypes
Requires-Dist: pywin32
At it's simplest it allows you to send mouse and keyboard
actions to windows dialogs and controls, but It has support for more complex

@ -1,11 +1,10 @@
pywinauto-0.6.6.dist-info/DESCRIPTION.rst,sha256=k2uqeFUEl_g6xxBeVuZEfpJGuEOwcWLWkYAPOCoNkrk,443
pywinauto-0.6.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pywinauto-0.6.6.dist-info/METADATA,sha256=0BOLG3k-RTQbPt5MoG8G7P0yDwqhu2hQddg1D03wNgA,1660
pywinauto-0.6.6.dist-info/RECORD,,
pywinauto-0.6.6.dist-info/WHEEL,sha256=Ds0ba8WsPJtjBPzEMyPOBG3qfPa6B4mlzB-vhzorIZs,97
pywinauto-0.6.6.dist-info/metadata.json,sha256=0I2fhQRsICsiE-qQSyHVGUikMukbxGqL_67vZLVOkPs,1363
pywinauto-0.6.6.dist-info/top_level.txt,sha256=7E8mqRxGiLpAamWQi4ClxZvTp1jx3P0shUi_Tu0zk44,10
pywinauto/__init__.py,sha256=BJ2Pni41MWP3DgzGAFhpNvFajGujGcVUxMnf6n5s1tI,6950
pywinauto-0.6.8.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pywinauto-0.6.8.dist-info/LICENSE,sha256=GKmZqVt7I9hsQQtFNORNafbYzhPDpTcZsGq4ldii5zo,1504
pywinauto-0.6.8.dist-info/METADATA,sha256=7x_-XwBl2UsjPrl_4e5bNgDVwA_FMH83WidT-ii0xb0,1723
pywinauto-0.6.8.dist-info/RECORD,,
pywinauto-0.6.8.dist-info/WHEEL,sha256=53VSps8MltPLN_x9Ib61FU2ZSaJKzgrWQqu9rS-Dkgk,116
pywinauto-0.6.8.dist-info/top_level.txt,sha256=7E8mqRxGiLpAamWQi4ClxZvTp1jx3P0shUi_Tu0zk44,10
pywinauto/__init__.py,sha256=xY7VLfy-UvPNHKJSlzekAoG9Sue8zdNdFIdjS-_zTFs,7231
pywinauto/__pycache__/__init__.cpython-37.pyc,,
pywinauto/__pycache__/actionlogger.cpython-37.pyc,,
pywinauto/__pycache__/application.cpython-37.pyc,,
@ -33,9 +32,9 @@ pywinauto/__pycache__/win32functions.cpython-37.pyc,,
pywinauto/__pycache__/win32structures.cpython-37.pyc,,
pywinauto/__pycache__/xml_helpers.cpython-37.pyc,,
pywinauto/actionlogger.py,sha256=JVny3VSQIzcSH6ESfUPkxPozSJrxMMOvlwzNiUzO-_E,5632
pywinauto/application.py,sha256=r1gE55O91UXteKme9rFqBUP1QmbYyt4tmpXNQAHHt7I,55887
pywinauto/application.py,sha256=_KIIkl_ZZNFDZo_phPhYBX1YuNZh4pFW5A1gdYvTXeo,58047
pywinauto/backend.py,sha256=hLgO3HsnCJUYNoPfU8CwD11yMKjUZiPuXlC080JNufE,4186
pywinauto/base_wrapper.py,sha256=wx_8TIg_RbXX_zvpxGyL8nUWcvfQHVtVK6tAl8gcC_A,37561
pywinauto/base_wrapper.py,sha256=qAIvH6wKd6okBBDHY21gnK7A2DQj5H43qV4heQqQxc4,37590
pywinauto/clipboard.py,sha256=VpKW7WQ3BF57cmLkWA0Of16RG6BCuLSqGX0sW2nN1ds,4329
pywinauto/controlproperties.py,sha256=YQ1lbHxWvMf38PGB0JYdN8rhh9PYoe8iwaWbtw3EU1w,9329
pywinauto/controls/__init__.py,sha256=0cuXVxqppu3vQIJfjgxB_J__3Vtr3EvbDEx7TaRY64A,2241
@ -46,26 +45,26 @@ pywinauto/controls/__pycache__/menuwrapper.cpython-37.pyc,,
pywinauto/controls/__pycache__/uia_controls.cpython-37.pyc,,
pywinauto/controls/__pycache__/uiawrapper.cpython-37.pyc,,
pywinauto/controls/__pycache__/win32_controls.cpython-37.pyc,,
pywinauto/controls/common_controls.py,sha256=zyx1EyyoSQ_pvl6snIPOzIp6WZuPXOYNAzYqM4Qh5GA,141066
pywinauto/controls/hwndwrapper.py,sha256=46cKLxKhYL6-BzN33KA8kG7wOy1-JGEJ68qVQLiCYts,68153
pywinauto/controls/menuwrapper.py,sha256=SS5UoaezIMknz_405021QUV0ixClkqCUfuck_EnsgIA,23477
pywinauto/controls/uia_controls.py,sha256=rmME_GCfDbohEBNnHJE_mLStshBvPX_-r8T_Xa6XuH8,53699
pywinauto/controls/uiawrapper.py,sha256=aEVJYh6aB6VIg9sBrHwyQ3LOKTMnFLruVCMmSxy0dfQ,30770
pywinauto/controls/common_controls.py,sha256=4a_RyQcDl4N2JW8F_9sK-utJWJK-ujwqXF4vEhAaFe0,138614
pywinauto/controls/hwndwrapper.py,sha256=nDiCY-DnVHrD2o49WTRv7-x_2kB9Xf9nBb3gWJkgl5I,68222
pywinauto/controls/menuwrapper.py,sha256=TlgHXxMm6pUB75VDW6R-X5octoSpauXM0t7pRIJ8bPE,23497
pywinauto/controls/uia_controls.py,sha256=ei-u10dGxMRjR7SQupD3dxrvlbiqHm90ggb9WyracJA,54886
pywinauto/controls/uiawrapper.py,sha256=w7wsUnbsSStm32H5t2jEI-P9sdbMVOS8OYASHJnmhDk,31386
pywinauto/controls/win32_controls.py,sha256=Iz-28a0b_TPR8XiSTIkr8areRXyxuXQ0gOqshIPcrhU,35099
pywinauto/element_info.py,sha256=L-s3E6xdVAxgfCFZXAQlMbaHl5OEtG_xFM845gFz5zc,6067
pywinauto/findbestmatch.py,sha256=xAJaaiqAnBmQwCrhiqga-AmI5FxR0gZuXE1v1k1tyRA,20605
pywinauto/findwindows.py,sha256=wYQgISnlHOAhuvxA0bG9shLSTwu9pKNg1_ApYJi1pHw,14290
pywinauto/findbestmatch.py,sha256=izVEqpMSXgFhdMLd3OxN6Sexfo6MGVHTPEwkFxhDDpU,20748
pywinauto/findwindows.py,sha256=OMn7J5i4vk2xiVINPQ4daaMZ5MDCAplgnt4MXHo2dGY,14470
pywinauto/fuzzydict.py,sha256=mNFpET8ckSpMen4LdRRYyGRR4LToMbQw-gqNG3lWCqM,6073
pywinauto/handleprops.py,sha256=WavBoIYV0WTLpq5YUXDQS0-kMv3GChpwk2etbMFZA_k,14748
pywinauto/keyboard.py,sha256=Q_hT07R48cC830HzBZTaM2o2XOMtLsucVG_KalAfgz4,22865
pywinauto/handleprops.py,sha256=85UJyb6LfUVNim5biyB9Fz-oICo3lq1S_-jPxxgs28c,14685
pywinauto/keyboard.py,sha256=tJ4MSH7WVvmPrinMDycRr_uWm7AEtiFrfYjFjVgOwW0,24562
pywinauto/linux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pywinauto/linux/__pycache__/__init__.cpython-37.pyc,,
pywinauto/linux/__pycache__/clipboard.cpython-37.pyc,,
pywinauto/linux/__pycache__/keyboard.cpython-37.pyc,,
pywinauto/linux/clipboard.py,sha256=X4wR0r1_X8fdLF0KphNskV_vV2c0_toNyyt2m-TY6nQ,3568
pywinauto/linux/keyboard.py,sha256=kvc5EZY8lML2WoCwV5er9SyzsF2NjQ4Abpum-YYT5-U,17380
pywinauto/linux/keyboard.py,sha256=z540dSwdCvmoyRSpCaJainPOTawbY76eo8i_UW2qyYQ,17458
pywinauto/mouse.py,sha256=-Rh9zY1KUfzVcKblvQixH0WKxf2lW9__yrsI-pRhpe0,10647
pywinauto/remote_memory_block.py,sha256=fC0HyKKrsFlwS-1QlwQZif3RFqK4hr1RkIwajkbzGM4,12204
pywinauto/remote_memory_block.py,sha256=eox-bC9ZpliwQw3gZuiPku8_oQ9sGNeKfrSOM2pNyJs,12168
pywinauto/sysinfo.py,sha256=NgLfiQ3XNaRGnapzSfYSafwn5my24FjE1uHTU66P4VM,3052
pywinauto/taskbar.py,sha256=vjHNAdOaQwyZvqJaLMvMB7teJBMOeCgXeedJpZrZGp4,5232
pywinauto/tests/__init__.py,sha256=DZXsho8W7nBWDSw5Qb-qao9CNpfOwTCKOtxG0dJRgos,5452
@ -97,11 +96,11 @@ pywinauto/tests/repeatedhotkey.py,sha256=6xFNznYzzIebpkX2dLUW6rIkTOBIe5la1qVohi3
pywinauto/tests/translation.py,sha256=0qVEsh42uqu1K5MDZfcQunPngSRanPfSLgL99An1W8g,6070
pywinauto/tests/truncation.py,sha256=MD5UTKnVtZPZyfP3Ejx5ZMBDrDYY089xY05a8SMtMjc,20006
pywinauto/timings.py,sha256=58c9xNODE5LjQYNhqoLpbLfNeJ9Lu0J8GZLw2d2tkMY,15668
pywinauto/uia_defines.py,sha256=-4w4hhRCd4O_748nEp5w5kKl-d0vb17aymVr3rdZTQ0,9819
pywinauto/uia_defines.py,sha256=ynA52N4tmKn8KBlqGP0EJ8etpygvYTyZhQNJ-vdOBRw,9979
pywinauto/uia_element_info.py,sha256=g2E9O4qSyXYmj80MqFD7mOin_nHXowM_-fVJVO0oV88,13762
pywinauto/win32_element_info.py,sha256=bJ9CIP4RPdGIZVB_HaZQg2Z_92QG2hWYw1aGkoBtTxI,9369
pywinauto/win32_hooks.py,sha256=X2Le46OJxmco94b0n830RN6Tpnk2BzMTtRVOYdwllWc,24289
pywinauto/win32defines.py,sha256=i-uScB7nzZRk0fiDNk6TqlhGraRESmjLx-GkBlgOOp4,499259
pywinauto/win32functions.py,sha256=uHpPx61qsWL_awp6Kq0D-ERN5GsAvHjC34pN-rx1xQQ,14987
pywinauto/win32structures.py,sha256=G9diB0fpPv95J8DQLt6z5D1033Ajw_FZUCojrS0xliA,42128
pywinauto/win32_hooks.py,sha256=_oG2uuMswls-9jxaGm_XRAstM6E9S38cQ6ZzBEoiYg0,24238
pywinauto/win32defines.py,sha256=zltu4uEoY397OBLDKI_Vo0R79719_uqHOjL0QuTO3rc,630639
pywinauto/win32functions.py,sha256=fHHeG9kARY_3a05qXoI9hbIIXua6Kj3IJUu6my0W6Fw,24133
pywinauto/win32structures.py,sha256=CGxoTtM-fH_AyxpxGhRl28YsVJfBM1jv3_aLUXDo0ng,41700
pywinauto/xml_helpers.py,sha256=uiairq6vJiduprD6KMIvc72qBuplPC-PQqduJVVVZnc,17263

@ -1,5 +1,6 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.29.0)
Generator: bdist_wheel (0.33.4)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any

@ -32,7 +32,7 @@
"""Python package for automating GUI manipulation on Windows"""
__version__ = "0.6.6"
__version__ = "0.6.8"
import sys # noqa: E402
import warnings # noqa: E402
@ -89,11 +89,9 @@ if sys.platform == 'win32':
from . import findwindows
WindowAmbiguousError = findwindows.WindowAmbiguousError
WindowNotFoundError = findwindows.WindowNotFoundError
ElementNotFoundError = findwindows.ElementNotFoundError
if UIA_support:
ElementNotFoundError = findwindows.ElementNotFoundError
ElementAmbiguousError = findwindows.ElementAmbiguousError
ElementAmbiguousError = findwindows.ElementAmbiguousError
from . import findbestmatch
from . import backend as backends
@ -106,13 +104,14 @@ if sys.platform == 'win32':
class Desktop(object):
"""Simple class to call something like ``Desktop().WindowName.ControlName.method()``"""
def __init__(self, backend=None):
def __init__(self, backend=None, allow_magic_lookup=True):
"""Create desktop element description"""
if not backend:
backend = backends.registry.name
if backend not in backends.registry.backends:
raise ValueError('Backend "{0}" is not registered!'.format(backend))
self.backend = backends.registry.backends[backend]
self.allow_magic_lookup = allow_magic_lookup
def window(self, **kwargs):
"""Create WindowSpecification object for top-level window"""
@ -121,7 +120,7 @@ if sys.platform == 'win32':
if 'backend' in kwargs:
raise ValueError('Using another backend than set in Desktop constructor is not allowed!')
kwargs['backend'] = self.backend.name
return WindowSpecification(kwargs)
return WindowSpecification(kwargs, allow_magic_lookup=self.allow_magic_lookup)
def windows(self, **kwargs):
"""Return a list of wrapped top level windows"""
@ -145,9 +144,12 @@ if sys.platform == 'win32':
def __getattribute__(self, attr_name):
"""Attribute access for this class"""
allow_magic_lookup = object.__getattribute__(self, "allow_magic_lookup") # Beware of recursions here!
try:
return object.__getattribute__(self, attr_name)
except AttributeError:
if not allow_magic_lookup:
raise
return self[attr_name] # delegate it to __get_item__
def from_point(self, x, y):

@ -141,11 +141,12 @@ class WindowSpecification(object):
'active': ('is_active',),
}
def __init__(self, search_criteria):
def __init__(self, search_criteria, allow_magic_lookup=True):
"""
Initialize the class
:param search_criteria: the criteria to match a dialog
:param allow_magic_lookup: whether attribute access must turn into child_window(best_match=...) search as fallback
"""
# kwargs will contain however to find this window
if 'backend' not in search_criteria:
@ -158,6 +159,7 @@ class WindowSpecification(object):
self.criteria = [search_criteria, ]
self.actions = ActionLogger()
self.backend = registry.backends[search_criteria['backend']]
self.allow_magic_lookup = allow_magic_lookup
if self.backend.name == 'win32':
# Non PEP-8 aliases for partial backward compatibility
@ -173,7 +175,7 @@ class WindowSpecification(object):
self.window_ = deprecated(self.child_window, deprecated_name='window_')
def __call__(self, *args, **kwargs):
"""No __call__ so return a usefull error"""
"""No __call__ so return a useful error"""
if "best_match" in self.criteria[-1]:
raise AttributeError("Neither GUI element (wrapper) " \
"nor wrapper method '{0}' were found (typo?)".
@ -182,8 +184,8 @@ class WindowSpecification(object):
message = (
"You tried to execute a function call on a WindowSpecification "
"instance. You probably have a typo for one of the methods of "
"this class.\n"
"The criteria leading up to this is: " + str(self.criteria))
"this class or of the targeted wrapper object.\n"
"The criteria leading up to this are: " + str(self.criteria))
raise AttributeError(message)
@ -277,7 +279,7 @@ class WindowSpecification(object):
if 'top_level_only' not in criteria:
criteria['top_level_only'] = False
new_item = WindowSpecification(self.criteria[0])
new_item = WindowSpecification(self.criteria[0], allow_magic_lookup=self.allow_magic_lookup)
new_item.criteria.extend(self.criteria[1:])
new_item.criteria.append(criteria)
@ -307,7 +309,7 @@ class WindowSpecification(object):
"""
# if we already have 2 levels of criteria (dlg, control)
# then resolve the control and do a getitem on it for the
if len(self.criteria) >= 2:
if len(self.criteria) >= 2: # FIXME - this is surprising
ctrls = self.__resolve_control(self.criteria)
@ -324,7 +326,7 @@ class WindowSpecification(object):
# if we get here then we must have only had one criteria so far
# so create a new :class:`WindowSpecification` for this control
new_item = WindowSpecification(self.criteria[0])
new_item = WindowSpecification(self.criteria[0], allow_magic_lookup=self.allow_magic_lookup)
# add our new criteria
new_item.criteria.append({"best_match": key})
@ -345,6 +347,21 @@ class WindowSpecification(object):
Otherwise delegate functionality to :func:`__getitem__` - which
sets the appropriate criteria for the control.
"""
allow_magic_lookup = object.__getattribute__(self, "allow_magic_lookup") # Beware of recursions here!
if not allow_magic_lookup:
try:
return object.__getattribute__(self, attr_name)
except AttributeError:
wrapper_object = self.wrapper_object()
try:
return getattr(wrapper_object, attr_name)
except AttributeError:
message = (
'Attribute "%s" exists neither on %s object nor on'
'targeted %s element wrapper (typo? or set allow_magic_lookup to True?)' %
(attr_name, self.__class__, wrapper_object.__class__))
raise AttributeError(message)
if attr_name in ['__dict__', '__members__', '__methods__', '__class__', '__name__']:
return object.__getattribute__(self, attr_name)
@ -354,10 +371,10 @@ class WindowSpecification(object):
if attr_name in self.__dict__:
return self.__dict__[attr_name]
# if we already have 2 levels of criteria (dlg, conrol)
# if we already have 2 levels of criteria (dlg, control)
# this third must be an attribute so resolve and get the
# attribute and return it
if len(self.criteria) >= 2:
if len(self.criteria) >= 2: # FIXME - this is surprising
ctrls = self.__resolve_control(self.criteria)
@ -366,6 +383,7 @@ class WindowSpecification(object):
except AttributeError:
return self.child_window(best_match=attr_name)
else:
# FIXME - I don't get this part at all, why is it win32-specific and why not keep the same logic as above?
# if we have been asked for an attribute of the dialog
# then resolve the window and return the attribute
desktop_wrapper = self.backend.generic_wrapper_class(self.backend.element_info_class())
@ -870,7 +888,7 @@ class Application(object):
.. automethod:: __getitem__
"""
def __init__(self, backend="win32", datafilename=None):
def __init__(self, backend="win32", datafilename=None, allow_magic_lookup=True):
"""
Initialize the Application object
@ -886,6 +904,7 @@ class Application(object):
if backend not in registry.backends:
raise ValueError('Backend "{0}" is not registered!'.format(backend))
self.backend = registry.backends[backend]
self.allow_magic_lookup = allow_magic_lookup
if self.backend.name == 'win32':
# Non PEP-8 aliases for partial backward compatibility
self.Start = deprecated(self.start)
@ -906,6 +925,10 @@ class Application(object):
self.match_history = pickle.load(datafile)
self.use_history = True
def __iter__(self):
"""Raise to avoid infinite loops"""
raise NotImplementedError("Object is not iterable, try to use .windows()")
def connect(self, **kwargs):
"""Connect to an already running process
@ -1139,7 +1162,7 @@ class Application(object):
else:
criteria['title'] = windows[0].name
return WindowSpecification(criteria)
return WindowSpecification(criteria, allow_magic_lookup=self.allow_magic_lookup)
def active(self):
"""Return WindowSpecification for an active window of the application"""
@ -1163,7 +1186,7 @@ class Application(object):
else:
criteria['title'] = windows[0].name
return WindowSpecification(criteria)
return WindowSpecification(criteria, allow_magic_lookup=self.allow_magic_lookup)
def windows(self, **kwargs):
"""Return a list of wrapped top level windows of the application"""
@ -1205,7 +1228,7 @@ class Application(object):
else:
# add the restriction for this particular application
kwargs['app'] = self
win_spec = WindowSpecification(kwargs)
win_spec = WindowSpecification(kwargs, allow_magic_lookup=self.allow_magic_lookup)
return win_spec
Window_ = window_ = window
@ -1216,6 +1239,17 @@ class Application(object):
return self.window(best_match=key)
def __getattribute__(self, attr_name):
allow_magic_lookup = object.__getattribute__(self, "allow_magic_lookup") # Beware of recursions here!
if not allow_magic_lookup:
try:
return object.__getattribute__(self, attr_name)
except AttributeError:
message = (
'Attribute "%s" doesn\'t exist on %s object'
' (typo? or set allow_magic_lookup to True?)' %
(attr_name, self.__class__))
raise AttributeError(message)
"""Find the specified dialog of the application"""
if attr_name in ['__dict__', '__members__', '__methods__', '__class__']:
return object.__getattribute__(self, attr_name)

@ -38,7 +38,6 @@ import ctypes
import locale
import re
import time
import win32process
import win32gui
import win32con
import win32api
@ -925,7 +924,8 @@ class BaseWrapper(object):
with_tabs = False,
with_newlines = False,
turn_off_numlock = True,
set_foreground = True):
set_foreground = True,
vk_packet = True):
"""
Type keys to the element using keyboard.send_keys
@ -945,7 +945,7 @@ class BaseWrapper(object):
# attach the Python process with the process that self is in
if self.element_info.handle:
window_thread_id, _ = win32process.GetWindowThreadProcessId(int(self.handle))
window_thread_id = win32functions.GetWindowThreadProcessId(self.handle, None)
win32functions.AttachThreadInput(win32functions.GetCurrentThreadId(), window_thread_id, win32defines.TRUE)
# TODO: check return value of AttachThreadInput properly
else:
@ -967,7 +967,8 @@ class BaseWrapper(object):
with_spaces,
with_tabs,
with_newlines,
turn_off_numlock)
turn_off_numlock,
vk_packet)
# detach the python process from the window's process
if self.element_info.handle:

@ -53,7 +53,6 @@ import warnings
import locale
import six
from .. import sysinfo
from .. import win32functions
from .. import win32defines
from .. import win32structures
@ -68,9 +67,6 @@ from ..handleprops import is64bitprocess
from ..sysinfo import is_x64_Python
from .. import deprecated
if sysinfo.UIA_support:
from ..uia_defines import IUIA
# Todo: I should return iterators from things like items() and texts()
# to save building full lists all the time
@ -135,7 +131,7 @@ class _listview_item(object):
item.iItem = self.item_index
item.iSubItem = self.subitem_index
item.stateMask = win32structures.UINT(-1)
item.stateMask = wintypes.UINT(-1)
item.cchTextMax = 2000
item.pszText = remote_mem.Address() + \
@ -501,9 +497,9 @@ class _listview_item(object):
lvitem = self.listview_ctrl.LVITEM()
lvitem.mask = win32structures.UINT(win32defines.LVIF_STATE)
lvitem.state = win32structures.UINT(index_to_state_image_mask(1)) # win32structures.UINT(0x1000)
lvitem.stateMask = win32structures.UINT(win32defines.LVIS_STATEIMAGEMASK)
lvitem.mask = wintypes.UINT(win32defines.LVIF_STATE)
lvitem.state = wintypes.UINT(index_to_state_image_mask(1)) # wintypes.UINT(0x1000)
lvitem.stateMask = wintypes.UINT(win32defines.LVIS_STATEIMAGEMASK)
remote_mem = RemoteMemoryBlock(self.listview_ctrl)
remote_mem.Write(lvitem)
@ -530,9 +526,9 @@ class _listview_item(object):
lvitem = self.listview_ctrl.LVITEM()
lvitem.mask = win32structures.UINT(win32defines.LVIF_STATE)
lvitem.state = win32structures.UINT(index_to_state_image_mask(2)) # win32structures.UINT(0x2000)
lvitem.stateMask = win32structures.UINT(win32defines.LVIS_STATEIMAGEMASK)
lvitem.mask = wintypes.UINT(win32defines.LVIF_STATE)
lvitem.state = wintypes.UINT(index_to_state_image_mask(2)) # wintypes.UINT(0x2000)
lvitem.stateMask = wintypes.UINT(win32defines.LVIS_STATEIMAGEMASK)
remote_mem = RemoteMemoryBlock(self.listview_ctrl)
remote_mem.Write(lvitem)
@ -591,12 +587,12 @@ class _listview_item(object):
# first we need to change the state of the item
lvitem = self.listview_ctrl.LVITEM()
lvitem.mask = win32structures.UINT(win32defines.LVIF_STATE)
lvitem.mask = wintypes.UINT(win32defines.LVIF_STATE)
if to_select:
lvitem.state = win32structures.UINT(win32defines.LVIS_FOCUSED | win32defines.LVIS_SELECTED)
lvitem.state = wintypes.UINT(win32defines.LVIS_FOCUSED | win32defines.LVIS_SELECTED)
lvitem.stateMask = win32structures.UINT(win32defines.LVIS_FOCUSED | win32defines.LVIS_SELECTED)
lvitem.stateMask = wintypes.UINT(win32defines.LVIS_FOCUSED | win32defines.LVIS_SELECTED)
remote_mem = RemoteMemoryBlock(self.listview_ctrl)
remote_mem.Write(lvitem, size=ctypes.sizeof(lvitem))
@ -721,10 +717,6 @@ class ListViewWrapper(hwndwrapper.HwndWrapper):
"TSysListView",
"ListView.*WndClass",
]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_ListControlTypeId
controltypes = []
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -1424,7 +1416,7 @@ class _treeview_element(object):
item.pszText = remote_mem.Address() + ctypes.sizeof(item) + 16
item.cchTextMax = 2000
item.hItem = self.elem
item.stateMask = win32structures.UINT(-1)
item.stateMask = wintypes.UINT(-1)
# Write the local TVITEM structure to the remote memory block
remote_mem.Write(item)
@ -1460,8 +1452,6 @@ class TreeViewWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "TreeView"
windowclasses = [
"SysTreeView32", r"WindowsForms\d*\.SysTreeView32\..*", "TTreeView", "TreeList.TreeListCtrl"]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_TreeControlTypeId]
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -1751,8 +1741,6 @@ class HeaderWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Header"
windowclasses = ["SysHeader32", "msvb_lib_header"]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_HeaderControlTypeId]
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -1894,8 +1882,6 @@ class StatusBarWrapper(hwndwrapper.HwndWrapper):
"msctls_statusbar32",
".*StatusBar",
r"WindowsForms\d*\.msctls_statusbar32\..*"]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_StatusBarControlTypeId]
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -2065,8 +2051,6 @@ class TabControlWrapper(hwndwrapper.HwndWrapper):
windowclasses = [
"SysTabControl32",
r"WindowsForms\d*\.SysTabControl32\..*"]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_TabControlTypeId]
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -2878,10 +2862,6 @@ class ReBarWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "ReBar"
windowclasses = ["ReBarWindow32", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -3086,8 +3066,6 @@ class UpDownWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "UpDown"
windowclasses = ["msctls_updown32", "msctls_updown", ]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_SpinnerControlTypeId]
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -3195,8 +3173,6 @@ class TrackbarWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Trackbar"
windowclasses = ["msctls_trackbar", ]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_SliderControlTypeId]
def get_range_min(self):
"""Get min available trackbar value"""
@ -3293,10 +3269,6 @@ class AnimationWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Animation"
windowclasses = ["SysAnimate32", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
#====================================================================
@ -3306,10 +3278,6 @@ class ComboBoxExWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "ComboBoxEx"
windowclasses = ["ComboBoxEx32", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
has_title = False
@ -3321,10 +3289,6 @@ class DateTimePickerWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "DateTimePicker"
windowclasses = ["SysDateTimePick32",
r"WindowsForms\d*\.SysDateTimePick32\..*", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
has_title = False
#----------------------------------------------------------------
@ -3387,10 +3351,6 @@ class HotkeyWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Hotkey"
windowclasses = ["msctls_hotkey32", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
has_title = False
@ -3401,10 +3361,6 @@ class IPAddressWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "IPAddress"
windowclasses = ["SysIPAddress32", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
has_title = False
@ -3415,8 +3371,6 @@ class CalendarWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Calendar"
windowclasses = ["SysMonthCal32", ]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_CalendarControlTypeId]
has_title = False
place_in_calendar = {
@ -3719,10 +3673,6 @@ class PagerWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Pager"
windowclasses = ["SysPager", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
#----------------------------------------------------------------
def get_position(self):
@ -3748,8 +3698,6 @@ class ProgressWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Progress"
windowclasses = ["msctls_progress", "msctls_progress32", ]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_ProgressBarControlTypeId]
has_title = False
#----------------------------------------------------------------

@ -493,7 +493,7 @@ class HwndWrapper(BaseWrapper):
(e.g. VK_LEFT, VK_DELETE), a KeySequenceError is raised. Consider using
the method send_keystrokes for such input.
"""
input_locale_id = ctypes.windll.User32.GetKeyboardLayout(0)
input_locale_id = win32functions.GetKeyboardLayout(0)
keys = keyboard.parse_keys(chars, with_spaces, with_tabs, with_newlines)
for key in keys:
@ -506,11 +506,11 @@ class HwndWrapper(BaseWrapper):
if unicode_char:
_, char = key_info[:2]
vk = ctypes.windll.User32.VkKeyScanExW(char, input_locale_id) & 0xFF
scan = keyboard.MapVirtualKey(vk, 0)
vk = win32functions.VkKeyScanExW(chr(char), input_locale_id) & 0xFF
scan = win32functions.MapVirtualKeyW(vk, 0)
else:
vk, scan = key_info[:2]
char = keyboard.MapVirtualKey(vk, 2)
char = win32functions.MapVirtualKeyW(vk, 2)
if char > 0:
lparam = 1 << 0 | scan << 16 | (flags & 1) << 24
@ -541,22 +541,21 @@ class HwndWrapper(BaseWrapper):
.. _`type_keys`: pywinauto.base_wrapper.html#pywinauto.base_wrapper.BaseWrapper.type_keys
"""
user32 = ctypes.windll.User32
PBYTE256 = ctypes.c_ubyte * 256
win32gui.SendMessage(self.handle, win32con.WM_ACTIVATE,
win32con.WA_ACTIVE, 0)
target_thread_id = user32.GetWindowThreadProcessId(self.handle, None)
current_thread_id = win32api.GetCurrentThreadId()
attach_success = user32.AttachThreadInput(target_thread_id, current_thread_id, True) != 0
target_thread_id = win32functions.GetWindowThreadProcessId(self.handle, None)
current_thread_id = win32functions.GetCurrentThreadId()
attach_success = win32functions.AttachThreadInput(target_thread_id, current_thread_id, True) != 0
if not attach_success:
warnings.warn('Failed to attach app\'s thread to the current thread\'s message queue',
UserWarning, stacklevel=2)
keyboard_state_stack = [PBYTE256()]
user32.GetKeyboardState(ctypes.byref(keyboard_state_stack[-1]))
win32functions.GetKeyboardState(keyboard_state_stack[-1])
input_locale_id = ctypes.windll.User32.GetKeyboardLayout(0)
input_locale_id = win32functions.GetKeyboardLayout(0)
context_code = 0
keys = keyboard.parse_keys(keystrokes, with_spaces, with_tabs, with_newlines)
@ -578,11 +577,11 @@ class HwndWrapper(BaseWrapper):
shift_state = 0
unicode_codepoint = flags & keyboard.KEYEVENTF_UNICODE != 0
if unicode_codepoint:
char = scan
vk_with_flags = user32.VkKeyScanExW(char, input_locale_id)
char = chr(scan)
vk_with_flags = win32functions.VkKeyScanExW(char, input_locale_id)
vk = vk_with_flags & 0xFF
shift_state = (vk_with_flags & 0xFF00) >> 8
scan = keyboard.MapVirtualKey(vk, 0)
scan = win32functions.MapVirtualKeyW(vk, 0)
if key.down and vk > 0:
new_keyboard_state = copy.deepcopy(keyboard_state_stack[-1])
@ -602,8 +601,8 @@ class HwndWrapper(BaseWrapper):
context_code << 29 |
0 << 31)
user32.SetKeyboardState(ctypes.byref(keyboard_state_stack[-1]))
win32api.PostMessage(self.handle, down_msg, vk, lparam)
win32functions.SetKeyboardState(keyboard_state_stack[-1])
win32functions.PostMessage(self.handle, down_msg, vk, lparam)
if vk == keyboard.VK_MENU:
context_code = 1
@ -621,8 +620,8 @@ class HwndWrapper(BaseWrapper):
1 << 30 |
1 << 31)
win32api.PostMessage(self.handle, up_msg, vk, lparam)
user32.SetKeyboardState(ctypes.byref(keyboard_state_stack[-1]))
win32functions.PostMessage(self.handle, up_msg, vk, lparam)
win32functions.SetKeyboardState(keyboard_state_stack[-1])
if vk == keyboard.VK_MENU:
context_code = 0
@ -636,10 +635,10 @@ class HwndWrapper(BaseWrapper):
UserWarning, stacklevel=2)
else:
warnings.warn(e.strerror, UserWarning, stacklevel=2)
user32.SetKeyboardState(ctypes.byref(keyboard_state_stack[0]))
win32functions.SetKeyboardState(keyboard_state_stack[0])
if attach_success:
user32.AttachThreadInput(target_thread_id, current_thread_id, False)
win32functions.AttachThreadInput(target_thread_id, current_thread_id, False)
# -----------------------------------------------------------
def send_message_timeout(
@ -1256,7 +1255,7 @@ class HwndWrapper(BaseWrapper):
"""Return a handle to the active window within the process"""
gui_info = win32structures.GUITHREADINFO()
gui_info.cbSize = ctypes.sizeof(gui_info)
window_thread_id, _ = win32process.GetWindowThreadProcessId(int(self.handle))
window_thread_id = win32functions.GetWindowThreadProcessId(self.handle, None)
ret = win32functions.GetGUIThreadInfo(
window_thread_id,
ctypes.byref(gui_info))
@ -1278,7 +1277,7 @@ class HwndWrapper(BaseWrapper):
"""
gui_info = win32structures.GUITHREADINFO()
gui_info.cbSize = ctypes.sizeof(gui_info)
window_thread_id, _ = win32process.GetWindowThreadProcessId(self.handle)
window_thread_id = win32functions.GetWindowThreadProcessId(self.handle, None)
ret = win32functions.GetGUIThreadInfo(
window_thread_id,
ctypes.byref(gui_info))
@ -1335,7 +1334,7 @@ class HwndWrapper(BaseWrapper):
def has_keyboard_focus(self):
"""Check the keyboard focus on this control."""
control_thread = win32process.GetWindowThreadProcessId(self.handle)[0]
control_thread = win32functions.GetWindowThreadProcessId(self.handle, None)
win32process.AttachThreadInput(control_thread, win32api.GetCurrentThreadId(), 1)
focused = win32gui.GetFocus()
win32process.AttachThreadInput(control_thread, win32api.GetCurrentThreadId(), 0)
@ -1346,9 +1345,9 @@ class HwndWrapper(BaseWrapper):
def set_keyboard_focus(self):
"""Set the keyboard focus to this control."""
control_thread = win32process.GetWindowThreadProcessId(self.handle)[0]
control_thread = win32functions.GetWindowThreadProcessId(self.handle, None)
win32process.AttachThreadInput(control_thread, win32api.GetCurrentThreadId(), 1)
win32gui.SetFocus(self.handle)
win32functions.SetFocus(self.handle)
win32process.AttachThreadInput(control_thread, win32api.GetCurrentThreadId(), 0)
win32functions.WaitGuiThreadIdle(self.handle)
@ -1602,12 +1601,13 @@ class DialogWrapper(HwndWrapper):
#win32defines.SMTO_BLOCK)
# get a handle we can wait on
_, pid = win32process.GetWindowThreadProcessId(int(self.handle))
pid = ctypes.c_ulong()
win32functions.GetWindowThreadProcessId(self.handle, ctypes.byref(pid))
try:
process_wait_handle = win32api.OpenProcess(
win32con.SYNCHRONIZE | win32con.PROCESS_TERMINATE,
0,
pid)
pid.value)
except win32gui.error:
return True # already closed
@ -1723,7 +1723,7 @@ def _perform_click(
# figure out the flags and pack coordinates
flags, click_point = _calc_flags_and_coords(pressed, coords)
#control_thread = win32functions.GetWindowThreadProcessId(ctrl, 0)
#control_thread = win32functions.GetWindowThreadProcessId(ctrl, None)
#win32functions.AttachThreadInput(win32functions.GetCurrentThreadId(), control_thread, win32defines.TRUE)
# TODO: check return value of AttachThreadInput properly

@ -283,7 +283,7 @@ class MenuItem(object):
# 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) and self.menu.owner_item:
if rect == win32structures.RECT(0, 0, 0, 0) and self.menu.owner_item:
self.menu.owner_item.click_input()
rect = self.rectangle()

@ -200,7 +200,11 @@ class ComboBoxWrapper(uiawrapper.UIAWrapper):
# -----------------------------------------------------------
def texts(self):
"""Return the text of the items in the combobox"""
texts = []
texts = self._texts_from_item_container()
if len(texts):
# flatten the list
return [ t for lst in texts for t in lst ]
# ComboBox has to be expanded to populate a list of its children items
try:
super(ComboBoxWrapper, self).expand()
@ -370,6 +374,11 @@ class EditWrapper(uiawrapper.UIAWrapper):
"""Return the current value of the element"""
return self.iface_value.CurrentValue
# -----------------------------------------------------------
def is_editable(self):
"""Return the edit possibility of the element"""
return not self.iface_value.CurrentIsReadOnly
# -----------------------------------------------------------
def texts(self):
"""Get the text of the edit control"""
@ -846,10 +855,19 @@ class ListViewWrapper(uiawrapper.UIAWrapper):
raise ValueError("Element '{0}' not found".format(row))
elif isinstance(row, six.integer_types):
# Get the item by a row index
# TODO: Can't get virtualized items that way
# TODO: See TODO section of item_count() method for details
list_items = self.children(content_only=True)
itm = list_items[self.__resolve_row_index(row)]
try:
com_elem = 0
for _ in range(0, self.__resolve_row_index(row) + 1):
com_elem = self.iface_item_container.FindItemByProperty(com_elem, 0, uia_defs.vt_empty)
# Try to load element using VirtualizedItem pattern
try:
get_elem_interface(com_elem, "VirtualizedItem").Realize()
except NoPatternInterfaceError:
pass
itm = uiawrapper.UIAWrapper(uia_element_info.UIAElementInfo(com_elem))
except (NoPatternInterfaceError, ValueError, AttributeError):
list_items = self.children(content_only=True)
itm = list_items[self.__resolve_row_index(row)]
else:
raise TypeError("String type or integer is expected")
@ -960,18 +978,18 @@ class MenuWrapper(uiawrapper.UIAWrapper):
return item
# -----------------------------------------------------------
@staticmethod
def _activate(item):
def _activate(self, item, is_last):
"""Activate the specified item"""
if not item.is_active():
item.set_focus()
try:
item.expand()
except(NoPatternInterfaceError):
pass
if self.element_info.framework_id == 'WinForm' and not is_last:
item.select()
# -----------------------------------------------------------
def _sub_item_by_text(self, menu, name, exact):
def _sub_item_by_text(self, menu, name, exact, is_last):
"""Find a menu sub-item by the specified text"""
sub_item = None
items = menu.items()
@ -987,18 +1005,18 @@ class MenuWrapper(uiawrapper.UIAWrapper):
texts.append(i.window_text())
sub_item = findbestmatch.find_best_match(name, texts, items)
self._activate(sub_item)
self._activate(sub_item, is_last)
return sub_item
# -----------------------------------------------------------
def _sub_item_by_idx(self, menu, idx):
def _sub_item_by_idx(self, menu, idx, is_last):
"""Find a menu sub-item by the specified index"""
sub_item = None
items = menu.items()
if items:
sub_item = items[idx]
self._activate(sub_item)
self._activate(sub_item, is_last)
return sub_item
# -----------------------------------------------------------
@ -1011,35 +1029,39 @@ class MenuWrapper(uiawrapper.UIAWrapper):
Note: $ - specifier is not supported
"""
# Get the path parts
part0, parts = path.split("->", 1)
part0 = part0.strip()
if len(part0) == 0:
menu_items = [p.strip() for p in path.split("->")]
items_cnt = len(menu_items)
if items_cnt == 0:
raise IndexError()
for item in menu_items:
if not item:
raise IndexError("Empty item name between '->' separators")
def next_level_menu(parent_menu, item_name, is_last):
if item_name.startswith("#"):
return self._sub_item_by_idx(parent_menu, int(item_name[1:]), is_last)
else:
return self._sub_item_by_text(parent_menu, item_name, exact, is_last)
# Find a top level menu item and select it. After selecting this item
# a new Menu control is created and placed on the dialog. It can be
# a direct child or a descendant.
# Sometimes we need to re-discover Menu again
try:
menu = None
if part0.startswith("#"):
menu = self._sub_item_by_idx(self, int(part0[1:]))
else:
menu = self._sub_item_by_text(self, part0, exact)
menu = next_level_menu(self, menu_items[0], items_cnt == 1)
if items_cnt == 1:
return menu
if not menu.items():
self._activate(menu)
self._activate(menu, False)
timings.wait_until(
timings.Timings.window_find_timeout,
timings.Timings.window_find_retry,
lambda: len(self.top_level_parent().descendants(control_type="Menu")) > 0)
menu = self.top_level_parent().descendants(control_type="Menu")[0]
for cur_part in [p.strip() for p in parts.split("->")]:
if cur_part.startswith("#"):
menu = self._sub_item_by_idx(menu, int(cur_part[1:]))
else:
menu = self._sub_item_by_text(menu, cur_part, exact)
for i in range(1, items_cnt):
menu = next_level_menu(menu, menu_items[i], items_cnt == i + 1)
except(AttributeError):
raise IndexError()

@ -782,5 +782,19 @@ class UIAWrapper(BaseWrapper):
return self
# -----------------------------------------------------------
def _texts_from_item_container(self):
"""Get texts through the ItemContainer interface"""
texts = []
try:
com_elem = self.iface_item_container.FindItemByProperty(0, 0, uia_defs.vt_empty)
while com_elem:
itm = UIAWrapper(UIAElementInfo(com_elem))
texts.append(itm.texts())
com_elem = self.iface_item_container.FindItemByProperty(com_elem, 0, uia_defs.vt_empty)
except (uia_defs.NoPatternInterfaceError):
pass
return texts
backend.register('uia', UIAElementInfo, UIAWrapper)

@ -331,8 +331,9 @@ def get_control_names(control, allcontrols, textcontrols):
if non_text_names:
names.extend(non_text_names)
# return the names - and make sure there are no duplicates
return set(names)
# return the names - and make sure there are no duplicates or empty values
cleaned_names = set(names) - set([None, ""])
return cleaned_names
#====================================================================
@ -493,6 +494,8 @@ def find_best_control_matches(search_text, controls):
"""
name_control_map = build_unique_dict(controls)
#print ">>>>>>>", repr(name_control_map).decode("ascii", "ignore")
# # collect all the possible names for all controls
# # and build a list of them
# for ctrl in controls:

@ -189,9 +189,10 @@ def find_elements(class_name=None,
if top_level_only:
# find the top level elements
element = backend_obj.element_info_class()
# vryabov: we don't use title=title below, because it fixes issue 779:
# https://github.com/pywinauto/pywinauto/issues/779
elements = element.children(process=process,
class_name=class_name,
title=title,
control_type=control_type,
cache_enable=True)
@ -206,8 +207,9 @@ def find_elements(class_name=None,
parent = backend_obj.element_info_class()
# look for ALL children of that parent
# vryabov: we don't use title=title below, because it fixes issue 779:
# https://github.com/pywinauto/pywinauto/issues/779
elements = parent.descendants(class_name=class_name,
title=title,
control_type=control_type,
cache_enable=True,
depth=depth)

@ -35,14 +35,18 @@ These are implemented in a procedural way so as to to be
useful to other modules with the least conceptual overhead
"""
import ctypes
import warnings
import win32process
import win32api
import win32con
import win32gui
import pywintypes
from ctypes import wintypes
from ctypes import WINFUNCTYPE
from ctypes import c_int
from ctypes import byref
from ctypes import sizeof
from ctypes import create_unicode_buffer
from . import win32functions
from . import win32defines
from . import win32structures
@ -58,7 +62,7 @@ def text(handle):
if class_name == 'MSCTFIME UI':
return 'M'
if class_name is None:
return None
return ''
#length = win32functions.SendMessage(handle, win32defines.WM_GETTEXTLENGTH, 0, 0)
# XXX: there are some very rare cases when WM_GETTEXTLENGTH hangs!
@ -71,11 +75,11 @@ def text(handle):
0,
win32defines.SMTO_ABORTIFHUNG,
500,
ctypes.byref(c_length)
byref(c_length)
)
if result == 0:
ActionLogger().log('WARNING! Cannot retrieve text length for handle = ' + str(handle))
return None
return ''
else:
length = c_length.value
@ -85,10 +89,10 @@ def text(handle):
if length > 0:
length += 1
buffer_ = ctypes.create_unicode_buffer(length)
buffer_ = create_unicode_buffer(length)
ret = win32functions.SendMessage(
handle, win32defines.WM_GETTEXT, length, ctypes.byref(buffer_))
handle, win32defines.WM_GETTEXT, length, byref(buffer_))
if ret:
textval = buffer_.value
@ -101,7 +105,7 @@ def classname(handle):
"""Return the class name of the window"""
if handle is None:
return None
class_name = ctypes.create_unicode_buffer(u"", 257)
class_name = create_unicode_buffer(u"", 257)
win32functions.GetClassName(handle, class_name, 256)
return class_name.value
@ -145,13 +149,13 @@ def contexthelpid(handle):
#=========================================================================
def iswindow(handle):
"""Return True if the handle is a window"""
return False if handle is None else bool(win32functions.IsWindow(handle))
return False if handle is None else bool(win32functions.IsWindow(handle))
#=========================================================================
def isvisible(handle):
"""Return True if the window is visible"""
return False if handle is None else bool(win32functions.IsWindowVisible(handle))
return False if handle is None else bool(win32functions.IsWindowVisible(handle))
#=========================================================================
@ -192,8 +196,8 @@ def is64bitbinary(filename):
binary_type = win32file.GetBinaryType(filename)
return binary_type != win32file.SCS_32BIT_BINARY
except Exception as exc:
warnings.warn('Cannot get binary type for file "{}". Error: {}' \
''.format(filename, exc), RuntimeWarning, stacklevel=2)
warnings.warn('Cannot get binary type for file "{}". Error: {}'
.format(filename, exc), RuntimeWarning, stacklevel=2)
return None
@ -201,24 +205,24 @@ def is64bitbinary(filename):
def clientrect(handle):
"""Return the client rectangle of the control"""
client_rect = win32structures.RECT()
win32functions.GetClientRect(handle, ctypes.byref(client_rect))
win32functions.GetClientRect(handle, byref(client_rect))
return client_rect
#=========================================================================
def rectangle(handle):
"""Return the rectangle of the window"""
# GetWindowRect returns 4-tuple
try:
return win32structures.RECT(*win32gui.GetWindowRect(handle))
except pywintypes.error:
return win32structures.RECT()
rect = win32structures.RECT()
win32functions.GetWindowRect(handle, byref(rect))
return rect
#=========================================================================
def font(handle):
"""Return the font as a LOGFONTW of the window"""
# get the font handle
if handle is None:
handle = 0 # make sure we don't pass window handle down as None
font_handle = win32functions.SendMessage(
handle, win32defines.WM_GETFONT, 0, 0)
@ -244,15 +248,10 @@ def font(handle):
font_handle = win32functions.GetStockObject(
win32defines.ANSI_VAR_FONT)
else:
fontval = win32structures.LOGFONTW()
ret = win32functions.GetObject(
font_handle, ctypes.sizeof(fontval), ctypes.byref(fontval))
# Get the Logfont structure of the font of the control
fontval = win32structures.LOGFONTW()
ret = win32functions.GetObject(
font_handle, ctypes.sizeof(fontval), ctypes.byref(fontval))
font_handle, sizeof(fontval), byref(fontval))
# The function could not get the font - this is probably
# because the control does not have associated Font/Text
@ -271,11 +270,11 @@ def font(handle):
# get the title font based on the system metrics rather
# than the font of the control itself
ncms = win32structures.NONCLIENTMETRICSW()
ncms.cbSize = ctypes.sizeof(ncms)
ncms.cbSize = sizeof(ncms)
win32functions.SystemParametersInfo(
win32defines.SPI_GETNONCLIENTMETRICS,
ctypes.sizeof(ncms),
ctypes.byref(ncms),
sizeof(ncms),
byref(ncms),
0)
# with either of the following 2 flags set the font of the
@ -293,8 +292,9 @@ def font(handle):
#=========================================================================
def processid(handle):
"""Return the ID of process that controls this window"""
_, process_id = win32process.GetWindowThreadProcessId(int(handle))
return process_id
pid = wintypes.DWORD()
win32functions.GetWindowThreadProcessId(handle, byref(pid))
return pid.value
#=========================================================================
@ -327,10 +327,10 @@ def children(handle):
return True
# define the child proc type
enum_child_proc_t = ctypes.WINFUNCTYPE(
ctypes.c_int, # return type
win32structures.HWND, # the window handle
win32structures.LPARAM) # extra information
enum_child_proc_t = WINFUNCTYPE(
c_int, # return type
wintypes.HWND, # the window handle
wintypes.LPARAM) # extra information
# update the proc to the correct type
proc = enum_child_proc_t(enum_child_proc)

@ -64,6 +64,8 @@ below. The module is also available on Linux.
{VK_F19}, {VK_EXECUTE}, {VK_PLAY}, {VK_RMENU}, {VK_F13}, {VK_F12}, {LWIN},
{VK_DOWN}, {VK_F17}, {VK_F16}, {VK_F15}, {VK_F14}
~ is a shorter alias for {ENTER}
**Modifiers:**
- ``'+': {VK_SHIFT}``
@ -96,10 +98,19 @@ Use curly brackers to escape modifiers and type reserved symbols as single keys:
send_keys('{^}a{^}c{%}') # type string "^a^c%" (Ctrl will not be pressed)
send_keys('{{}ENTER{}}') # type string "{ENTER}" without pressing Enter key
For Windows only, pywinauto defaults to sending a virtual key packet
(VK_PACKET) for textual input. For applications that do not handle VK_PACKET
appropriately, the ``vk_packet`` option may be set to ``False``. In this case
pywinauto will attempt to send the virtual key code of the requested key. This
option only affects the behavior of keys matching [-=[]\;',./a-zA-Z0-9 ]. Note
that upper and lower case are included for a-z. Both reference the same
virtual key for convenience.
"""
from __future__ import unicode_literals
import sys
import string
from . import deprecated
@ -113,6 +124,7 @@ else:
import six
from . import win32structures
from . import win32functions
__all__ = ['KeySequenceError', 'send_keys']
@ -120,17 +132,6 @@ else:
DEBUG = 0
GetMessageExtraInfo = ctypes.windll.user32.GetMessageExtraInfo
MapVirtualKey = ctypes.windll.user32.MapVirtualKeyW
SendInput = ctypes.windll.user32.SendInput
UINT = ctypes.c_uint
SendInput.restype = UINT
SendInput.argtypes = [UINT, ctypes.c_void_p, ctypes.c_int]
VkKeyScan = ctypes.windll.user32.VkKeyScanW
VkKeyScan.restype = ctypes.c_short
VkKeyScan.argtypes = [ctypes.c_wchar]
INPUT_KEYBOARD = 1
KEYEVENTF_EXTENDEDKEY = 1
KEYEVENTF_KEYUP = 2
@ -310,6 +311,29 @@ else:
'%': VK_MENU,
}
# Virtual keys that map to an ASCII character
# See https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
ascii_vk = {
' ': 0x20,
'=': 0xbb,
',': 0xbc,
'-': 0xbd,
'.': 0xbe,
# According to the above reference, the following characters vary per region.
# This mapping applies to US keyboards
';': 0xba,
'/': 0xbf,
'`': 0xc0,
'[': 0xdb,
'\\': 0xdc,
']': 0xdd,
'\'': 0xde,
}
# [0-9A-Z] map exactly to their ASCII counterparts
ascii_vk.update(dict((c, ord(c)) for c in string.ascii_uppercase + string.digits))
# map [a-z] to their uppercase ASCII counterparts
ascii_vk.update(dict((c, ord(c.upper())) for c in string.ascii_lowercase))
class KeySequenceError(Exception):
@ -368,7 +392,7 @@ else:
# it seems to return 0 every time but it's required by MSDN specification
# so call it just in case
inp.ki.dwExtraInfo = GetMessageExtraInfo()
inp.ki.dwExtraInfo = win32functions.GetMessageExtraInfo()
# if we are releasing - then let it up
if self.up:
@ -381,7 +405,7 @@ else:
inputs = self.GetInput()
# SendInput() supports all Unicode symbols
num_inserted_events = SendInput(len(inputs), ctypes.byref(inputs),
num_inserted_events = win32functions.SendInput(len(inputs), ctypes.byref(inputs),
ctypes.sizeof(win32structures.INPUT))
if num_inserted_events != len(inputs):
raise RuntimeError('SendInput() inserted only ' + str(num_inserted_events) +
@ -447,7 +471,7 @@ else:
# return self.key, 0, 0
# this works for Tic Tac Toe i.e. +{RIGHT} SHIFT + RIGHT
return self.key, MapVirtualKey(self.key, 0), flags
return self.key, win32functions.MapVirtualKeyW(self.key, 0), flags
def run(self):
"""Execute the action"""
@ -468,9 +492,9 @@ else:
The vk and scan code are generated differently.
"""
vkey_scan = LoByte(VkKeyScan(self.key))
vkey_scan = LoByte(win32functions.VkKeyScanW(self.key))
return (vkey_scan, MapVirtualKey(vkey_scan, 0), 0)
return (vkey_scan, win32functions.MapVirtualKeyW(vkey_scan, 0), 0)
def key_description(self):
"""Return a description of the key"""
@ -500,7 +524,7 @@ else:
__repr__ = __str__
def handle_code(code):
def handle_code(code, vk_packet):
"""Handle a key or sequence of keys in braces"""
code_keys = []
# it is a known code (e.g. {DOWN}, {ENTER}, etc)
@ -509,7 +533,10 @@ else:
# it is an escaped modifier e.g. {%}, {^}, {+}
elif len(code) == 1:
code_keys.append(KeyAction(code))
if not vk_packet and code in ascii_vk:
code_keys.append(VirtualKeyAction(ascii_vk[code]))
else:
code_keys.append(KeyAction(code))
# it is a repetition or a pause {DOWN 5}, {PAUSE 1.3}
elif ' ' in code:
@ -535,7 +562,7 @@ else:
[VirtualKeyAction(CODES[to_repeat])] * count)
# otherwise parse the keys and we get back a KeyAction
else:
to_repeat = parse_keys(to_repeat)
to_repeat = parse_keys(to_repeat, vk_packet=vk_packet)
if isinstance(to_repeat, list):
keys = to_repeat * count
else:
@ -550,7 +577,8 @@ else:
with_spaces=False,
with_tabs=False,
with_newlines=False,
modifiers=None):
modifiers=None,
vk_packet=True):
"""Return the parsed keys"""
keys = []
if not modifiers:
@ -579,8 +607,10 @@ else:
end_pos = string.find(")", index)
if end_pos == -1:
raise KeySequenceError('`)` not found')
keys.extend(
parse_keys(string[index:end_pos], modifiers=modifiers))
keys.extend(parse_keys(
string[index:end_pos],
modifiers=modifiers,
vk_packet=vk_packet))
index = end_pos + 1
# Escape or named key
@ -597,7 +627,7 @@ else:
if any(key_event in code.lower() for key_event in key_events):
code, current_key_event = code.split(' ')
should_escape_next_keys = True
current_keys = handle_code(code)
current_keys = handle_code(code, vk_packet)
if current_key_event is not None:
if isinstance(current_keys[0].key, six.string_types):
current_keys[0] = EscapedKeyAction(current_keys[0].key)
@ -636,6 +666,11 @@ else:
elif modifiers or should_escape_next_keys:
keys.append(EscapedKeyAction(c))
# if user disables the vk_packet option, always try to send a
# virtual key of the actual keystroke
elif not vk_packet and c in ascii_vk:
keys.append(VirtualKeyAction(ascii_vk[c]))
else:
keys.append(KeyAction(c))
@ -667,9 +702,12 @@ else:
with_spaces=False,
with_tabs=False,
with_newlines=False,
turn_off_numlock=True):
turn_off_numlock=True,
vk_packet=True):
"""Parse the keys and type them"""
keys = parse_keys(keys, with_spaces, with_tabs, with_newlines)
keys = parse_keys(
keys, with_spaces, with_tabs, with_newlines,
vk_packet=vk_packet)
for k in keys:
k.run()

@ -382,7 +382,7 @@ class PauseAction(KeyAction):
__repr__ = __str__
def handle_code(code):
def handle_code(code, vk_packet=True):
"""Handle a key or sequence of keys in braces"""
code_keys = []
# it is a known code (e.g. {DOWN}, {ENTER}, etc)
@ -433,7 +433,8 @@ def parse_keys(string,
with_spaces = False,
with_tabs = False,
with_newlines = False,
modifiers = None):
modifiers = None,
vk_packet=True):
"""Return the parsed keys"""
keys = []
if not modifiers:
@ -523,7 +524,8 @@ def send_keys(keys,
with_spaces=False,
with_tabs=False,
with_newlines=False,
turn_off_numlock=True):
turn_off_numlock=True,
vk_packet=True):
"""Parse the keys and type them"""
keys = parse_keys(keys, with_spaces, with_tabs, with_newlines)
for k in keys:

@ -35,10 +35,15 @@ Win32 API functions to perform custom marshalling
from __future__ import print_function
import sys
import ctypes
import win32api
import win32process
from ctypes import wintypes
from ctypes import c_void_p
from ctypes import pointer
from ctypes import sizeof
from ctypes import byref
from ctypes import c_size_t
from ctypes import WinError
from . import win32functions
from . import win32defines
from . import win32structures
@ -70,10 +75,12 @@ class RemoteMemoryBlock(object):
self._as_parameter_ = self.mem_address
_, process_id = win32process.GetWindowThreadProcessId(self.handle)
pid = wintypes.DWORD()
win32functions.GetWindowThreadProcessId(self.handle, byref(pid))
process_id = pid.value
if not process_id:
raise AccessDenied(
str(ctypes.WinError()) + " Cannot get process ID from handle.")
str(WinError()) + " Cannot get process ID from handle.")
self.process = win32functions.OpenProcess(
win32defines.PROCESS_VM_OPERATION |
@ -85,12 +92,12 @@ class RemoteMemoryBlock(object):
if not self.process:
raise AccessDenied(
str(ctypes.WinError()) + "process: %d",
str(WinError()) + "process: %d",
process_id)
self.mem_address = win32functions.VirtualAllocEx(
ctypes.c_void_p(self.process), # remote process
ctypes.c_void_p(0), # let Valloc decide where
c_void_p(self.process), # remote process
c_void_p(0), # let Valloc decide where
win32structures.ULONG_PTR(self.size + 4), # how much to allocate
win32defines.MEM_RESERVE | \
win32defines.MEM_COMMIT, # allocation type
@ -100,7 +107,7 @@ class RemoteMemoryBlock(object):
self.mem_address = self.mem_address.value
if self.mem_address == 0:
raise ctypes.WinError()
raise WinError()
if hex(self.mem_address) == '0xffffffff80000000' or hex(self.mem_address).upper() == '0xFFFFFFFF00000000':
raise Exception('Incorrect allocation: ' + hex(self.mem_address))
@ -108,11 +115,11 @@ class RemoteMemoryBlock(object):
self._as_parameter_ = self.mem_address
# write guard signature at the end of memory block
signature = win32structures.LONG(0x66666666)
signature = wintypes.LONG(0x66666666)
ret = win32functions.WriteProcessMemory(
ctypes.c_void_p(self.process),
ctypes.c_void_p(self.mem_address + self.size),
ctypes.pointer(signature),
c_void_p(self.process),
c_void_p(self.mem_address + self.size),
pointer(signature),
win32structures.ULONG_PTR(4),
win32structures.ULONG_PTR(0)
)
@ -129,7 +136,7 @@ class RemoteMemoryBlock(object):
if ret == 0:
ActionLogger().log('Warning: cannot close process handle!')
#raise ctypes.WinError()
#raise WinError()
#----------------------------------------------------------------
def CleanUp(self):
@ -140,17 +147,17 @@ class RemoteMemoryBlock(object):
self.CheckGuardSignature()
ret = win32functions.VirtualFreeEx(
ctypes.c_void_p(self.process),
ctypes.c_void_p(self.mem_address),
c_void_p(self.process),
c_void_p(self.mem_address),
win32structures.ULONG_PTR(0),
win32structures.DWORD(win32defines.MEM_RELEASE))
wintypes.DWORD(win32defines.MEM_RELEASE))
if ret == 0:
print('Error: CleanUp: VirtualFreeEx() returned zero for address ', hex(self.mem_address))
last_error = win32api.GetLastError()
print('LastError = ', last_error, ': ', win32api.FormatMessage(last_error).rstrip())
sys.stdout.flush()
self._CloseHandle()
raise ctypes.WinError()
raise WinError()
self.mem_address = 0
self._CloseHandle()
else:
@ -180,7 +187,7 @@ class RemoteMemoryBlock(object):
if size:
nSize = win32structures.ULONG_PTR(size)
else:
nSize = win32structures.ULONG_PTR(ctypes.sizeof(data))
nSize = win32structures.ULONG_PTR(sizeof(data))
if self.size < nSize.value:
raise Exception(('Write: RemoteMemoryBlock is too small ({0} bytes),' +
@ -190,19 +197,19 @@ class RemoteMemoryBlock(object):
raise Exception('Write: RemoteMemoryBlock has incorrect address = ' + hex(address))
ret = win32functions.WriteProcessMemory(
ctypes.c_void_p(self.process),
ctypes.c_void_p(address),
ctypes.pointer(data),
c_void_p(self.process),
c_void_p(address),
pointer(data),
nSize,
win32structures.ULONG_PTR(0)
)
if ret == 0:
ActionLogger().log('Error: Write failed: address = ', address)
ActionLogger().log('Error: Write failed: address = ' + str(address))
last_error = win32api.GetLastError()
ActionLogger().log('Error: LastError = ', last_error, ': ',
ActionLogger().log('Error: LastError = ' + str(last_error) + ': ' +
win32api.FormatMessage(last_error).rstrip())
raise ctypes.WinError()
raise WinError()
self.CheckGuardSignature()
#----------------------------------------------------------------
@ -216,7 +223,7 @@ class RemoteMemoryBlock(object):
if size:
nSize = win32structures.ULONG_PTR(size)
else:
nSize = win32structures.ULONG_PTR(ctypes.sizeof(data))
nSize = win32structures.ULONG_PTR(sizeof(data))
if self.size < nSize.value:
raise Exception(('Read: RemoteMemoryBlock is too small ({0} bytes),' +
@ -225,14 +232,14 @@ class RemoteMemoryBlock(object):
if hex(address).lower().startswith('0xffffff'):
raise Exception('Read: RemoteMemoryBlock has incorrect address =' + hex(address))
lpNumberOfBytesRead = ctypes.c_size_t(0)
lpNumberOfBytesRead = c_size_t(0)
ret = win32functions.ReadProcessMemory(
ctypes.c_void_p(self.process),
ctypes.c_void_p(address),
ctypes.byref(data),
c_void_p(self.process),
c_void_p(address),
byref(data),
nSize,
ctypes.byref(lpNumberOfBytesRead)
byref(lpNumberOfBytesRead)
)
# disabled as it often returns an error - but
@ -240,27 +247,27 @@ class RemoteMemoryBlock(object):
if ret == 0:
# try again
ret = win32functions.ReadProcessMemory(
ctypes.c_void_p(self.process),
ctypes.c_void_p(address),
ctypes.byref(data),
c_void_p(self.process),
c_void_p(address),
byref(data),
nSize,
ctypes.byref(lpNumberOfBytesRead)
byref(lpNumberOfBytesRead)
)
if ret == 0:
last_error = win32api.GetLastError()
if last_error != win32defines.ERROR_PARTIAL_COPY:
ActionLogger().log('Read: WARNING! self.mem_address =' +
hex(self.mem_address) + ' data address =' + str(ctypes.byref(data)))
hex(self.mem_address) + ' data address =' + str(byref(data)))
ActionLogger().log('LastError = ' + str(last_error) +
': ' + win32api.FormatMessage(last_error).rstrip())
else:
ActionLogger().log('Error: ERROR_PARTIAL_COPY')
ActionLogger().log('\nRead: WARNING! self.mem_address =' +
hex(self.mem_address) + ' data address =' + str(ctypes.byref(data)))
hex(self.mem_address) + ' data address =' + str(byref(data)))
ActionLogger().log('lpNumberOfBytesRead =' +
str(lpNumberOfBytesRead) + ' nSize =' + str(nSize))
raise ctypes.WinError()
raise WinError()
else:
ActionLogger().log('Warning! Read OK: 2nd attempt!')
#else:
@ -273,18 +280,18 @@ class RemoteMemoryBlock(object):
def CheckGuardSignature(self):
"""read guard signature at the end of memory block"""
signature = win32structures.LONG(0)
lpNumberOfBytesRead = ctypes.c_size_t(0)
lpNumberOfBytesRead = c_size_t(0)
ret = win32functions.ReadProcessMemory(
ctypes.c_void_p(self.process),
ctypes.c_void_p(self.mem_address + self.size),
ctypes.pointer(signature), # 0x66666666
c_void_p(self.process),
c_void_p(self.mem_address + self.size),
pointer(signature), # 0x66666666
win32structures.ULONG_PTR(4),
ctypes.byref(lpNumberOfBytesRead))
byref(lpNumberOfBytesRead))
if ret == 0:
ActionLogger().log('Error: Failed to read guard signature: address = ' +
hex(self.mem_address) + ', size = ' + str(self.size) +
', lpNumberOfBytesRead = ' + str(lpNumberOfBytesRead))
raise ctypes.WinError()
raise WinError()
else:
if hex(signature.value) != '0x66666666':
raise Exception('---------------------------------------- ' +

@ -82,8 +82,8 @@ class IUIA(object):
end_len = len('ControlTypeId')
self._control_types = [attr[start_len:-end_len] for attr in dir(self.UIA_dll) if attr.endswith('ControlTypeId')]
self.known_control_types = {} # string id: numeric id
self.known_control_type_ids = {} # numeric id: string id
self.known_control_types = { 'InvalidControlType': 0 } # string id: numeric id
self.known_control_type_ids = { 0: 'InvalidControlType' } # numeric id: string id
for ctrl_type in self._control_types:
type_id_name = 'UIA_' + ctrl_type + 'ControlTypeId'
@ -218,6 +218,8 @@ scroll_no_amount = IUIA().ui_automation_client.ScrollAmount_NoAmount
scroll_large_increment = IUIA().ui_automation_client.ScrollAmount_LargeIncrement
scroll_small_increment = IUIA().ui_automation_client.ScrollAmount_SmallIncrement
vt_empty = IUIA().ui_automation_client.VARIANT.empty.vt
vt_null = IUIA().ui_automation_client.VARIANT.null.vt
def get_elem_interface(element_info, pattern_name):
"""A helper to retrieve an element interface by the specified pattern name

@ -79,7 +79,6 @@ windll.user32.SetWindowsHookExA.restype = wintypes.HHOOK
windll.user32.SetWindowsHookExA.argtypes = [c_int, HOOKCB, wintypes.HINSTANCE, wintypes.DWORD]
windll.user32.SetWindowsHookExW.restype = wintypes.HHOOK
windll.user32.SetWindowsHookExW.argtypes = [c_int, HOOKCB, wintypes.HINSTANCE, wintypes.DWORD]
windll.user32.GetMessageW.argtypes = [POINTER(wintypes.MSG), wintypes.HWND, c_uint, c_uint]
windll.user32.TranslateMessage.argtypes = [POINTER(wintypes.MSG)]
windll.user32.DispatchMessageW.argtypes = [POINTER(wintypes.MSG)]
@ -452,7 +451,7 @@ class Hook(object):
al = ActionLogger()
al.log("_process_kbd_msg_type, bad event_type: {0}".format(event_type))
if event_type == 'key down':
if event_type == 'key down' and current_key not in self.pressed_keys:
self.pressed_keys.append(current_key)
elif event_type == 'key up':
if current_key in self.pressed_keys:

@ -31,192 +31,678 @@
"""Defines Windows(tm) functions"""
import ctypes
from ctypes import LibraryLoader
from ctypes import WinDLL
from ctypes import wintypes
from . import win32defines, win32structures
from .actionlogger import ActionLogger
from ctypes import c_uint, c_short, c_long
from ctypes import c_short
from ctypes import WINFUNCTYPE
from ctypes import c_void_p
from ctypes import c_int
from ctypes import byref
from ctypes import POINTER
from ctypes import c_ubyte
from ctypes import c_size_t
# Quote: "If you want cached libs without polluting ctypes.cdll or
# ctypes.windll, just create your own instance such as
# windll = ctypes.LibraryLoader(ctypes.WinDLL)."
# see https://bugs.python.org/issue22552
windll = LibraryLoader(WinDLL)
import sys
if sys.platform == "cygwin":
windll = ctypes.cdll
HRESULT = c_long
UINT = c_uint
SHORT = c_short
CreateBrushIndirect = ctypes.windll.gdi32.CreateBrushIndirect
CreateDC = ctypes.windll.gdi32.CreateDCW
CreateFontIndirect = ctypes.windll.gdi32.CreateFontIndirectW
CreatePen = ctypes.windll.gdi32.CreatePen
DeleteDC = ctypes.windll.gdi32.DeleteDC
GetObject = ctypes.windll.gdi32.GetObjectW
DeleteObject = ctypes.windll.gdi32.DeleteObject
DrawText = ctypes.windll.user32.DrawTextW
TextOut = ctypes.windll.gdi32.TextOutW
Rectangle = ctypes.windll.gdi32.Rectangle
SelectObject = ctypes.windll.gdi32.SelectObject
GetStockObject = ctypes.windll.gdi32.GetStockObject
GetSystemMetrics = ctypes.windll.user32.GetSystemMetrics
GetSystemMetrics.restype = ctypes.c_int
GetSystemMetrics.argtypes = (ctypes.c_int, )
GetTextMetrics = ctypes.windll.gdi32.GetTextMetricsW
EnumChildWindows = ctypes.windll.user32.EnumChildWindows
EnumDesktopWindows = ctypes.windll.user32.EnumDesktopWindows
EnumWindows = ctypes.windll.user32.EnumWindows
GetDC = ctypes.windll.user32.GetDC
GetDesktopWindow = ctypes.windll.user32.GetDesktopWindow
SendInput = ctypes.windll.user32.SendInput
SetCursorPos = ctypes.windll.user32.SetCursorPos
GetCursorPos = ctypes.windll.user32.GetCursorPos
GetCaretPos = ctypes.windll.user32.GetCaretPos
CreateBrushIndirect = windll.gdi32.CreateBrushIndirect
CreateBrushIndirect.restype = wintypes.HBRUSH
CreateBrushIndirect.argtypes = [
c_void_p,
]
CreateDC = windll.gdi32.CreateDCW
CreateDC.restype = wintypes.HDC
CreateDC.argtypes = [
wintypes.LPCWSTR,
wintypes.LPCWSTR,
wintypes.LPCWSTR,
c_void_p,
]
CreateFontIndirect = windll.gdi32.CreateFontIndirectW
CreateFontIndirect.restype = wintypes.HFONT
CreateFontIndirect.argtypes = [
POINTER(win32structures.LOGFONTW),
]
CreatePen = windll.gdi32.CreatePen
CreatePen.restype = wintypes.HPEN
CreatePen.argtypes = [
c_int,
c_int,
wintypes.COLORREF,
]
DeleteDC = windll.gdi32.DeleteDC
DeleteDC.restype = wintypes.BOOL
DeleteDC.argtypes = [
wintypes.HDC,
]
GetObject = windll.gdi32.GetObjectW
GetObject.restype = c_int
GetObject.argtypes = [
wintypes.HANDLE,
c_int,
wintypes.LPVOID,
]
DeleteObject = windll.gdi32.DeleteObject
DeleteObject.restype = wintypes.BOOL
DeleteObject.argtypes = [
wintypes.HGDIOBJ,
]
DrawText = windll.user32.DrawTextW
DrawText.restype = c_int
DrawText.argtypes = [
wintypes.HDC,
wintypes.LPCWSTR,
c_int,
POINTER(wintypes.RECT),
wintypes.UINT,
]
TextOut = windll.gdi32.TextOutW
TextOut.restype = wintypes.BOOL
TextOut.argtypes = [
wintypes.HDC,
c_int,
c_int,
wintypes.LPCWSTR,
c_int,
]
Rectangle = windll.gdi32.Rectangle
Rectangle.restype = wintypes.BOOL
Rectangle.argtypes = [
wintypes.HDC,
c_int,
c_int,
c_int,
c_int,
]
SelectObject = windll.gdi32.SelectObject
SelectObject.restype = wintypes.HGDIOBJ
SelectObject.argtypes = [
wintypes.HDC,
wintypes.HGDIOBJ,
]
GetStockObject = windll.gdi32.GetStockObject
GetStockObject.restype = wintypes.HGDIOBJ
GetStockObject.argtypes = [
c_int,
]
GetSystemMetrics = windll.user32.GetSystemMetrics
GetSystemMetrics.restype = c_int
GetSystemMetrics.argtypes = [
c_int,
]
GetTextMetrics = windll.gdi32.GetTextMetricsW
GetTextMetrics.restype = wintypes.BOOL
GetTextMetrics.argtypes = [
wintypes.HDC,
POINTER(win32structures.TEXTMETRICW),
]
EnumChildWindows = windll.user32.EnumChildWindows
EnumChildWindows.restype = wintypes.BOOL
EnumChildWindows.argtypes = [
wintypes.HWND,
WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM),
wintypes.LPARAM,
]
EnumDesktopWindows = windll.user32.EnumDesktopWindows
EnumDesktopWindows.restype = wintypes.BOOL
EnumDesktopWindows.argtypes = [
wintypes.LPVOID,
WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM),
wintypes.LPARAM,
]
EnumWindows = windll.user32.EnumWindows
EnumWindows.restype = wintypes.BOOL
EnumWindows.argtypes = [
WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM),
wintypes.LPARAM,
]
GetDC = windll.user32.GetDC
GetDC.restype = wintypes.LPVOID
GetDC.argtypes = [
wintypes.HWND,
]
GetDesktopWindow = windll.user32.GetDesktopWindow
GetDesktopWindow.restype = wintypes.HWND
GetDesktopWindow.argtypes = [
]
SendInput = windll.user32.SendInput
SendInput.restype = wintypes.UINT
SendInput.argtypes = [
wintypes.UINT,
c_void_p, # using POINTER(win32structures.INPUT) needs rework in keyboard.py
c_int,
]
SetCursorPos = windll.user32.SetCursorPos
SetCursorPos.restype = wintypes.BOOL
SetCursorPos.argtypes = [
c_int,
c_int,
]
GetCursorPos = windll.user32.GetCursorPos
GetCursorPos.restype = wintypes.BOOL
GetCursorPos.argtypes = [
POINTER(wintypes.POINT),
]
GetCaretPos = windll.user32.GetCaretPos
GetCaretPos.restype = wintypes.BOOL
GetCaretPos.argtypes = [
POINTER(wintypes.POINT),
]
GetKeyboardState = windll.user32.GetKeyboardState
GetKeyboardState.restype = wintypes.BOOL
GetKeyboardState.argtypes = [
POINTER(c_ubyte),
]
SetKeyboardState = windll.user32.SetKeyboardState
SetKeyboardState.restype = wintypes.BOOL
SetKeyboardState.argtypes = [
POINTER(c_ubyte),
]
GetKeyboardLayout = windll.user32.GetKeyboardLayout
GetKeyboardLayout.restype = wintypes.HKL
GetKeyboardLayout.argtypes = [
wintypes.DWORD,
]
VkKeyScanW = windll.user32.VkKeyScanW
VkKeyScanW.restype = SHORT
VkKeyScanW.argtypes = [
wintypes.WCHAR,
]
VkKeyScanExW = windll.user32.VkKeyScanExW
VkKeyScanExW.restype = SHORT
VkKeyScanExW.argtypes = [
wintypes.WCHAR,
wintypes.HKL,
]
GetMessageExtraInfo = windll.user32.GetMessageExtraInfo
MapVirtualKeyW = windll.user32.MapVirtualKeyW
# menu functions
DrawMenuBar = ctypes.windll.user32.DrawMenuBar
GetMenu = ctypes.windll.user32.GetMenu
GetMenuBarInfo = ctypes.windll.user32.GetMenuBarInfo
GetMenuInfo = ctypes.windll.user32.GetMenuInfo
GetMenuItemCount = ctypes.windll.user32.GetMenuItemCount
GetMenuItemInfo = ctypes.windll.user32.GetMenuItemInfoW
SetMenuItemInfo = ctypes.windll.user32.SetMenuItemInfoW
GetMenuItemRect = ctypes.windll.user32.GetMenuItemRect
CheckMenuItem = ctypes.windll.user32.CheckMenuItem
GetMenuState = ctypes.windll.user32.GetMenuState
GetSubMenu = ctypes.windll.user32.GetSubMenu
GetSystemMenu = ctypes.windll.user32.GetSystemMenu
HiliteMenuItem = ctypes.windll.user32.HiliteMenuItem
IsMenu = ctypes.windll.user32.IsMenu
MenuItemFromPoint = ctypes.windll.user32.MenuItemFromPoint
BringWindowToTop = ctypes.windll.user32.BringWindowToTop
GetVersion = ctypes.windll.kernel32.GetVersion
GetParent = ctypes.windll.user32.GetParent
GetWindow = ctypes.windll.user32.GetWindow
ShowWindow = ctypes.windll.user32.ShowWindow
GetWindowContextHelpId = ctypes.windll.user32.GetWindowContextHelpId
GetWindowLong = ctypes.windll.user32.GetWindowLongW
GetWindowPlacement = ctypes.windll.user32.GetWindowPlacement
GetWindowRect = ctypes.windll.user32.GetWindowRect
GetWindowText = ctypes.windll.user32.GetWindowTextW
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
GetClassName = ctypes.windll.user32.GetClassNameW
GetClassName.argtypes = [win32structures.HWND, wintypes.LPWSTR, ctypes.c_int]
GetClassName.restrype = ctypes.c_int
GetClientRect = ctypes.windll.user32.GetClientRect
IsChild = ctypes.windll.user32.IsChild
IsWindow = ctypes.windll.user32.IsWindow
IsWindow.argtypes = [win32structures.HWND]
IsWindow.restype = win32structures.BOOL
IsWindowUnicode = ctypes.windll.user32.IsWindowUnicode
IsWindowUnicode.argtypes = [win32structures.HWND]
IsWindowUnicode.restype = win32structures.BOOL
IsWindowVisible = ctypes.windll.user32.IsWindowVisible
IsWindowVisible.argtypes = [win32structures.HWND]
IsWindowVisible.restype = win32structures.BOOL
IsWindowEnabled = ctypes.windll.user32.IsWindowEnabled
IsWindowEnabled.argtypes = [win32structures.HWND]
IsWindowEnabled.restype = win32structures.BOOL
ClientToScreen = ctypes.windll.user32.ClientToScreen
ScreenToClient = ctypes.windll.user32.ScreenToClient
GetCurrentThreadId = ctypes.windll.Kernel32.GetCurrentThreadId
GetWindowThreadProcessId = ctypes.windll.user32.GetWindowThreadProcessId
GetGUIThreadInfo = ctypes.windll.user32.GetGUIThreadInfo
AttachThreadInput = ctypes.windll.user32.AttachThreadInput
AttachThreadInput.restype = win32structures.BOOL
AttachThreadInput.argtypes = [win32structures.DWORD, win32structures.DWORD, win32structures.BOOL]
#GetWindowThreadProcessId = ctypes.windll.user32.GetWindowThreadProcessId
GetLastError = ctypes.windll.kernel32.GetLastError
OpenProcess = ctypes.windll.kernel32.OpenProcess
CloseHandle = ctypes.windll.kernel32.CloseHandle
CreateProcess = ctypes.windll.kernel32.CreateProcessW
TerminateProcess = ctypes.windll.kernel32.TerminateProcess
ExitProcess = ctypes.windll.kernel32.ExitProcess
ReadProcessMemory = ctypes.windll.kernel32.ReadProcessMemory
GlobalAlloc = ctypes.windll.kernel32.GlobalAlloc
GlobalLock = ctypes.windll.kernel32.GlobalLock
GlobalUnlock = ctypes.windll.kernel32.GlobalUnlock
SendMessage = ctypes.windll.user32.SendMessageW
SendMessageTimeout = ctypes.windll.user32.SendMessageTimeoutW
SendMessageTimeout.argtypes = [win32structures.HWND, win32structures.UINT, win32structures.WPARAM,
win32structures.LPARAM, win32structures.UINT, win32structures.UINT,
win32structures.PDWORD_PTR]
SendMessageTimeout.restype = win32structures.LRESULT
SendMessageA = ctypes.windll.user32.SendMessageA
PostMessage = ctypes.windll.user32.PostMessageW
GetMessage = ctypes.windll.user32.GetMessageW
RegisterWindowMessage = ctypes.windll.user32.RegisterWindowMessageW
RegisterWindowMessage.restype = UINT
MoveWindow = ctypes.windll.user32.MoveWindow
EnableWindow = ctypes.windll.user32.EnableWindow
SetActiveWindow = ctypes.windll.user32.SetActiveWindow
GetFocus = ctypes.windll.user32.GetFocus
SetFocus = ctypes.windll.user32.SetFocus
SetForegroundWindow = ctypes.windll.user32.SetForegroundWindow
GetForegroundWindow = ctypes.windll.user32.GetForegroundWindow
SetWindowLong = ctypes.windll.user32.SetWindowLongW
DrawMenuBar = windll.user32.DrawMenuBar
DrawMenuBar.restype = wintypes.BOOL
DrawMenuBar.argstype = [
wintypes.HWND,
]
GetMenu = windll.user32.GetMenu
GetMenu.restype = wintypes.HMENU
GetMenu.argtypes = [
wintypes.HWND,
]
GetMenuBarInfo = windll.user32.GetMenuBarInfo
GetMenuBarInfo.restype = wintypes.BOOL
GetMenuBarInfo.argtypes = [
wintypes.HWND,
wintypes.LONG,
wintypes.LONG,
POINTER(win32structures.MENUBARINFO),
]
GetMenuInfo = windll.user32.GetMenuInfo
GetMenuInfo.restype = wintypes.BOOL
GetMenuInfo.argtypes = [
wintypes.HWND,
POINTER(win32structures.MENUINFO),
]
GetMenuItemCount = windll.user32.GetMenuItemCount
GetMenuItemCount.restype = c_int
GetMenuItemCount.argtypes = [
wintypes.HMENU,
]
GetMenuItemInfo = windll.user32.GetMenuItemInfoW
GetMenuItemInfo.restype = wintypes.BOOL
GetMenuItemInfo.argtypes = [
wintypes.HMENU,
wintypes.UINT,
wintypes.BOOL,
POINTER(win32structures.MENUITEMINFOW),
]
SetMenuItemInfo = windll.user32.SetMenuItemInfoW
SetMenuItemInfo.restype = wintypes.BOOL
SetMenuItemInfo.argtypes = [
wintypes.HMENU,
wintypes.UINT,
wintypes.BOOL,
POINTER(win32structures.MENUITEMINFOW),
]
GetMenuItemRect = windll.user32.GetMenuItemRect
GetMenuItemRect.restype = wintypes.BOOL
GetMenuItemRect.argtypes = [
wintypes.HWND,
wintypes.HMENU,
wintypes.UINT,
POINTER(wintypes.RECT),
]
CheckMenuItem = windll.user32.CheckMenuItem
CheckMenuItem.restype = wintypes.DWORD
CheckMenuItem.argtypes = [
wintypes.HMENU,
wintypes.UINT,
wintypes.UINT,
]
GetMenuState = windll.user32.GetMenuState
GetMenuState.restype = wintypes.UINT
GetMenuState.argtypes = [
wintypes.HMENU,
wintypes.UINT,
wintypes.UINT,
]
GetSubMenu = windll.user32.GetSubMenu
GetSubMenu.restype = wintypes.HMENU
GetSubMenu.argtypes = [
wintypes.HMENU,
c_int,
]
GetSystemMenu = windll.user32.GetSystemMenu
GetSystemMenu.restype = wintypes.HMENU
GetSystemMenu.argtypes = [
wintypes.HWND,
wintypes.BOOL,
]
HiliteMenuItem = windll.user32.HiliteMenuItem
HiliteMenuItem.restype = wintypes.BOOL
HiliteMenuItem.argtypes = [
wintypes.HWND,
wintypes.HMENU,
wintypes.UINT,
wintypes.UINT,
]
IsMenu = windll.user32.IsMenu
IsMenu.restype = wintypes.BOOL
IsMenu.argtypes = [
wintypes.HMENU,
]
MenuItemFromPoint = windll.user32.MenuItemFromPoint
MenuItemFromPoint.restype = c_int
MenuItemFromPoint.argtypes = [
wintypes.HWND,
wintypes.HMENU,
POINTER(wintypes.POINT),
]
BringWindowToTop = windll.user32.BringWindowToTop
BringWindowToTop.restype = wintypes.BOOL
BringWindowToTop.argtypes = [
wintypes.HWND,
]
GetParent = windll.user32.GetParent
GetParent.restype = wintypes.HWND
GetParent.argtypes = [
wintypes.HWND,
]
GetWindow = windll.user32.GetWindow
GetWindow.restype = wintypes.HWND
GetWindow.argtypes = [
wintypes.HWND,
wintypes.UINT,
]
ShowWindow = windll.user32.ShowWindow
ShowWindow.restype = wintypes.BOOL
ShowWindow.argtypes = [
wintypes.HWND,
c_int,
]
GetWindowContextHelpId = windll.user32.GetWindowContextHelpId
GetWindowContextHelpId.restype = wintypes.DWORD
GetWindowContextHelpId.argtypes = [
wintypes.HWND,
]
GetWindowLong = windll.user32.GetWindowLongW
GetWindowLong.restype = wintypes.LONG
GetWindowLong.argtypes = [
wintypes.HWND,
c_int,
]
GetWindowPlacement = windll.user32.GetWindowPlacement
GetWindowPlacement.restype = wintypes.BOOL
GetWindowPlacement.argtypes = [
wintypes.HWND,
POINTER(win32structures.WINDOWPLACEMENT),
]
GetWindowRect = windll.user32.GetWindowRect
GetWindowRect.restype = wintypes.BOOL
GetWindowRect.argtypes = [
wintypes.HWND,
POINTER(wintypes.RECT),
]
GetWindowText = windll.user32.GetWindowTextW
GetWindowText.restype = c_int
GetWindowText.argtypes = [
wintypes.HWND,
wintypes.LPWSTR,
c_int,
]
GetWindowTextLength = windll.user32.GetWindowTextLengthW
GetWindowTextLength.restype = c_int
GetWindowTextLength.argtypes = [
wintypes.HWND,
]
GetClassName = windll.user32.GetClassNameW
GetClassName.restype = c_int
GetClassName.argtypes = [
wintypes.HWND,
wintypes.LPWSTR,
c_int,
]
GetClientRect = windll.user32.GetClientRect
GetClientRect.restype = wintypes.BOOL
GetClientRect.argtypes = [
wintypes.HWND,
POINTER(wintypes.RECT),
]
IsChild = windll.user32.IsChild
IsChild.restype = wintypes.BOOL
IsChild.argtypes = [
wintypes.HWND,
wintypes.HWND,
]
IsWindow = windll.user32.IsWindow
IsWindow.restype = wintypes.BOOL
IsWindow.argtypes = [
wintypes.HWND,
]
IsWindowUnicode = windll.user32.IsWindowUnicode
IsWindowUnicode.restype = wintypes.BOOL
IsWindowUnicode.argtypes = [
wintypes.HWND,
]
IsWindowVisible = windll.user32.IsWindowVisible
IsWindowVisible.restype = wintypes.BOOL
IsWindowVisible.argtypes = [
wintypes.HWND,
]
IsWindowEnabled = windll.user32.IsWindowEnabled
IsWindowEnabled.restype = wintypes.BOOL
IsWindowEnabled.argtypes = [
wintypes.HWND,
]
ClientToScreen = windll.user32.ClientToScreen
ClientToScreen.restype = wintypes.BOOL
ClientToScreen.argtypes = [
wintypes.HWND,
POINTER(wintypes.POINT),
]
ScreenToClient = windll.user32.ScreenToClient
ScreenToClient.restype = wintypes.BOOL
ScreenToClient.argtypes = [
wintypes.HWND,
POINTER(wintypes.POINT),
]
GetCurrentThreadId = windll.kernel32.GetCurrentThreadId
GetCurrentThreadId.restype = wintypes.DWORD
GetCurrentThreadId.argtypes = [
]
GetWindowThreadProcessId = windll.user32.GetWindowThreadProcessId
GetWindowThreadProcessId.restype = wintypes.DWORD
GetWindowThreadProcessId.argtypes = [
wintypes.HWND,
POINTER(wintypes.DWORD),
]
GetGUIThreadInfo = windll.user32.GetGUIThreadInfo
GetGUIThreadInfo.restype = wintypes.BOOL
GetGUIThreadInfo.argtypes = [
wintypes.DWORD,
POINTER(win32structures.GUITHREADINFO),
]
AttachThreadInput = windll.user32.AttachThreadInput
AttachThreadInput.restype = wintypes.BOOL
AttachThreadInput.argtypes = [
wintypes.DWORD,
wintypes.DWORD,
wintypes.BOOL
]
OpenProcess = windll.kernel32.OpenProcess
OpenProcess.restype = wintypes.HANDLE
OpenProcess.argtypes = [
wintypes.DWORD,
wintypes.BOOL,
wintypes.DWORD,
]
CloseHandle = windll.kernel32.CloseHandle
CloseHandle.restype = wintypes.BOOL
CloseHandle.argtypes = [
wintypes.HANDLE,
]
CreateProcess = windll.kernel32.CreateProcessW
CreateProcess.restype = wintypes.BOOL
CreateProcess.argtypes = [
wintypes.LPCWSTR,
wintypes.LPWSTR,
POINTER(win32structures.SECURITY_ATTRIBUTES),
POINTER(win32structures.SECURITY_ATTRIBUTES),
wintypes.BOOL,
wintypes.DWORD,
wintypes.LPVOID,
wintypes.LPCWSTR,
POINTER(win32structures.STARTUPINFOW),
POINTER(win32structures.PROCESS_INFORMATION),
]
TerminateProcess = windll.kernel32.TerminateProcess
TerminateProcess.restype = wintypes.BOOL
TerminateProcess.argtypes = [
wintypes.HANDLE,
wintypes.UINT,
]
ExitProcess = windll.kernel32.ExitProcess
ExitProcess.restype = None
ExitProcess.argtypes = [
wintypes.UINT,
]
ReadProcessMemory = windll.kernel32.ReadProcessMemory
ReadProcessMemory.restype = wintypes.BOOL
ReadProcessMemory.argtypes = [
wintypes.HANDLE,
wintypes.LPVOID,
wintypes.LPVOID,
c_size_t,
POINTER(c_size_t),
]
GlobalAlloc = windll.kernel32.GlobalAlloc
GlobalLock = windll.kernel32.GlobalLock
GlobalUnlock = windll.kernel32.GlobalUnlock
SendMessage = windll.user32.SendMessageW
SendMessage.restype = wintypes.LPARAM
SendMessage.argtypes = [
wintypes.HWND,
wintypes.UINT,
wintypes.WPARAM,
wintypes.LPVOID,
]
SendMessageTimeout = windll.user32.SendMessageTimeoutW
SendMessageTimeout.restype = wintypes.LPARAM
SendMessageTimeout.argtypes = [
wintypes.HWND,
wintypes.UINT,
wintypes.WPARAM,
wintypes.LPARAM,
wintypes.UINT,
wintypes.UINT,
win32structures.PDWORD_PTR,
]
PostMessage = windll.user32.PostMessageW
PostMessage.restype = wintypes.BOOL
PostMessage.argtypes = [
wintypes.HWND,
wintypes.UINT,
wintypes.WPARAM,
wintypes.LPARAM,
]
GetMessage = windll.user32.GetMessageW
GetMessage.restype = wintypes.BOOL
GetMessage.argtypes = [
POINTER(wintypes.MSG),
wintypes.HWND,
wintypes.UINT,
wintypes.UINT,
]
RegisterWindowMessage = windll.user32.RegisterWindowMessageW
RegisterWindowMessage.restype = wintypes.UINT
RegisterWindowMessage.argtypes = [
wintypes.LPCWSTR,
]
MoveWindow = windll.user32.MoveWindow
MoveWindow.restype = wintypes.BOOL
MoveWindow.argtypes = [
wintypes.HWND,
c_int,
c_int,
c_int,
c_int,
wintypes.BOOL,
]
EnableWindow = windll.user32.EnableWindow
EnableWindow.restype = wintypes.BOOL
EnableWindow.argtypes = [
wintypes.HWND,
wintypes.BOOL,
]
SetFocus = windll.user32.SetFocus
SetFocus.restype = wintypes.HWND
SetFocus.argtypes = [
wintypes.HWND,
]
SetWindowLong = windll.user32.SetWindowLongW
SetWindowLong.restype = wintypes.LONG
SetWindowLong.argtypes = [
wintypes.HWND,
c_int,
wintypes.LONG,
]
try:
SetWindowLongPtr = ctypes.windll.user32.SetWindowLongPtrW
SetWindowLongPtr.argtypes = [win32structures.HWND, ctypes.c_int, win32structures.LONG_PTR]
SetWindowLongPtr.restype = win32structures.LONG_PTR
SetWindowLongPtr = windll.user32.SetWindowLongPtrW
SetWindowLongPtr.argtypes = [wintypes.HWND, c_int, wintypes.LONG_PTR]
SetWindowLongPtr.restype = wintypes.LONG_PTR
except AttributeError:
SetWindowLongPtr = SetWindowLong
SystemParametersInfo = ctypes.windll.user32.SystemParametersInfoW
VirtualAllocEx = ctypes.windll.kernel32.VirtualAllocEx
VirtualAllocEx.restype = ctypes.c_void_p
VirtualFreeEx = ctypes.windll.kernel32.VirtualFreeEx
DebugBreakProcess = ctypes.windll.kernel32.DebugBreakProcess
VirtualAlloc = ctypes.windll.kernel32.VirtualAlloc
VirtualFree = ctypes.windll.kernel32.VirtualFree
WriteProcessMemory = ctypes.windll.kernel32.WriteProcessMemory
GetActiveWindow = ctypes.windll.user32.GetActiveWindow
GetLastActivePopup = ctypes.windll.user32.GetLastActivePopup
FindWindow = ctypes.windll.user32.FindWindowW
GetTopWindow = ctypes.windll.user32.GetTopWindow
SetCapture = ctypes.windll.user32.SetCapture
ReleaseCapture = ctypes.windll.user32.ReleaseCapture
ShowOwnedPopups = ctypes.windll.user32.ShowOwnedPopups
WindowFromPoint = ctypes.windll.user32.WindowFromPoint
WideCharToMultiByte = ctypes.windll.kernel32.WideCharToMultiByte
GetACP = ctypes.windll.kernel32.GetACP
WaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject
WaitForInputIdle = ctypes.windll.user32.WaitForInputIdle
IsHungAppWindow = ctypes.windll.user32.IsHungAppWindow
IsHungAppWindow.restype = win32structures.BOOL
IsHungAppWindow.argtypes = [win32structures.HWND]
GetModuleFileNameEx = ctypes.windll.psapi.GetModuleFileNameExW
GetClipboardData = ctypes.windll.user32.GetClipboardData
OpenClipboard = ctypes.windll.user32.OpenClipboard
EmptyClipboard = ctypes.windll.user32.EmptyClipboard
CloseClipboard = ctypes.windll.user32.CloseClipboard
CountClipboardFormats = ctypes.windll.user32.CountClipboardFormats
EnumClipboardFormats = ctypes.windll.user32.EnumClipboardFormats
GetClipboardFormatName = ctypes.windll.user32.GetClipboardFormatNameW
SystemParametersInfo = windll.user32.SystemParametersInfoW
SystemParametersInfo.restype = wintypes.UINT
SystemParametersInfo.argtypes = [
wintypes.UINT,
wintypes.UINT,
wintypes.LPVOID, # should map well to PVOID
wintypes.UINT,
]
VirtualAllocEx = windll.kernel32.VirtualAllocEx
VirtualAllocEx.restype = wintypes.LPVOID
VirtualAllocEx.argtypes = [
wintypes.HANDLE,
wintypes.LPVOID,
c_size_t,
wintypes.DWORD,
wintypes.DWORD,
]
VirtualFreeEx = windll.kernel32.VirtualFreeEx
VirtualFreeEx.restype = wintypes.BOOL
VirtualFreeEx.argtypes = [
wintypes.HANDLE,
wintypes.LPVOID,
c_size_t,
wintypes.DWORD,
]
VirtualAlloc = windll.kernel32.VirtualAlloc
VirtualAlloc.restype = wintypes.LPVOID
VirtualAlloc.argtypes = [
wintypes.LPVOID,
c_size_t,
wintypes.DWORD,
wintypes.DWORD,
]
VirtualFree = windll.kernel32.VirtualFree
VirtualFree.retype = wintypes.BOOL
VirtualFree.argtypes = [
wintypes.LPVOID,
c_size_t,
wintypes.DWORD,
]
WriteProcessMemory = windll.kernel32.WriteProcessMemory
WriteProcessMemory.restype = wintypes.BOOL
WriteProcessMemory.argtypes = [
wintypes.HANDLE,
wintypes.LPVOID,
wintypes.LPVOID,
c_size_t,
POINTER(c_size_t),
]
ReleaseCapture = windll.user32.ReleaseCapture
ReleaseCapture.restype = wintypes.BOOL
ReleaseCapture.argtypes = [
]
WindowFromPoint = windll.user32.WindowFromPoint
WindowFromPoint.restype = wintypes.HWND
WindowFromPoint.argtypes = [
wintypes.POINT,
]
WaitForSingleObject = windll.kernel32.WaitForSingleObject
WaitForSingleObject.restype = wintypes.DWORD
WaitForSingleObject.argtypes = [
wintypes.HANDLE,
wintypes.DWORD,
]
WaitForInputIdle = windll.user32.WaitForInputIdle
WaitForInputIdle.restype = wintypes.DWORD
WaitForInputIdle.argtypes = [
wintypes.HANDLE,
wintypes.DWORD,
]
IsHungAppWindow = windll.user32.IsHungAppWindow
IsHungAppWindow.restype = wintypes.BOOL
IsHungAppWindow.argtypes = [
wintypes.HWND,
]
GetModuleFileNameEx = windll.psapi.GetModuleFileNameExW
GetModuleFileNameEx.restype = wintypes.DWORD
GetModuleFileNameEx.argtypes = [
wintypes.HANDLE,
wintypes.HMODULE,
wintypes.LPWSTR,
wintypes.DWORD,
]
GetClipboardData = windll.user32.GetClipboardData
GetClipboardData.restype = wintypes.HANDLE
GetClipboardData.argtypes = [
wintypes.UINT,
]
OpenClipboard = windll.user32.OpenClipboard
OpenClipboard.restype = wintypes.BOOL
OpenClipboard.argtypes = [
wintypes.HWND,
]
EmptyClipboard = windll.user32.EmptyClipboard
EmptyClipboard.restype = wintypes.BOOL
EmptyClipboard.argtypes = [
]
CloseClipboard = windll.user32.CloseClipboard
CloseClipboard.restype = wintypes.BOOL
CloseClipboard.argtypes = [
]
CountClipboardFormats = windll.user32.CountClipboardFormats
CountClipboardFormats.restype = c_int
CountClipboardFormats.argtypes = [
]
EnumClipboardFormats = windll.user32.EnumClipboardFormats
EnumClipboardFormats.restype = wintypes.UINT
EnumClipboardFormats.argtypes = [
wintypes.UINT,
]
GetClipboardFormatName = windll.user32.GetClipboardFormatNameW
GetClipboardFormatName.restype = c_int
GetClipboardFormatName.argtypes = [
wintypes.UINT,
wintypes.LPWSTR,
c_int,
]
# DPIAware API funcs are not available on WinXP
try:
IsProcessDPIAware = ctypes.windll.user32.IsProcessDPIAware
SetProcessDPIAware = ctypes.windll.user32.SetProcessDPIAware
IsProcessDPIAware = windll.user32.IsProcessDPIAware
SetProcessDPIAware = windll.user32.SetProcessDPIAware
except AttributeError:
IsProcessDPIAware = None
SetProcessDPIAware = None
@ -230,7 +716,7 @@ except AttributeError:
# Process_Per_Monitor_DPI_Aware = 2
# } Process_DPI_Awareness;
try:
shcore = ctypes.windll.LoadLibrary("Shcore.dll")
shcore = windll.LoadLibrary("Shcore.dll")
SetProcessDpiAwareness = shcore.SetProcessDpiAwareness
GetProcessDpiAwareness = shcore.GetProcessDpiAwareness
Process_DPI_Awareness = {
@ -252,26 +738,17 @@ elif SetProcessDPIAware:
ActionLogger().log("Call SetProcessDPIAware")
SetProcessDPIAware()
GetQueueStatus = ctypes.windll.user32.GetQueueStatus
GetQueueStatus = windll.user32.GetQueueStatus
LoadString = ctypes.windll.user32.LoadStringW
LoadString = windll.user32.LoadStringW
#def VkKeyScanW(p1):
# # C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4225
# return VkKeyScanW._api_(p1)
#VkKeyScan = stdcall(SHORT, 'user32', [c_wchar]) (VkKeyScanW)
#
#def MapVirtualKeyExW(p1, p2, p3):
# # C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4376
# return MapVirtualKeyExW._api_(p1, p2, p3)
#MapVirtualKeyEx = stdcall(
# UINT, 'user32', [c_uint, c_uint, c_long]) (MapVirtualKeyExW)
#
#def MapVirtualKeyW(p1, p2):
# # C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4355
# return MapVirtualKeyW._api_(p1, p2)
#MapVirtualKey = stdcall(UINT, 'user32', [c_uint, c_uint]) (MapVirtualKeyW)
#====================================================================
@ -297,7 +774,7 @@ def LoWord(value):
def WaitGuiThreadIdle(handle):
"""Wait until the thread of the specified handle is ready"""
process_id = wintypes.DWORD(0)
GetWindowThreadProcessId(handle, ctypes.POINTER(wintypes.DWORD)(process_id))
GetWindowThreadProcessId(handle, byref(process_id))
# ask the control if it has finished processing the message
hprocess = OpenProcess(
@ -327,10 +804,10 @@ def GetDpiAwarenessByPid(pid):
return dpi_awareness
try:
dpi_awareness = ctypes.c_int()
dpi_awareness = c_int()
hRes = GetProcessDpiAwareness(
hProcess,
ctypes.byref(dpi_awareness))
byref(dpi_awareness))
CloseHandle(hProcess)
if hRes == 0:
return dpi_awareness.value

@ -32,19 +32,18 @@
"""Definition of Windows structures"""
import six
import ctypes
from ctypes import Structure as Struct
from ctypes import \
c_int, c_uint, c_long, c_ulong, c_void_p, c_wchar, c_char, \
c_ubyte, c_ushort, \
c_int, c_long, c_void_p, c_char, memmove, addressof, \
POINTER, sizeof, alignment, Union, c_longlong, c_size_t, wintypes
from .win32defines import LF_FACESIZE
from . import sysinfo
class Structure(ctypes.Structure):
class StructureMixIn(object):
"""Override the Structure class from ctypes to add printing and comparison"""
"""Define printing and comparison behaviors to be used for the Structure class from ctypes"""
#----------------------------------------------------------------
def __str__(self):
@ -52,47 +51,59 @@ class Structure(ctypes.Structure):
fields in exceptList will not be printed"""
lines = []
for f in self._fields_:
name = f[0]
lines.append("%20s\t%s"% (name, getattr(self, name)))
for field_name, _ in getattr(self, "_fields_", []):
lines.append("%20s\t%s"% (field_name, getattr(self, field_name)))
return "\n".join(lines)
#----------------------------------------------------------------
def __eq__(self, other_struct):
"""Return True if the two structures have the same coordinates"""
if isinstance(other_struct, ctypes.Structure):
def __eq__(self, other):
"""Return True if the two instances have the same coordinates"""
fields = getattr(self, "_fields_", [])
if isinstance(other, Struct):
try:
# pretend they are two structures - check that they both
# have the same value for all fields
are_equal = True
for field in self._fields_:
name = field[0]
if getattr(self, name) != getattr(other_struct, name):
are_equal = False
break
return are_equal
if len(fields) != len(getattr(other, "_fields_", [])):
return False
for field_name, _ in fields:
if getattr(self, field_name) != getattr(other, field_name):
return False
return True
except AttributeError:
return False
if isinstance(other_struct, (list, tuple)):
elif isinstance(other, (list, tuple)):
# Now try to see if we have been passed in a list or tuple
if len(fields) != len(other):
return False
try:
are_equal = True
for i, field in enumerate(self._fields_):
name = field[0]
if getattr(self, name) != other_struct[i]:
are_equal = False
break
return are_equal
for i, (field_name, _) in enumerate(fields):
if getattr(self, field_name) != other[i]:
return False
return True
except Exception:
return False
return False
#----------------------------------------------------------------
def __ne__(self, other):
"""Return False if the two instances have the same coordinates"""
return not self.__eq__(other)
__hash__ = None
class Structure(Struct, StructureMixIn):
"""Override the Structure class from ctypes to add printing and comparison"""
pass
##====================================================================
#def PrintCtypesStruct(struct, exceptList = []):
# """Print out the fields of the ctypes Structure
@ -110,7 +121,7 @@ class Structure(ctypes.Structure):
# e.g. RECT.__reduce__ = _reduce
def _construct(typ, buf):
obj = typ.__new__(typ)
ctypes.memmove(ctypes.addressof(obj), buf, len(buf))
memmove(addressof(obj), buf, len(buf))
return obj
def _reduce(self):
@ -119,21 +130,21 @@ def _reduce(self):
#LPTTTOOLINFOW = POINTER(tagTOOLINFOW)
#PTOOLINFOW = POINTER(tagTOOLINFOW)
BOOL = c_int
BYTE = c_ubyte
BOOL = wintypes.BOOL
BYTE = wintypes.BYTE
CHAR = c_char
DWORD = c_ulong
HANDLE = c_void_p
HBITMAP = c_long
LONG = c_long
LPVOID = c_void_p
DWORD = wintypes.DWORD
HANDLE = wintypes.HANDLE
HBITMAP = HANDLE
LONG = wintypes.LONG
LPVOID = wintypes.LPVOID
PVOID = c_void_p
UINT = c_uint
WCHAR = c_wchar
WORD = c_ushort
UINT = wintypes.UINT
WCHAR = wintypes.WCHAR
WORD = wintypes.WORD
LRESULT = wintypes.LPARAM
COLORREF = DWORD
COLORREF = wintypes.COLORREF
LPBYTE = POINTER(BYTE)
LPWSTR = c_size_t #POINTER(WCHAR)
DWORD_PTR = UINT_PTR = ULONG_PTR = c_size_t
@ -143,26 +154,20 @@ if sysinfo.is_x64_Python():
else:
INT_PTR = LONG_PTR = c_long
HBITMAP = LONG_PTR #LONG
HINSTANCE = LONG_PTR #LONG
HMENU = LONG_PTR #LONG
HBRUSH = LONG_PTR #LONG
HBRUSH = wintypes.HBRUSH # LONG_PTR #LONG
HTREEITEM = LONG_PTR #LONG
HWND = LONG_PTR #LONG
HWND = wintypes.HWND
# TODO: switch to ctypes.wintypes.LPARAM and ctypes.wintypes.WPARAM
# Notice that wintypes definition of LPARAM/WPARAM differs between 32/64 bit
LPARAM = LONG_PTR
WPARAM = UINT_PTR
LPARAM = wintypes.LPARAM
WPARAM = wintypes.WPARAM
class POINT(Structure):
_pack_ = 4
_fields_ = [
# C:/PROGRA~1/MIAF9D~1/VC98/Include/windef.h 307
('x', LONG),
('y', LONG),
]
class POINT(wintypes.POINT, StructureMixIn):
"""Wrap the POINT structure and add extra functionality"""
def __iter__(self):
"""Allow iteration through coordinates"""
@ -178,25 +183,18 @@ class POINT(Structure):
else:
raise IndexError("Illegal index")
assert sizeof(POINT) == 8, sizeof(POINT)
assert alignment(POINT) == 4, alignment(POINT)
# ====================================================================
class RECT(Structure):
class RECT(wintypes.RECT, StructureMixIn):
"""Wrap the RECT structure and add extra functionality"""
_fields_ = [
# C:/PROGRA~1/MIAF9D~1/VC98/Include/windef.h 287
('left', LONG),
('top', LONG),
('right', LONG),
('bottom', LONG),
]
# ----------------------------------------------------------------
def __init__(self, otherRect_or_left = 0, top = 0, right = 0, bottom = 0):
def __init__(self, otherRect_or_left=0, top=0, right=0, bottom=0):
"""Provide a constructor for RECT structures
A RECT can be constructed by:
@ -220,20 +218,6 @@ class RECT(Structure):
self.top = long_int(top)
self.bottom = long_int(bottom)
# # ----------------------------------------------------------------
# def __eq__(self, otherRect):
# "return true if the two rectangles have the same coordinates"
#
# try:
# return \
# self.left == otherRect.left and \
# self.top == otherRect.top and \
# self.right == otherRect.right and \
# self.bottom == otherRect.bottom
# except AttributeError:
# return False
# ----------------------------------------------------------------
def __str__(self):
"""Return a string representation of the RECT"""
@ -286,18 +270,17 @@ class RECT(Structure):
def mid_point(self):
"""Return a POINT structure representing the mid point"""
pt = POINT()
pt.x = self.left + int(float(self.width())/2.)
pt.y = self.top + int(float(self.height())/2.)
pt.x = self.left + int(float(self.width()) / 2.)
pt.y = self.top + int(float(self.height()) / 2.)
return pt
#def __hash__(self):
# return hash (self.left, self.top, self.right, self.bottom)
__reduce__ = _reduce
RECT.__reduce__ = _reduce
assert sizeof(RECT) == 16, sizeof(RECT)
assert alignment(RECT) == 4, alignment(RECT)
class SETTEXTEX(Structure):
_pack_ = 1
_fields_ = [

@ -1,18 +1,25 @@
Metadata-Version: 2.1
Name: pyOpenRPA
Version: 1.1.12
Version: 1.1.13
Summary: First open source RPA platform for business
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
Author: Ivan Maslov
Author-email: Ivan.Maslov@unicodelabs.ru
License: MIT
Keywords: OpenRPA RPA Robot Automation Robotization
Keywords: OpenRPA RPA Robot Automation Robotization OpenSource
Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: MIT License
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Home Automation
Description-Content-Type: text/markdown
Requires-Dist: pywinauto (>=0.6.6)
Requires-Dist: pywinauto (>=0.6.8)
Requires-Dist: WMI (>=1.4.9)
Requires-Dist: pillow (>=6.0.0)
Requires-Dist: keyboard (>=0.13.3)
@ -50,17 +57,17 @@ Resources\WPy64-3720\python-3.7.2.amd64\python.exe
# Module GUI activity List:
############################
Новая версия
Новая версия
############################
Получить список элементов, который удовлетворяет условиям через расширенный движок поиска
Получить список элементов, который удовлетворяет условиям через расширенный движок поиска
[
{
"index":<Позиция элемента в родительском объекте>,
"depth_start" - глубина, с которой начинается поиск (по умолчанию 1)
"depth_end" - глубина, до которой ведется поиск (по умолчанию 1)
"class_name" - наименование класса, который требуется искать
"title" - наименование заголовка
"rich_text" - наименование rich_text
"index":<Позиция элемента в родительском объекте>,
"depth_start" - глубина, с которой начинается поиск (по умолчанию 1)
"depth_end" - глубина, до которой ведется поиск (по умолчанию 1)
"class_name" - наименование класса, который требуется искать
"title" - наименование заголовка
"rich_text" - наименование rich_text
}
]

@ -1,8 +1,8 @@
pyOpenRPA-1.1.12.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.1.12.dist-info/METADATA,sha256=QQ3aid4fLcFpJ0aWDRyYrVf1EMWi3cYocTyqvmHwJ90,3542
pyOpenRPA-1.1.12.dist-info/RECORD,,
pyOpenRPA-1.1.12.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.1.12.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA-1.1.13.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.1.13.dist-info/METADATA,sha256=rjIGRZpHzGWnt9LvY4CqdNByJhS4FqqdMUdzP_2BWmk,3352
pyOpenRPA-1.1.13.dist-info/RECORD,,
pyOpenRPA-1.1.13.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.1.13.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/.idea/inspectionProfiles/profiles_settings.xml,sha256=YXLFmX7rPNGcnKK1uX1uKYPN0fpgskYNe7t0BV7cqkY,174
pyOpenRPA/.idea/misc.xml,sha256=ySjeaQ1DfqxaRTlFGT_3zW5r9mWuwxoAK_AX4QiuAZM,203
pyOpenRPA/.idea/modules.xml,sha256=Q__U1JIA2cjxbLRXAv-SfYY00fZA0TNlpkkbY4s3ncg,277
@ -300,6 +300,6 @@ pyOpenRPA/Tools/Terminator.py,sha256=VcjX3gFXiCGu3MMCidhrTNsmC9wsAqfjRJdTSU9fLnU
pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/__pycache__/Terminator.cpython-37.pyc,,
pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=4A8Uettbe_avfR459RgVJNkUxs-2hHjTgSVKpVOFjKw,175
pyOpenRPA/__init__.py,sha256=MLl4coStn9rfw3D3uxDlH6uWJFlRPjAXs2Scbs-T3KA,175
pyOpenRPA/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/test.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

@ -3,7 +3,7 @@ r"""
The OpenRPA package (from UnicodeLabs)
"""
__version__ = 'v1.1.12'
__version__ = 'v1.1.13'
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from .Core import Robot

@ -1,13 +0,0 @@
At it's simplest it allows you to send mouse and keyboard
actions to windows dialogs and controls, but It has support for more complex
controls also.
Useful links
-------------
- Home page: http://pywinauto.github.io/
- Docs Intro: https://pywinauto.readthedocs.io/en/latest/
- Getting Started Guide: https://pywinauto.readthedocs.io/en/latest/getting_started.html
- StackOverflow tag: https://stackoverflow.com/questions/tagged/pywinauto

@ -1 +0,0 @@
{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: Microsoft :: Windows", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Testing", "Topic :: Software Development :: User Interfaces", "Topic :: Software Development :: Quality Assurance"], "extensions": {"python.details": {"contacts": [{"email": "pywinauto-users@lists.sourceforge.net", "name": "Mark Mc Mahon and Contributors", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "http://pywinauto.github.io/"}}}, "extras": [], "generator": "bdist_wheel (0.29.0)", "keywords": ["windows", "gui", "automation", "GuiAuto", "testing", "test", "desktop", "mouse", "keyboard"], "license": "BSD 3-clause", "metadata_version": "2.0", "name": "pywinauto", "platform": "win32", "run_requires": [{"requires": ["comtypes", "six"]}], "summary": "A set of Python modules to automate the Microsoft Windows GUI", "version": "0.6.6"}

@ -0,0 +1,27 @@
Copyright (c) 2017, Mark Mc Mahon and Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of pywinauto nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -1,6 +1,6 @@
Metadata-Version: 2.0
Metadata-Version: 2.1
Name: pywinauto
Version: 0.6.6
Version: 0.6.8
Summary: A set of Python modules to automate the Microsoft Windows GUI
Home-page: http://pywinauto.github.io/
Author: Mark Mc Mahon and Contributors
@ -23,9 +23,9 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Dist: comtypes
Requires-Dist: six
Requires-Dist: comtypes
Requires-Dist: pywin32
At it's simplest it allows you to send mouse and keyboard
actions to windows dialogs and controls, but It has support for more complex

@ -1,11 +1,10 @@
pywinauto-0.6.6.dist-info/DESCRIPTION.rst,sha256=k2uqeFUEl_g6xxBeVuZEfpJGuEOwcWLWkYAPOCoNkrk,443
pywinauto-0.6.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pywinauto-0.6.6.dist-info/METADATA,sha256=0BOLG3k-RTQbPt5MoG8G7P0yDwqhu2hQddg1D03wNgA,1660
pywinauto-0.6.6.dist-info/RECORD,,
pywinauto-0.6.6.dist-info/WHEEL,sha256=Ds0ba8WsPJtjBPzEMyPOBG3qfPa6B4mlzB-vhzorIZs,97
pywinauto-0.6.6.dist-info/metadata.json,sha256=0I2fhQRsICsiE-qQSyHVGUikMukbxGqL_67vZLVOkPs,1363
pywinauto-0.6.6.dist-info/top_level.txt,sha256=7E8mqRxGiLpAamWQi4ClxZvTp1jx3P0shUi_Tu0zk44,10
pywinauto/__init__.py,sha256=BJ2Pni41MWP3DgzGAFhpNvFajGujGcVUxMnf6n5s1tI,6950
pywinauto-0.6.8.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pywinauto-0.6.8.dist-info/LICENSE,sha256=GKmZqVt7I9hsQQtFNORNafbYzhPDpTcZsGq4ldii5zo,1504
pywinauto-0.6.8.dist-info/METADATA,sha256=7x_-XwBl2UsjPrl_4e5bNgDVwA_FMH83WidT-ii0xb0,1723
pywinauto-0.6.8.dist-info/RECORD,,
pywinauto-0.6.8.dist-info/WHEEL,sha256=53VSps8MltPLN_x9Ib61FU2ZSaJKzgrWQqu9rS-Dkgk,116
pywinauto-0.6.8.dist-info/top_level.txt,sha256=7E8mqRxGiLpAamWQi4ClxZvTp1jx3P0shUi_Tu0zk44,10
pywinauto/__init__.py,sha256=xY7VLfy-UvPNHKJSlzekAoG9Sue8zdNdFIdjS-_zTFs,7231
pywinauto/__pycache__/__init__.cpython-37.pyc,,
pywinauto/__pycache__/actionlogger.cpython-37.pyc,,
pywinauto/__pycache__/application.cpython-37.pyc,,
@ -33,9 +32,9 @@ pywinauto/__pycache__/win32functions.cpython-37.pyc,,
pywinauto/__pycache__/win32structures.cpython-37.pyc,,
pywinauto/__pycache__/xml_helpers.cpython-37.pyc,,
pywinauto/actionlogger.py,sha256=JVny3VSQIzcSH6ESfUPkxPozSJrxMMOvlwzNiUzO-_E,5632
pywinauto/application.py,sha256=r1gE55O91UXteKme9rFqBUP1QmbYyt4tmpXNQAHHt7I,55887
pywinauto/application.py,sha256=_KIIkl_ZZNFDZo_phPhYBX1YuNZh4pFW5A1gdYvTXeo,58047
pywinauto/backend.py,sha256=hLgO3HsnCJUYNoPfU8CwD11yMKjUZiPuXlC080JNufE,4186
pywinauto/base_wrapper.py,sha256=wx_8TIg_RbXX_zvpxGyL8nUWcvfQHVtVK6tAl8gcC_A,37561
pywinauto/base_wrapper.py,sha256=qAIvH6wKd6okBBDHY21gnK7A2DQj5H43qV4heQqQxc4,37590
pywinauto/clipboard.py,sha256=VpKW7WQ3BF57cmLkWA0Of16RG6BCuLSqGX0sW2nN1ds,4329
pywinauto/controlproperties.py,sha256=YQ1lbHxWvMf38PGB0JYdN8rhh9PYoe8iwaWbtw3EU1w,9329
pywinauto/controls/__init__.py,sha256=0cuXVxqppu3vQIJfjgxB_J__3Vtr3EvbDEx7TaRY64A,2241
@ -46,26 +45,26 @@ pywinauto/controls/__pycache__/menuwrapper.cpython-37.pyc,,
pywinauto/controls/__pycache__/uia_controls.cpython-37.pyc,,
pywinauto/controls/__pycache__/uiawrapper.cpython-37.pyc,,
pywinauto/controls/__pycache__/win32_controls.cpython-37.pyc,,
pywinauto/controls/common_controls.py,sha256=zyx1EyyoSQ_pvl6snIPOzIp6WZuPXOYNAzYqM4Qh5GA,141066
pywinauto/controls/hwndwrapper.py,sha256=46cKLxKhYL6-BzN33KA8kG7wOy1-JGEJ68qVQLiCYts,68153
pywinauto/controls/menuwrapper.py,sha256=SS5UoaezIMknz_405021QUV0ixClkqCUfuck_EnsgIA,23477
pywinauto/controls/uia_controls.py,sha256=rmME_GCfDbohEBNnHJE_mLStshBvPX_-r8T_Xa6XuH8,53699
pywinauto/controls/uiawrapper.py,sha256=aEVJYh6aB6VIg9sBrHwyQ3LOKTMnFLruVCMmSxy0dfQ,30770
pywinauto/controls/common_controls.py,sha256=4a_RyQcDl4N2JW8F_9sK-utJWJK-ujwqXF4vEhAaFe0,138614
pywinauto/controls/hwndwrapper.py,sha256=nDiCY-DnVHrD2o49WTRv7-x_2kB9Xf9nBb3gWJkgl5I,68222
pywinauto/controls/menuwrapper.py,sha256=TlgHXxMm6pUB75VDW6R-X5octoSpauXM0t7pRIJ8bPE,23497
pywinauto/controls/uia_controls.py,sha256=ei-u10dGxMRjR7SQupD3dxrvlbiqHm90ggb9WyracJA,54886
pywinauto/controls/uiawrapper.py,sha256=w7wsUnbsSStm32H5t2jEI-P9sdbMVOS8OYASHJnmhDk,31386
pywinauto/controls/win32_controls.py,sha256=Iz-28a0b_TPR8XiSTIkr8areRXyxuXQ0gOqshIPcrhU,35099
pywinauto/element_info.py,sha256=L-s3E6xdVAxgfCFZXAQlMbaHl5OEtG_xFM845gFz5zc,6067
pywinauto/findbestmatch.py,sha256=xAJaaiqAnBmQwCrhiqga-AmI5FxR0gZuXE1v1k1tyRA,20605
pywinauto/findwindows.py,sha256=wYQgISnlHOAhuvxA0bG9shLSTwu9pKNg1_ApYJi1pHw,14290
pywinauto/findbestmatch.py,sha256=izVEqpMSXgFhdMLd3OxN6Sexfo6MGVHTPEwkFxhDDpU,20748
pywinauto/findwindows.py,sha256=OMn7J5i4vk2xiVINPQ4daaMZ5MDCAplgnt4MXHo2dGY,14470
pywinauto/fuzzydict.py,sha256=mNFpET8ckSpMen4LdRRYyGRR4LToMbQw-gqNG3lWCqM,6073
pywinauto/handleprops.py,sha256=WavBoIYV0WTLpq5YUXDQS0-kMv3GChpwk2etbMFZA_k,14748
pywinauto/keyboard.py,sha256=Q_hT07R48cC830HzBZTaM2o2XOMtLsucVG_KalAfgz4,22865
pywinauto/handleprops.py,sha256=85UJyb6LfUVNim5biyB9Fz-oICo3lq1S_-jPxxgs28c,14685
pywinauto/keyboard.py,sha256=tJ4MSH7WVvmPrinMDycRr_uWm7AEtiFrfYjFjVgOwW0,24562
pywinauto/linux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pywinauto/linux/__pycache__/__init__.cpython-37.pyc,,
pywinauto/linux/__pycache__/clipboard.cpython-37.pyc,,
pywinauto/linux/__pycache__/keyboard.cpython-37.pyc,,
pywinauto/linux/clipboard.py,sha256=X4wR0r1_X8fdLF0KphNskV_vV2c0_toNyyt2m-TY6nQ,3568
pywinauto/linux/keyboard.py,sha256=kvc5EZY8lML2WoCwV5er9SyzsF2NjQ4Abpum-YYT5-U,17380
pywinauto/linux/keyboard.py,sha256=z540dSwdCvmoyRSpCaJainPOTawbY76eo8i_UW2qyYQ,17458
pywinauto/mouse.py,sha256=-Rh9zY1KUfzVcKblvQixH0WKxf2lW9__yrsI-pRhpe0,10647
pywinauto/remote_memory_block.py,sha256=fC0HyKKrsFlwS-1QlwQZif3RFqK4hr1RkIwajkbzGM4,12204
pywinauto/remote_memory_block.py,sha256=eox-bC9ZpliwQw3gZuiPku8_oQ9sGNeKfrSOM2pNyJs,12168
pywinauto/sysinfo.py,sha256=NgLfiQ3XNaRGnapzSfYSafwn5my24FjE1uHTU66P4VM,3052
pywinauto/taskbar.py,sha256=vjHNAdOaQwyZvqJaLMvMB7teJBMOeCgXeedJpZrZGp4,5232
pywinauto/tests/__init__.py,sha256=DZXsho8W7nBWDSw5Qb-qao9CNpfOwTCKOtxG0dJRgos,5452
@ -97,11 +96,11 @@ pywinauto/tests/repeatedhotkey.py,sha256=6xFNznYzzIebpkX2dLUW6rIkTOBIe5la1qVohi3
pywinauto/tests/translation.py,sha256=0qVEsh42uqu1K5MDZfcQunPngSRanPfSLgL99An1W8g,6070
pywinauto/tests/truncation.py,sha256=MD5UTKnVtZPZyfP3Ejx5ZMBDrDYY089xY05a8SMtMjc,20006
pywinauto/timings.py,sha256=58c9xNODE5LjQYNhqoLpbLfNeJ9Lu0J8GZLw2d2tkMY,15668
pywinauto/uia_defines.py,sha256=-4w4hhRCd4O_748nEp5w5kKl-d0vb17aymVr3rdZTQ0,9819
pywinauto/uia_defines.py,sha256=ynA52N4tmKn8KBlqGP0EJ8etpygvYTyZhQNJ-vdOBRw,9979
pywinauto/uia_element_info.py,sha256=g2E9O4qSyXYmj80MqFD7mOin_nHXowM_-fVJVO0oV88,13762
pywinauto/win32_element_info.py,sha256=bJ9CIP4RPdGIZVB_HaZQg2Z_92QG2hWYw1aGkoBtTxI,9369
pywinauto/win32_hooks.py,sha256=X2Le46OJxmco94b0n830RN6Tpnk2BzMTtRVOYdwllWc,24289
pywinauto/win32defines.py,sha256=i-uScB7nzZRk0fiDNk6TqlhGraRESmjLx-GkBlgOOp4,499259
pywinauto/win32functions.py,sha256=uHpPx61qsWL_awp6Kq0D-ERN5GsAvHjC34pN-rx1xQQ,14987
pywinauto/win32structures.py,sha256=G9diB0fpPv95J8DQLt6z5D1033Ajw_FZUCojrS0xliA,42128
pywinauto/win32_hooks.py,sha256=_oG2uuMswls-9jxaGm_XRAstM6E9S38cQ6ZzBEoiYg0,24238
pywinauto/win32defines.py,sha256=zltu4uEoY397OBLDKI_Vo0R79719_uqHOjL0QuTO3rc,630639
pywinauto/win32functions.py,sha256=fHHeG9kARY_3a05qXoI9hbIIXua6Kj3IJUu6my0W6Fw,24133
pywinauto/win32structures.py,sha256=CGxoTtM-fH_AyxpxGhRl28YsVJfBM1jv3_aLUXDo0ng,41700
pywinauto/xml_helpers.py,sha256=uiairq6vJiduprD6KMIvc72qBuplPC-PQqduJVVVZnc,17263

@ -1,5 +1,6 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.29.0)
Generator: bdist_wheel (0.33.4)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any

@ -32,7 +32,7 @@
"""Python package for automating GUI manipulation on Windows"""
__version__ = "0.6.6"
__version__ = "0.6.8"
import sys # noqa: E402
import warnings # noqa: E402
@ -89,11 +89,9 @@ if sys.platform == 'win32':
from . import findwindows
WindowAmbiguousError = findwindows.WindowAmbiguousError
WindowNotFoundError = findwindows.WindowNotFoundError
ElementNotFoundError = findwindows.ElementNotFoundError
if UIA_support:
ElementNotFoundError = findwindows.ElementNotFoundError
ElementAmbiguousError = findwindows.ElementAmbiguousError
ElementAmbiguousError = findwindows.ElementAmbiguousError
from . import findbestmatch
from . import backend as backends
@ -106,13 +104,14 @@ if sys.platform == 'win32':
class Desktop(object):
"""Simple class to call something like ``Desktop().WindowName.ControlName.method()``"""
def __init__(self, backend=None):
def __init__(self, backend=None, allow_magic_lookup=True):
"""Create desktop element description"""
if not backend:
backend = backends.registry.name
if backend not in backends.registry.backends:
raise ValueError('Backend "{0}" is not registered!'.format(backend))
self.backend = backends.registry.backends[backend]
self.allow_magic_lookup = allow_magic_lookup
def window(self, **kwargs):
"""Create WindowSpecification object for top-level window"""
@ -121,7 +120,7 @@ if sys.platform == 'win32':
if 'backend' in kwargs:
raise ValueError('Using another backend than set in Desktop constructor is not allowed!')
kwargs['backend'] = self.backend.name
return WindowSpecification(kwargs)
return WindowSpecification(kwargs, allow_magic_lookup=self.allow_magic_lookup)
def windows(self, **kwargs):
"""Return a list of wrapped top level windows"""
@ -145,9 +144,12 @@ if sys.platform == 'win32':
def __getattribute__(self, attr_name):
"""Attribute access for this class"""
allow_magic_lookup = object.__getattribute__(self, "allow_magic_lookup") # Beware of recursions here!
try:
return object.__getattribute__(self, attr_name)
except AttributeError:
if not allow_magic_lookup:
raise
return self[attr_name] # delegate it to __get_item__
def from_point(self, x, y):

@ -141,11 +141,12 @@ class WindowSpecification(object):
'active': ('is_active',),
}
def __init__(self, search_criteria):
def __init__(self, search_criteria, allow_magic_lookup=True):
"""
Initialize the class
:param search_criteria: the criteria to match a dialog
:param allow_magic_lookup: whether attribute access must turn into child_window(best_match=...) search as fallback
"""
# kwargs will contain however to find this window
if 'backend' not in search_criteria:
@ -158,6 +159,7 @@ class WindowSpecification(object):
self.criteria = [search_criteria, ]
self.actions = ActionLogger()
self.backend = registry.backends[search_criteria['backend']]
self.allow_magic_lookup = allow_magic_lookup
if self.backend.name == 'win32':
# Non PEP-8 aliases for partial backward compatibility
@ -173,7 +175,7 @@ class WindowSpecification(object):
self.window_ = deprecated(self.child_window, deprecated_name='window_')
def __call__(self, *args, **kwargs):
"""No __call__ so return a usefull error"""
"""No __call__ so return a useful error"""
if "best_match" in self.criteria[-1]:
raise AttributeError("Neither GUI element (wrapper) " \
"nor wrapper method '{0}' were found (typo?)".
@ -182,8 +184,8 @@ class WindowSpecification(object):
message = (
"You tried to execute a function call on a WindowSpecification "
"instance. You probably have a typo for one of the methods of "
"this class.\n"
"The criteria leading up to this is: " + str(self.criteria))
"this class or of the targeted wrapper object.\n"
"The criteria leading up to this are: " + str(self.criteria))
raise AttributeError(message)
@ -277,7 +279,7 @@ class WindowSpecification(object):
if 'top_level_only' not in criteria:
criteria['top_level_only'] = False
new_item = WindowSpecification(self.criteria[0])
new_item = WindowSpecification(self.criteria[0], allow_magic_lookup=self.allow_magic_lookup)
new_item.criteria.extend(self.criteria[1:])
new_item.criteria.append(criteria)
@ -307,7 +309,7 @@ class WindowSpecification(object):
"""
# if we already have 2 levels of criteria (dlg, control)
# then resolve the control and do a getitem on it for the
if len(self.criteria) >= 2:
if len(self.criteria) >= 2: # FIXME - this is surprising
ctrls = self.__resolve_control(self.criteria)
@ -324,7 +326,7 @@ class WindowSpecification(object):
# if we get here then we must have only had one criteria so far
# so create a new :class:`WindowSpecification` for this control
new_item = WindowSpecification(self.criteria[0])
new_item = WindowSpecification(self.criteria[0], allow_magic_lookup=self.allow_magic_lookup)
# add our new criteria
new_item.criteria.append({"best_match": key})
@ -345,6 +347,21 @@ class WindowSpecification(object):
Otherwise delegate functionality to :func:`__getitem__` - which
sets the appropriate criteria for the control.
"""
allow_magic_lookup = object.__getattribute__(self, "allow_magic_lookup") # Beware of recursions here!
if not allow_magic_lookup:
try:
return object.__getattribute__(self, attr_name)
except AttributeError:
wrapper_object = self.wrapper_object()
try:
return getattr(wrapper_object, attr_name)
except AttributeError:
message = (
'Attribute "%s" exists neither on %s object nor on'
'targeted %s element wrapper (typo? or set allow_magic_lookup to True?)' %
(attr_name, self.__class__, wrapper_object.__class__))
raise AttributeError(message)
if attr_name in ['__dict__', '__members__', '__methods__', '__class__', '__name__']:
return object.__getattribute__(self, attr_name)
@ -354,10 +371,10 @@ class WindowSpecification(object):
if attr_name in self.__dict__:
return self.__dict__[attr_name]
# if we already have 2 levels of criteria (dlg, conrol)
# if we already have 2 levels of criteria (dlg, control)
# this third must be an attribute so resolve and get the
# attribute and return it
if len(self.criteria) >= 2:
if len(self.criteria) >= 2: # FIXME - this is surprising
ctrls = self.__resolve_control(self.criteria)
@ -366,6 +383,7 @@ class WindowSpecification(object):
except AttributeError:
return self.child_window(best_match=attr_name)
else:
# FIXME - I don't get this part at all, why is it win32-specific and why not keep the same logic as above?
# if we have been asked for an attribute of the dialog
# then resolve the window and return the attribute
desktop_wrapper = self.backend.generic_wrapper_class(self.backend.element_info_class())
@ -870,7 +888,7 @@ class Application(object):
.. automethod:: __getitem__
"""
def __init__(self, backend="win32", datafilename=None):
def __init__(self, backend="win32", datafilename=None, allow_magic_lookup=True):
"""
Initialize the Application object
@ -886,6 +904,7 @@ class Application(object):
if backend not in registry.backends:
raise ValueError('Backend "{0}" is not registered!'.format(backend))
self.backend = registry.backends[backend]
self.allow_magic_lookup = allow_magic_lookup
if self.backend.name == 'win32':
# Non PEP-8 aliases for partial backward compatibility
self.Start = deprecated(self.start)
@ -906,6 +925,10 @@ class Application(object):
self.match_history = pickle.load(datafile)
self.use_history = True
def __iter__(self):
"""Raise to avoid infinite loops"""
raise NotImplementedError("Object is not iterable, try to use .windows()")
def connect(self, **kwargs):
"""Connect to an already running process
@ -1139,7 +1162,7 @@ class Application(object):
else:
criteria['title'] = windows[0].name
return WindowSpecification(criteria)
return WindowSpecification(criteria, allow_magic_lookup=self.allow_magic_lookup)
def active(self):
"""Return WindowSpecification for an active window of the application"""
@ -1163,7 +1186,7 @@ class Application(object):
else:
criteria['title'] = windows[0].name
return WindowSpecification(criteria)
return WindowSpecification(criteria, allow_magic_lookup=self.allow_magic_lookup)
def windows(self, **kwargs):
"""Return a list of wrapped top level windows of the application"""
@ -1205,7 +1228,7 @@ class Application(object):
else:
# add the restriction for this particular application
kwargs['app'] = self
win_spec = WindowSpecification(kwargs)
win_spec = WindowSpecification(kwargs, allow_magic_lookup=self.allow_magic_lookup)
return win_spec
Window_ = window_ = window
@ -1216,6 +1239,17 @@ class Application(object):
return self.window(best_match=key)
def __getattribute__(self, attr_name):
allow_magic_lookup = object.__getattribute__(self, "allow_magic_lookup") # Beware of recursions here!
if not allow_magic_lookup:
try:
return object.__getattribute__(self, attr_name)
except AttributeError:
message = (
'Attribute "%s" doesn\'t exist on %s object'
' (typo? or set allow_magic_lookup to True?)' %
(attr_name, self.__class__))
raise AttributeError(message)
"""Find the specified dialog of the application"""
if attr_name in ['__dict__', '__members__', '__methods__', '__class__']:
return object.__getattribute__(self, attr_name)

@ -38,7 +38,6 @@ import ctypes
import locale
import re
import time
import win32process
import win32gui
import win32con
import win32api
@ -925,7 +924,8 @@ class BaseWrapper(object):
with_tabs = False,
with_newlines = False,
turn_off_numlock = True,
set_foreground = True):
set_foreground = True,
vk_packet = True):
"""
Type keys to the element using keyboard.send_keys
@ -945,7 +945,7 @@ class BaseWrapper(object):
# attach the Python process with the process that self is in
if self.element_info.handle:
window_thread_id, _ = win32process.GetWindowThreadProcessId(int(self.handle))
window_thread_id = win32functions.GetWindowThreadProcessId(self.handle, None)
win32functions.AttachThreadInput(win32functions.GetCurrentThreadId(), window_thread_id, win32defines.TRUE)
# TODO: check return value of AttachThreadInput properly
else:
@ -967,7 +967,8 @@ class BaseWrapper(object):
with_spaces,
with_tabs,
with_newlines,
turn_off_numlock)
turn_off_numlock,
vk_packet)
# detach the python process from the window's process
if self.element_info.handle:

@ -53,7 +53,6 @@ import warnings
import locale
import six
from .. import sysinfo
from .. import win32functions
from .. import win32defines
from .. import win32structures
@ -68,9 +67,6 @@ from ..handleprops import is64bitprocess
from ..sysinfo import is_x64_Python
from .. import deprecated
if sysinfo.UIA_support:
from ..uia_defines import IUIA
# Todo: I should return iterators from things like items() and texts()
# to save building full lists all the time
@ -135,7 +131,7 @@ class _listview_item(object):
item.iItem = self.item_index
item.iSubItem = self.subitem_index
item.stateMask = win32structures.UINT(-1)
item.stateMask = wintypes.UINT(-1)
item.cchTextMax = 2000
item.pszText = remote_mem.Address() + \
@ -501,9 +497,9 @@ class _listview_item(object):
lvitem = self.listview_ctrl.LVITEM()
lvitem.mask = win32structures.UINT(win32defines.LVIF_STATE)
lvitem.state = win32structures.UINT(index_to_state_image_mask(1)) # win32structures.UINT(0x1000)
lvitem.stateMask = win32structures.UINT(win32defines.LVIS_STATEIMAGEMASK)
lvitem.mask = wintypes.UINT(win32defines.LVIF_STATE)
lvitem.state = wintypes.UINT(index_to_state_image_mask(1)) # wintypes.UINT(0x1000)
lvitem.stateMask = wintypes.UINT(win32defines.LVIS_STATEIMAGEMASK)
remote_mem = RemoteMemoryBlock(self.listview_ctrl)
remote_mem.Write(lvitem)
@ -530,9 +526,9 @@ class _listview_item(object):
lvitem = self.listview_ctrl.LVITEM()
lvitem.mask = win32structures.UINT(win32defines.LVIF_STATE)
lvitem.state = win32structures.UINT(index_to_state_image_mask(2)) # win32structures.UINT(0x2000)
lvitem.stateMask = win32structures.UINT(win32defines.LVIS_STATEIMAGEMASK)
lvitem.mask = wintypes.UINT(win32defines.LVIF_STATE)
lvitem.state = wintypes.UINT(index_to_state_image_mask(2)) # wintypes.UINT(0x2000)
lvitem.stateMask = wintypes.UINT(win32defines.LVIS_STATEIMAGEMASK)
remote_mem = RemoteMemoryBlock(self.listview_ctrl)
remote_mem.Write(lvitem)
@ -591,12 +587,12 @@ class _listview_item(object):
# first we need to change the state of the item
lvitem = self.listview_ctrl.LVITEM()
lvitem.mask = win32structures.UINT(win32defines.LVIF_STATE)
lvitem.mask = wintypes.UINT(win32defines.LVIF_STATE)
if to_select:
lvitem.state = win32structures.UINT(win32defines.LVIS_FOCUSED | win32defines.LVIS_SELECTED)
lvitem.state = wintypes.UINT(win32defines.LVIS_FOCUSED | win32defines.LVIS_SELECTED)
lvitem.stateMask = win32structures.UINT(win32defines.LVIS_FOCUSED | win32defines.LVIS_SELECTED)
lvitem.stateMask = wintypes.UINT(win32defines.LVIS_FOCUSED | win32defines.LVIS_SELECTED)
remote_mem = RemoteMemoryBlock(self.listview_ctrl)
remote_mem.Write(lvitem, size=ctypes.sizeof(lvitem))
@ -721,10 +717,6 @@ class ListViewWrapper(hwndwrapper.HwndWrapper):
"TSysListView",
"ListView.*WndClass",
]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_ListControlTypeId
controltypes = []
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -1424,7 +1416,7 @@ class _treeview_element(object):
item.pszText = remote_mem.Address() + ctypes.sizeof(item) + 16
item.cchTextMax = 2000
item.hItem = self.elem
item.stateMask = win32structures.UINT(-1)
item.stateMask = wintypes.UINT(-1)
# Write the local TVITEM structure to the remote memory block
remote_mem.Write(item)
@ -1460,8 +1452,6 @@ class TreeViewWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "TreeView"
windowclasses = [
"SysTreeView32", r"WindowsForms\d*\.SysTreeView32\..*", "TTreeView", "TreeList.TreeListCtrl"]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_TreeControlTypeId]
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -1751,8 +1741,6 @@ class HeaderWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Header"
windowclasses = ["SysHeader32", "msvb_lib_header"]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_HeaderControlTypeId]
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -1894,8 +1882,6 @@ class StatusBarWrapper(hwndwrapper.HwndWrapper):
"msctls_statusbar32",
".*StatusBar",
r"WindowsForms\d*\.msctls_statusbar32\..*"]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_StatusBarControlTypeId]
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -2065,8 +2051,6 @@ class TabControlWrapper(hwndwrapper.HwndWrapper):
windowclasses = [
"SysTabControl32",
r"WindowsForms\d*\.SysTabControl32\..*"]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_TabControlTypeId]
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -2878,10 +2862,6 @@ class ReBarWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "ReBar"
windowclasses = ["ReBarWindow32", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -3086,8 +3066,6 @@ class UpDownWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "UpDown"
windowclasses = ["msctls_updown32", "msctls_updown", ]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_SpinnerControlTypeId]
#----------------------------------------------------------------
def __init__(self, hwnd):
@ -3195,8 +3173,6 @@ class TrackbarWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Trackbar"
windowclasses = ["msctls_trackbar", ]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_SliderControlTypeId]
def get_range_min(self):
"""Get min available trackbar value"""
@ -3293,10 +3269,6 @@ class AnimationWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Animation"
windowclasses = ["SysAnimate32", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
#====================================================================
@ -3306,10 +3278,6 @@ class ComboBoxExWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "ComboBoxEx"
windowclasses = ["ComboBoxEx32", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
has_title = False
@ -3321,10 +3289,6 @@ class DateTimePickerWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "DateTimePicker"
windowclasses = ["SysDateTimePick32",
r"WindowsForms\d*\.SysDateTimePick32\..*", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
has_title = False
#----------------------------------------------------------------
@ -3387,10 +3351,6 @@ class HotkeyWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Hotkey"
windowclasses = ["msctls_hotkey32", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
has_title = False
@ -3401,10 +3361,6 @@ class IPAddressWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "IPAddress"
windowclasses = ["SysIPAddress32", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
has_title = False
@ -3415,8 +3371,6 @@ class CalendarWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Calendar"
windowclasses = ["SysMonthCal32", ]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_CalendarControlTypeId]
has_title = False
place_in_calendar = {
@ -3719,10 +3673,6 @@ class PagerWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Pager"
windowclasses = ["SysPager", ]
if sysinfo.UIA_support:
#controltypes is empty to make wrapper search result unique
#possible control types: IUIA().UIA_dll.UIA_PaneControlTypeId
controltypes = []
#----------------------------------------------------------------
def get_position(self):
@ -3748,8 +3698,6 @@ class ProgressWrapper(hwndwrapper.HwndWrapper):
friendlyclassname = "Progress"
windowclasses = ["msctls_progress", "msctls_progress32", ]
if sysinfo.UIA_support:
controltypes = [IUIA().UIA_dll.UIA_ProgressBarControlTypeId]
has_title = False
#----------------------------------------------------------------

@ -493,7 +493,7 @@ class HwndWrapper(BaseWrapper):
(e.g. VK_LEFT, VK_DELETE), a KeySequenceError is raised. Consider using
the method send_keystrokes for such input.
"""
input_locale_id = ctypes.windll.User32.GetKeyboardLayout(0)
input_locale_id = win32functions.GetKeyboardLayout(0)
keys = keyboard.parse_keys(chars, with_spaces, with_tabs, with_newlines)
for key in keys:
@ -506,11 +506,11 @@ class HwndWrapper(BaseWrapper):
if unicode_char:
_, char = key_info[:2]
vk = ctypes.windll.User32.VkKeyScanExW(char, input_locale_id) & 0xFF
scan = keyboard.MapVirtualKey(vk, 0)
vk = win32functions.VkKeyScanExW(chr(char), input_locale_id) & 0xFF
scan = win32functions.MapVirtualKeyW(vk, 0)
else:
vk, scan = key_info[:2]
char = keyboard.MapVirtualKey(vk, 2)
char = win32functions.MapVirtualKeyW(vk, 2)
if char > 0:
lparam = 1 << 0 | scan << 16 | (flags & 1) << 24
@ -541,22 +541,21 @@ class HwndWrapper(BaseWrapper):
.. _`type_keys`: pywinauto.base_wrapper.html#pywinauto.base_wrapper.BaseWrapper.type_keys
"""
user32 = ctypes.windll.User32
PBYTE256 = ctypes.c_ubyte * 256
win32gui.SendMessage(self.handle, win32con.WM_ACTIVATE,
win32con.WA_ACTIVE, 0)
target_thread_id = user32.GetWindowThreadProcessId(self.handle, None)
current_thread_id = win32api.GetCurrentThreadId()
attach_success = user32.AttachThreadInput(target_thread_id, current_thread_id, True) != 0
target_thread_id = win32functions.GetWindowThreadProcessId(self.handle, None)
current_thread_id = win32functions.GetCurrentThreadId()
attach_success = win32functions.AttachThreadInput(target_thread_id, current_thread_id, True) != 0
if not attach_success:
warnings.warn('Failed to attach app\'s thread to the current thread\'s message queue',
UserWarning, stacklevel=2)
keyboard_state_stack = [PBYTE256()]
user32.GetKeyboardState(ctypes.byref(keyboard_state_stack[-1]))
win32functions.GetKeyboardState(keyboard_state_stack[-1])
input_locale_id = ctypes.windll.User32.GetKeyboardLayout(0)
input_locale_id = win32functions.GetKeyboardLayout(0)
context_code = 0
keys = keyboard.parse_keys(keystrokes, with_spaces, with_tabs, with_newlines)
@ -578,11 +577,11 @@ class HwndWrapper(BaseWrapper):
shift_state = 0
unicode_codepoint = flags & keyboard.KEYEVENTF_UNICODE != 0
if unicode_codepoint:
char = scan
vk_with_flags = user32.VkKeyScanExW(char, input_locale_id)
char = chr(scan)
vk_with_flags = win32functions.VkKeyScanExW(char, input_locale_id)
vk = vk_with_flags & 0xFF
shift_state = (vk_with_flags & 0xFF00) >> 8
scan = keyboard.MapVirtualKey(vk, 0)
scan = win32functions.MapVirtualKeyW(vk, 0)
if key.down and vk > 0:
new_keyboard_state = copy.deepcopy(keyboard_state_stack[-1])
@ -602,8 +601,8 @@ class HwndWrapper(BaseWrapper):
context_code << 29 |
0 << 31)
user32.SetKeyboardState(ctypes.byref(keyboard_state_stack[-1]))
win32api.PostMessage(self.handle, down_msg, vk, lparam)
win32functions.SetKeyboardState(keyboard_state_stack[-1])
win32functions.PostMessage(self.handle, down_msg, vk, lparam)
if vk == keyboard.VK_MENU:
context_code = 1
@ -621,8 +620,8 @@ class HwndWrapper(BaseWrapper):
1 << 30 |
1 << 31)
win32api.PostMessage(self.handle, up_msg, vk, lparam)
user32.SetKeyboardState(ctypes.byref(keyboard_state_stack[-1]))
win32functions.PostMessage(self.handle, up_msg, vk, lparam)
win32functions.SetKeyboardState(keyboard_state_stack[-1])
if vk == keyboard.VK_MENU:
context_code = 0
@ -636,10 +635,10 @@ class HwndWrapper(BaseWrapper):
UserWarning, stacklevel=2)
else:
warnings.warn(e.strerror, UserWarning, stacklevel=2)
user32.SetKeyboardState(ctypes.byref(keyboard_state_stack[0]))
win32functions.SetKeyboardState(keyboard_state_stack[0])
if attach_success:
user32.AttachThreadInput(target_thread_id, current_thread_id, False)
win32functions.AttachThreadInput(target_thread_id, current_thread_id, False)
# -----------------------------------------------------------
def send_message_timeout(
@ -1256,7 +1255,7 @@ class HwndWrapper(BaseWrapper):
"""Return a handle to the active window within the process"""
gui_info = win32structures.GUITHREADINFO()
gui_info.cbSize = ctypes.sizeof(gui_info)
window_thread_id, _ = win32process.GetWindowThreadProcessId(int(self.handle))
window_thread_id = win32functions.GetWindowThreadProcessId(self.handle, None)
ret = win32functions.GetGUIThreadInfo(
window_thread_id,
ctypes.byref(gui_info))
@ -1278,7 +1277,7 @@ class HwndWrapper(BaseWrapper):
"""
gui_info = win32structures.GUITHREADINFO()
gui_info.cbSize = ctypes.sizeof(gui_info)
window_thread_id, _ = win32process.GetWindowThreadProcessId(self.handle)
window_thread_id = win32functions.GetWindowThreadProcessId(self.handle, None)
ret = win32functions.GetGUIThreadInfo(
window_thread_id,
ctypes.byref(gui_info))
@ -1335,7 +1334,7 @@ class HwndWrapper(BaseWrapper):
def has_keyboard_focus(self):
"""Check the keyboard focus on this control."""
control_thread = win32process.GetWindowThreadProcessId(self.handle)[0]
control_thread = win32functions.GetWindowThreadProcessId(self.handle, None)
win32process.AttachThreadInput(control_thread, win32api.GetCurrentThreadId(), 1)
focused = win32gui.GetFocus()
win32process.AttachThreadInput(control_thread, win32api.GetCurrentThreadId(), 0)
@ -1346,9 +1345,9 @@ class HwndWrapper(BaseWrapper):
def set_keyboard_focus(self):
"""Set the keyboard focus to this control."""
control_thread = win32process.GetWindowThreadProcessId(self.handle)[0]
control_thread = win32functions.GetWindowThreadProcessId(self.handle, None)
win32process.AttachThreadInput(control_thread, win32api.GetCurrentThreadId(), 1)
win32gui.SetFocus(self.handle)
win32functions.SetFocus(self.handle)
win32process.AttachThreadInput(control_thread, win32api.GetCurrentThreadId(), 0)
win32functions.WaitGuiThreadIdle(self.handle)
@ -1602,12 +1601,13 @@ class DialogWrapper(HwndWrapper):
#win32defines.SMTO_BLOCK)
# get a handle we can wait on
_, pid = win32process.GetWindowThreadProcessId(int(self.handle))
pid = ctypes.c_ulong()
win32functions.GetWindowThreadProcessId(self.handle, ctypes.byref(pid))
try:
process_wait_handle = win32api.OpenProcess(
win32con.SYNCHRONIZE | win32con.PROCESS_TERMINATE,
0,
pid)
pid.value)
except win32gui.error:
return True # already closed
@ -1723,7 +1723,7 @@ def _perform_click(
# figure out the flags and pack coordinates
flags, click_point = _calc_flags_and_coords(pressed, coords)
#control_thread = win32functions.GetWindowThreadProcessId(ctrl, 0)
#control_thread = win32functions.GetWindowThreadProcessId(ctrl, None)
#win32functions.AttachThreadInput(win32functions.GetCurrentThreadId(), control_thread, win32defines.TRUE)
# TODO: check return value of AttachThreadInput properly

@ -283,7 +283,7 @@ class MenuItem(object):
# 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) and self.menu.owner_item:
if rect == win32structures.RECT(0, 0, 0, 0) and self.menu.owner_item:
self.menu.owner_item.click_input()
rect = self.rectangle()

@ -200,7 +200,11 @@ class ComboBoxWrapper(uiawrapper.UIAWrapper):
# -----------------------------------------------------------
def texts(self):
"""Return the text of the items in the combobox"""
texts = []
texts = self._texts_from_item_container()
if len(texts):
# flatten the list
return [ t for lst in texts for t in lst ]
# ComboBox has to be expanded to populate a list of its children items
try:
super(ComboBoxWrapper, self).expand()
@ -370,6 +374,11 @@ class EditWrapper(uiawrapper.UIAWrapper):
"""Return the current value of the element"""
return self.iface_value.CurrentValue
# -----------------------------------------------------------
def is_editable(self):
"""Return the edit possibility of the element"""
return not self.iface_value.CurrentIsReadOnly
# -----------------------------------------------------------
def texts(self):
"""Get the text of the edit control"""
@ -846,10 +855,19 @@ class ListViewWrapper(uiawrapper.UIAWrapper):
raise ValueError("Element '{0}' not found".format(row))
elif isinstance(row, six.integer_types):
# Get the item by a row index
# TODO: Can't get virtualized items that way
# TODO: See TODO section of item_count() method for details
list_items = self.children(content_only=True)
itm = list_items[self.__resolve_row_index(row)]
try:
com_elem = 0
for _ in range(0, self.__resolve_row_index(row) + 1):
com_elem = self.iface_item_container.FindItemByProperty(com_elem, 0, uia_defs.vt_empty)
# Try to load element using VirtualizedItem pattern
try:
get_elem_interface(com_elem, "VirtualizedItem").Realize()
except NoPatternInterfaceError:
pass
itm = uiawrapper.UIAWrapper(uia_element_info.UIAElementInfo(com_elem))
except (NoPatternInterfaceError, ValueError, AttributeError):
list_items = self.children(content_only=True)
itm = list_items[self.__resolve_row_index(row)]
else:
raise TypeError("String type or integer is expected")
@ -960,18 +978,18 @@ class MenuWrapper(uiawrapper.UIAWrapper):
return item
# -----------------------------------------------------------
@staticmethod
def _activate(item):
def _activate(self, item, is_last):
"""Activate the specified item"""
if not item.is_active():
item.set_focus()
try:
item.expand()
except(NoPatternInterfaceError):
pass
if self.element_info.framework_id == 'WinForm' and not is_last:
item.select()
# -----------------------------------------------------------
def _sub_item_by_text(self, menu, name, exact):
def _sub_item_by_text(self, menu, name, exact, is_last):
"""Find a menu sub-item by the specified text"""
sub_item = None
items = menu.items()
@ -987,18 +1005,18 @@ class MenuWrapper(uiawrapper.UIAWrapper):
texts.append(i.window_text())
sub_item = findbestmatch.find_best_match(name, texts, items)
self._activate(sub_item)
self._activate(sub_item, is_last)
return sub_item
# -----------------------------------------------------------
def _sub_item_by_idx(self, menu, idx):
def _sub_item_by_idx(self, menu, idx, is_last):
"""Find a menu sub-item by the specified index"""
sub_item = None
items = menu.items()
if items:
sub_item = items[idx]
self._activate(sub_item)
self._activate(sub_item, is_last)
return sub_item
# -----------------------------------------------------------
@ -1011,35 +1029,39 @@ class MenuWrapper(uiawrapper.UIAWrapper):
Note: $ - specifier is not supported
"""
# Get the path parts
part0, parts = path.split("->", 1)
part0 = part0.strip()
if len(part0) == 0:
menu_items = [p.strip() for p in path.split("->")]
items_cnt = len(menu_items)
if items_cnt == 0:
raise IndexError()
for item in menu_items:
if not item:
raise IndexError("Empty item name between '->' separators")
def next_level_menu(parent_menu, item_name, is_last):
if item_name.startswith("#"):
return self._sub_item_by_idx(parent_menu, int(item_name[1:]), is_last)
else:
return self._sub_item_by_text(parent_menu, item_name, exact, is_last)
# Find a top level menu item and select it. After selecting this item
# a new Menu control is created and placed on the dialog. It can be
# a direct child or a descendant.
# Sometimes we need to re-discover Menu again
try:
menu = None
if part0.startswith("#"):
menu = self._sub_item_by_idx(self, int(part0[1:]))
else:
menu = self._sub_item_by_text(self, part0, exact)
menu = next_level_menu(self, menu_items[0], items_cnt == 1)
if items_cnt == 1:
return menu
if not menu.items():
self._activate(menu)
self._activate(menu, False)
timings.wait_until(
timings.Timings.window_find_timeout,
timings.Timings.window_find_retry,
lambda: len(self.top_level_parent().descendants(control_type="Menu")) > 0)
menu = self.top_level_parent().descendants(control_type="Menu")[0]
for cur_part in [p.strip() for p in parts.split("->")]:
if cur_part.startswith("#"):
menu = self._sub_item_by_idx(menu, int(cur_part[1:]))
else:
menu = self._sub_item_by_text(menu, cur_part, exact)
for i in range(1, items_cnt):
menu = next_level_menu(menu, menu_items[i], items_cnt == i + 1)
except(AttributeError):
raise IndexError()

@ -782,5 +782,19 @@ class UIAWrapper(BaseWrapper):
return self
# -----------------------------------------------------------
def _texts_from_item_container(self):
"""Get texts through the ItemContainer interface"""
texts = []
try:
com_elem = self.iface_item_container.FindItemByProperty(0, 0, uia_defs.vt_empty)
while com_elem:
itm = UIAWrapper(UIAElementInfo(com_elem))
texts.append(itm.texts())
com_elem = self.iface_item_container.FindItemByProperty(com_elem, 0, uia_defs.vt_empty)
except (uia_defs.NoPatternInterfaceError):
pass
return texts
backend.register('uia', UIAElementInfo, UIAWrapper)

@ -331,8 +331,9 @@ def get_control_names(control, allcontrols, textcontrols):
if non_text_names:
names.extend(non_text_names)
# return the names - and make sure there are no duplicates
return set(names)
# return the names - and make sure there are no duplicates or empty values
cleaned_names = set(names) - set([None, ""])
return cleaned_names
#====================================================================
@ -493,6 +494,8 @@ def find_best_control_matches(search_text, controls):
"""
name_control_map = build_unique_dict(controls)
#print ">>>>>>>", repr(name_control_map).decode("ascii", "ignore")
# # collect all the possible names for all controls
# # and build a list of them
# for ctrl in controls:

@ -189,9 +189,10 @@ def find_elements(class_name=None,
if top_level_only:
# find the top level elements
element = backend_obj.element_info_class()
# vryabov: we don't use title=title below, because it fixes issue 779:
# https://github.com/pywinauto/pywinauto/issues/779
elements = element.children(process=process,
class_name=class_name,
title=title,
control_type=control_type,
cache_enable=True)
@ -206,8 +207,9 @@ def find_elements(class_name=None,
parent = backend_obj.element_info_class()
# look for ALL children of that parent
# vryabov: we don't use title=title below, because it fixes issue 779:
# https://github.com/pywinauto/pywinauto/issues/779
elements = parent.descendants(class_name=class_name,
title=title,
control_type=control_type,
cache_enable=True,
depth=depth)

@ -35,14 +35,18 @@ These are implemented in a procedural way so as to to be
useful to other modules with the least conceptual overhead
"""
import ctypes
import warnings
import win32process
import win32api
import win32con
import win32gui
import pywintypes
from ctypes import wintypes
from ctypes import WINFUNCTYPE
from ctypes import c_int
from ctypes import byref
from ctypes import sizeof
from ctypes import create_unicode_buffer
from . import win32functions
from . import win32defines
from . import win32structures
@ -58,7 +62,7 @@ def text(handle):
if class_name == 'MSCTFIME UI':
return 'M'
if class_name is None:
return None
return ''
#length = win32functions.SendMessage(handle, win32defines.WM_GETTEXTLENGTH, 0, 0)
# XXX: there are some very rare cases when WM_GETTEXTLENGTH hangs!
@ -71,11 +75,11 @@ def text(handle):
0,
win32defines.SMTO_ABORTIFHUNG,
500,
ctypes.byref(c_length)
byref(c_length)
)
if result == 0:
ActionLogger().log('WARNING! Cannot retrieve text length for handle = ' + str(handle))
return None
return ''
else:
length = c_length.value
@ -85,10 +89,10 @@ def text(handle):
if length > 0:
length += 1
buffer_ = ctypes.create_unicode_buffer(length)
buffer_ = create_unicode_buffer(length)
ret = win32functions.SendMessage(
handle, win32defines.WM_GETTEXT, length, ctypes.byref(buffer_))
handle, win32defines.WM_GETTEXT, length, byref(buffer_))
if ret:
textval = buffer_.value
@ -101,7 +105,7 @@ def classname(handle):
"""Return the class name of the window"""
if handle is None:
return None
class_name = ctypes.create_unicode_buffer(u"", 257)
class_name = create_unicode_buffer(u"", 257)
win32functions.GetClassName(handle, class_name, 256)
return class_name.value
@ -145,13 +149,13 @@ def contexthelpid(handle):
#=========================================================================
def iswindow(handle):
"""Return True if the handle is a window"""
return False if handle is None else bool(win32functions.IsWindow(handle))
return False if handle is None else bool(win32functions.IsWindow(handle))
#=========================================================================
def isvisible(handle):
"""Return True if the window is visible"""
return False if handle is None else bool(win32functions.IsWindowVisible(handle))
return False if handle is None else bool(win32functions.IsWindowVisible(handle))
#=========================================================================
@ -192,8 +196,8 @@ def is64bitbinary(filename):
binary_type = win32file.GetBinaryType(filename)
return binary_type != win32file.SCS_32BIT_BINARY
except Exception as exc:
warnings.warn('Cannot get binary type for file "{}". Error: {}' \
''.format(filename, exc), RuntimeWarning, stacklevel=2)
warnings.warn('Cannot get binary type for file "{}". Error: {}'
.format(filename, exc), RuntimeWarning, stacklevel=2)
return None
@ -201,24 +205,24 @@ def is64bitbinary(filename):
def clientrect(handle):
"""Return the client rectangle of the control"""
client_rect = win32structures.RECT()
win32functions.GetClientRect(handle, ctypes.byref(client_rect))
win32functions.GetClientRect(handle, byref(client_rect))
return client_rect
#=========================================================================
def rectangle(handle):
"""Return the rectangle of the window"""
# GetWindowRect returns 4-tuple
try:
return win32structures.RECT(*win32gui.GetWindowRect(handle))
except pywintypes.error:
return win32structures.RECT()
rect = win32structures.RECT()
win32functions.GetWindowRect(handle, byref(rect))
return rect
#=========================================================================
def font(handle):
"""Return the font as a LOGFONTW of the window"""
# get the font handle
if handle is None:
handle = 0 # make sure we don't pass window handle down as None
font_handle = win32functions.SendMessage(
handle, win32defines.WM_GETFONT, 0, 0)
@ -244,15 +248,10 @@ def font(handle):
font_handle = win32functions.GetStockObject(
win32defines.ANSI_VAR_FONT)
else:
fontval = win32structures.LOGFONTW()
ret = win32functions.GetObject(
font_handle, ctypes.sizeof(fontval), ctypes.byref(fontval))
# Get the Logfont structure of the font of the control
fontval = win32structures.LOGFONTW()
ret = win32functions.GetObject(
font_handle, ctypes.sizeof(fontval), ctypes.byref(fontval))
font_handle, sizeof(fontval), byref(fontval))
# The function could not get the font - this is probably
# because the control does not have associated Font/Text
@ -271,11 +270,11 @@ def font(handle):
# get the title font based on the system metrics rather
# than the font of the control itself
ncms = win32structures.NONCLIENTMETRICSW()
ncms.cbSize = ctypes.sizeof(ncms)
ncms.cbSize = sizeof(ncms)
win32functions.SystemParametersInfo(
win32defines.SPI_GETNONCLIENTMETRICS,
ctypes.sizeof(ncms),
ctypes.byref(ncms),
sizeof(ncms),
byref(ncms),
0)
# with either of the following 2 flags set the font of the
@ -293,8 +292,9 @@ def font(handle):
#=========================================================================
def processid(handle):
"""Return the ID of process that controls this window"""
_, process_id = win32process.GetWindowThreadProcessId(int(handle))
return process_id
pid = wintypes.DWORD()
win32functions.GetWindowThreadProcessId(handle, byref(pid))
return pid.value
#=========================================================================
@ -327,10 +327,10 @@ def children(handle):
return True
# define the child proc type
enum_child_proc_t = ctypes.WINFUNCTYPE(
ctypes.c_int, # return type
win32structures.HWND, # the window handle
win32structures.LPARAM) # extra information
enum_child_proc_t = WINFUNCTYPE(
c_int, # return type
wintypes.HWND, # the window handle
wintypes.LPARAM) # extra information
# update the proc to the correct type
proc = enum_child_proc_t(enum_child_proc)

@ -64,6 +64,8 @@ below. The module is also available on Linux.
{VK_F19}, {VK_EXECUTE}, {VK_PLAY}, {VK_RMENU}, {VK_F13}, {VK_F12}, {LWIN},
{VK_DOWN}, {VK_F17}, {VK_F16}, {VK_F15}, {VK_F14}
~ is a shorter alias for {ENTER}
**Modifiers:**
- ``'+': {VK_SHIFT}``
@ -96,10 +98,19 @@ Use curly brackers to escape modifiers and type reserved symbols as single keys:
send_keys('{^}a{^}c{%}') # type string "^a^c%" (Ctrl will not be pressed)
send_keys('{{}ENTER{}}') # type string "{ENTER}" without pressing Enter key
For Windows only, pywinauto defaults to sending a virtual key packet
(VK_PACKET) for textual input. For applications that do not handle VK_PACKET
appropriately, the ``vk_packet`` option may be set to ``False``. In this case
pywinauto will attempt to send the virtual key code of the requested key. This
option only affects the behavior of keys matching [-=[]\;',./a-zA-Z0-9 ]. Note
that upper and lower case are included for a-z. Both reference the same
virtual key for convenience.
"""
from __future__ import unicode_literals
import sys
import string
from . import deprecated
@ -113,6 +124,7 @@ else:
import six
from . import win32structures
from . import win32functions
__all__ = ['KeySequenceError', 'send_keys']
@ -120,17 +132,6 @@ else:
DEBUG = 0
GetMessageExtraInfo = ctypes.windll.user32.GetMessageExtraInfo
MapVirtualKey = ctypes.windll.user32.MapVirtualKeyW
SendInput = ctypes.windll.user32.SendInput
UINT = ctypes.c_uint
SendInput.restype = UINT
SendInput.argtypes = [UINT, ctypes.c_void_p, ctypes.c_int]
VkKeyScan = ctypes.windll.user32.VkKeyScanW
VkKeyScan.restype = ctypes.c_short
VkKeyScan.argtypes = [ctypes.c_wchar]
INPUT_KEYBOARD = 1
KEYEVENTF_EXTENDEDKEY = 1
KEYEVENTF_KEYUP = 2
@ -310,6 +311,29 @@ else:
'%': VK_MENU,
}
# Virtual keys that map to an ASCII character
# See https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
ascii_vk = {
' ': 0x20,
'=': 0xbb,
',': 0xbc,
'-': 0xbd,
'.': 0xbe,
# According to the above reference, the following characters vary per region.
# This mapping applies to US keyboards
';': 0xba,
'/': 0xbf,
'`': 0xc0,
'[': 0xdb,
'\\': 0xdc,
']': 0xdd,
'\'': 0xde,
}
# [0-9A-Z] map exactly to their ASCII counterparts
ascii_vk.update(dict((c, ord(c)) for c in string.ascii_uppercase + string.digits))
# map [a-z] to their uppercase ASCII counterparts
ascii_vk.update(dict((c, ord(c.upper())) for c in string.ascii_lowercase))
class KeySequenceError(Exception):
@ -368,7 +392,7 @@ else:
# it seems to return 0 every time but it's required by MSDN specification
# so call it just in case
inp.ki.dwExtraInfo = GetMessageExtraInfo()
inp.ki.dwExtraInfo = win32functions.GetMessageExtraInfo()
# if we are releasing - then let it up
if self.up:
@ -381,7 +405,7 @@ else:
inputs = self.GetInput()
# SendInput() supports all Unicode symbols
num_inserted_events = SendInput(len(inputs), ctypes.byref(inputs),
num_inserted_events = win32functions.SendInput(len(inputs), ctypes.byref(inputs),
ctypes.sizeof(win32structures.INPUT))
if num_inserted_events != len(inputs):
raise RuntimeError('SendInput() inserted only ' + str(num_inserted_events) +
@ -447,7 +471,7 @@ else:
# return self.key, 0, 0
# this works for Tic Tac Toe i.e. +{RIGHT} SHIFT + RIGHT
return self.key, MapVirtualKey(self.key, 0), flags
return self.key, win32functions.MapVirtualKeyW(self.key, 0), flags
def run(self):
"""Execute the action"""
@ -468,9 +492,9 @@ else:
The vk and scan code are generated differently.
"""
vkey_scan = LoByte(VkKeyScan(self.key))
vkey_scan = LoByte(win32functions.VkKeyScanW(self.key))
return (vkey_scan, MapVirtualKey(vkey_scan, 0), 0)
return (vkey_scan, win32functions.MapVirtualKeyW(vkey_scan, 0), 0)
def key_description(self):
"""Return a description of the key"""
@ -500,7 +524,7 @@ else:
__repr__ = __str__
def handle_code(code):
def handle_code(code, vk_packet):
"""Handle a key or sequence of keys in braces"""
code_keys = []
# it is a known code (e.g. {DOWN}, {ENTER}, etc)
@ -509,7 +533,10 @@ else:
# it is an escaped modifier e.g. {%}, {^}, {+}
elif len(code) == 1:
code_keys.append(KeyAction(code))
if not vk_packet and code in ascii_vk:
code_keys.append(VirtualKeyAction(ascii_vk[code]))
else:
code_keys.append(KeyAction(code))
# it is a repetition or a pause {DOWN 5}, {PAUSE 1.3}
elif ' ' in code:
@ -535,7 +562,7 @@ else:
[VirtualKeyAction(CODES[to_repeat])] * count)
# otherwise parse the keys and we get back a KeyAction
else:
to_repeat = parse_keys(to_repeat)
to_repeat = parse_keys(to_repeat, vk_packet=vk_packet)
if isinstance(to_repeat, list):
keys = to_repeat * count
else:
@ -550,7 +577,8 @@ else:
with_spaces=False,
with_tabs=False,
with_newlines=False,
modifiers=None):
modifiers=None,
vk_packet=True):
"""Return the parsed keys"""
keys = []
if not modifiers:
@ -579,8 +607,10 @@ else:
end_pos = string.find(")", index)
if end_pos == -1:
raise KeySequenceError('`)` not found')
keys.extend(
parse_keys(string[index:end_pos], modifiers=modifiers))
keys.extend(parse_keys(
string[index:end_pos],
modifiers=modifiers,
vk_packet=vk_packet))
index = end_pos + 1
# Escape or named key
@ -597,7 +627,7 @@ else:
if any(key_event in code.lower() for key_event in key_events):
code, current_key_event = code.split(' ')
should_escape_next_keys = True
current_keys = handle_code(code)
current_keys = handle_code(code, vk_packet)
if current_key_event is not None:
if isinstance(current_keys[0].key, six.string_types):
current_keys[0] = EscapedKeyAction(current_keys[0].key)
@ -636,6 +666,11 @@ else:
elif modifiers or should_escape_next_keys:
keys.append(EscapedKeyAction(c))
# if user disables the vk_packet option, always try to send a
# virtual key of the actual keystroke
elif not vk_packet and c in ascii_vk:
keys.append(VirtualKeyAction(ascii_vk[c]))
else:
keys.append(KeyAction(c))
@ -667,9 +702,12 @@ else:
with_spaces=False,
with_tabs=False,
with_newlines=False,
turn_off_numlock=True):
turn_off_numlock=True,
vk_packet=True):
"""Parse the keys and type them"""
keys = parse_keys(keys, with_spaces, with_tabs, with_newlines)
keys = parse_keys(
keys, with_spaces, with_tabs, with_newlines,
vk_packet=vk_packet)
for k in keys:
k.run()

@ -382,7 +382,7 @@ class PauseAction(KeyAction):
__repr__ = __str__
def handle_code(code):
def handle_code(code, vk_packet=True):
"""Handle a key or sequence of keys in braces"""
code_keys = []
# it is a known code (e.g. {DOWN}, {ENTER}, etc)
@ -433,7 +433,8 @@ def parse_keys(string,
with_spaces = False,
with_tabs = False,
with_newlines = False,
modifiers = None):
modifiers = None,
vk_packet=True):
"""Return the parsed keys"""
keys = []
if not modifiers:
@ -523,7 +524,8 @@ def send_keys(keys,
with_spaces=False,
with_tabs=False,
with_newlines=False,
turn_off_numlock=True):
turn_off_numlock=True,
vk_packet=True):
"""Parse the keys and type them"""
keys = parse_keys(keys, with_spaces, with_tabs, with_newlines)
for k in keys:

@ -35,10 +35,15 @@ Win32 API functions to perform custom marshalling
from __future__ import print_function
import sys
import ctypes
import win32api
import win32process
from ctypes import wintypes
from ctypes import c_void_p
from ctypes import pointer
from ctypes import sizeof
from ctypes import byref
from ctypes import c_size_t
from ctypes import WinError
from . import win32functions
from . import win32defines
from . import win32structures
@ -70,10 +75,12 @@ class RemoteMemoryBlock(object):
self._as_parameter_ = self.mem_address
_, process_id = win32process.GetWindowThreadProcessId(self.handle)
pid = wintypes.DWORD()
win32functions.GetWindowThreadProcessId(self.handle, byref(pid))
process_id = pid.value
if not process_id:
raise AccessDenied(
str(ctypes.WinError()) + " Cannot get process ID from handle.")
str(WinError()) + " Cannot get process ID from handle.")
self.process = win32functions.OpenProcess(
win32defines.PROCESS_VM_OPERATION |
@ -85,12 +92,12 @@ class RemoteMemoryBlock(object):
if not self.process:
raise AccessDenied(
str(ctypes.WinError()) + "process: %d",
str(WinError()) + "process: %d",
process_id)
self.mem_address = win32functions.VirtualAllocEx(
ctypes.c_void_p(self.process), # remote process
ctypes.c_void_p(0), # let Valloc decide where
c_void_p(self.process), # remote process
c_void_p(0), # let Valloc decide where
win32structures.ULONG_PTR(self.size + 4), # how much to allocate
win32defines.MEM_RESERVE | \
win32defines.MEM_COMMIT, # allocation type
@ -100,7 +107,7 @@ class RemoteMemoryBlock(object):
self.mem_address = self.mem_address.value
if self.mem_address == 0:
raise ctypes.WinError()
raise WinError()
if hex(self.mem_address) == '0xffffffff80000000' or hex(self.mem_address).upper() == '0xFFFFFFFF00000000':
raise Exception('Incorrect allocation: ' + hex(self.mem_address))
@ -108,11 +115,11 @@ class RemoteMemoryBlock(object):
self._as_parameter_ = self.mem_address
# write guard signature at the end of memory block
signature = win32structures.LONG(0x66666666)
signature = wintypes.LONG(0x66666666)
ret = win32functions.WriteProcessMemory(
ctypes.c_void_p(self.process),
ctypes.c_void_p(self.mem_address + self.size),
ctypes.pointer(signature),
c_void_p(self.process),
c_void_p(self.mem_address + self.size),
pointer(signature),
win32structures.ULONG_PTR(4),
win32structures.ULONG_PTR(0)
)
@ -129,7 +136,7 @@ class RemoteMemoryBlock(object):
if ret == 0:
ActionLogger().log('Warning: cannot close process handle!')
#raise ctypes.WinError()
#raise WinError()
#----------------------------------------------------------------
def CleanUp(self):
@ -140,17 +147,17 @@ class RemoteMemoryBlock(object):
self.CheckGuardSignature()
ret = win32functions.VirtualFreeEx(
ctypes.c_void_p(self.process),
ctypes.c_void_p(self.mem_address),
c_void_p(self.process),
c_void_p(self.mem_address),
win32structures.ULONG_PTR(0),
win32structures.DWORD(win32defines.MEM_RELEASE))
wintypes.DWORD(win32defines.MEM_RELEASE))
if ret == 0:
print('Error: CleanUp: VirtualFreeEx() returned zero for address ', hex(self.mem_address))
last_error = win32api.GetLastError()
print('LastError = ', last_error, ': ', win32api.FormatMessage(last_error).rstrip())
sys.stdout.flush()
self._CloseHandle()
raise ctypes.WinError()
raise WinError()
self.mem_address = 0
self._CloseHandle()
else:
@ -180,7 +187,7 @@ class RemoteMemoryBlock(object):
if size:
nSize = win32structures.ULONG_PTR(size)
else:
nSize = win32structures.ULONG_PTR(ctypes.sizeof(data))
nSize = win32structures.ULONG_PTR(sizeof(data))
if self.size < nSize.value:
raise Exception(('Write: RemoteMemoryBlock is too small ({0} bytes),' +
@ -190,19 +197,19 @@ class RemoteMemoryBlock(object):
raise Exception('Write: RemoteMemoryBlock has incorrect address = ' + hex(address))
ret = win32functions.WriteProcessMemory(
ctypes.c_void_p(self.process),
ctypes.c_void_p(address),
ctypes.pointer(data),
c_void_p(self.process),
c_void_p(address),
pointer(data),
nSize,
win32structures.ULONG_PTR(0)
)
if ret == 0:
ActionLogger().log('Error: Write failed: address = ', address)
ActionLogger().log('Error: Write failed: address = ' + str(address))
last_error = win32api.GetLastError()
ActionLogger().log('Error: LastError = ', last_error, ': ',
ActionLogger().log('Error: LastError = ' + str(last_error) + ': ' +
win32api.FormatMessage(last_error).rstrip())
raise ctypes.WinError()
raise WinError()
self.CheckGuardSignature()
#----------------------------------------------------------------
@ -216,7 +223,7 @@ class RemoteMemoryBlock(object):
if size:
nSize = win32structures.ULONG_PTR(size)
else:
nSize = win32structures.ULONG_PTR(ctypes.sizeof(data))
nSize = win32structures.ULONG_PTR(sizeof(data))
if self.size < nSize.value:
raise Exception(('Read: RemoteMemoryBlock is too small ({0} bytes),' +
@ -225,14 +232,14 @@ class RemoteMemoryBlock(object):
if hex(address).lower().startswith('0xffffff'):
raise Exception('Read: RemoteMemoryBlock has incorrect address =' + hex(address))
lpNumberOfBytesRead = ctypes.c_size_t(0)
lpNumberOfBytesRead = c_size_t(0)
ret = win32functions.ReadProcessMemory(
ctypes.c_void_p(self.process),
ctypes.c_void_p(address),
ctypes.byref(data),
c_void_p(self.process),
c_void_p(address),
byref(data),
nSize,
ctypes.byref(lpNumberOfBytesRead)
byref(lpNumberOfBytesRead)
)
# disabled as it often returns an error - but
@ -240,27 +247,27 @@ class RemoteMemoryBlock(object):
if ret == 0:
# try again
ret = win32functions.ReadProcessMemory(
ctypes.c_void_p(self.process),
ctypes.c_void_p(address),
ctypes.byref(data),
c_void_p(self.process),
c_void_p(address),
byref(data),
nSize,
ctypes.byref(lpNumberOfBytesRead)
byref(lpNumberOfBytesRead)
)
if ret == 0:
last_error = win32api.GetLastError()
if last_error != win32defines.ERROR_PARTIAL_COPY:
ActionLogger().log('Read: WARNING! self.mem_address =' +
hex(self.mem_address) + ' data address =' + str(ctypes.byref(data)))
hex(self.mem_address) + ' data address =' + str(byref(data)))
ActionLogger().log('LastError = ' + str(last_error) +
': ' + win32api.FormatMessage(last_error).rstrip())
else:
ActionLogger().log('Error: ERROR_PARTIAL_COPY')
ActionLogger().log('\nRead: WARNING! self.mem_address =' +
hex(self.mem_address) + ' data address =' + str(ctypes.byref(data)))
hex(self.mem_address) + ' data address =' + str(byref(data)))
ActionLogger().log('lpNumberOfBytesRead =' +
str(lpNumberOfBytesRead) + ' nSize =' + str(nSize))
raise ctypes.WinError()
raise WinError()
else:
ActionLogger().log('Warning! Read OK: 2nd attempt!')
#else:
@ -273,18 +280,18 @@ class RemoteMemoryBlock(object):
def CheckGuardSignature(self):
"""read guard signature at the end of memory block"""
signature = win32structures.LONG(0)
lpNumberOfBytesRead = ctypes.c_size_t(0)
lpNumberOfBytesRead = c_size_t(0)
ret = win32functions.ReadProcessMemory(
ctypes.c_void_p(self.process),
ctypes.c_void_p(self.mem_address + self.size),
ctypes.pointer(signature), # 0x66666666
c_void_p(self.process),
c_void_p(self.mem_address + self.size),
pointer(signature), # 0x66666666
win32structures.ULONG_PTR(4),
ctypes.byref(lpNumberOfBytesRead))
byref(lpNumberOfBytesRead))
if ret == 0:
ActionLogger().log('Error: Failed to read guard signature: address = ' +
hex(self.mem_address) + ', size = ' + str(self.size) +
', lpNumberOfBytesRead = ' + str(lpNumberOfBytesRead))
raise ctypes.WinError()
raise WinError()
else:
if hex(signature.value) != '0x66666666':
raise Exception('---------------------------------------- ' +

@ -82,8 +82,8 @@ class IUIA(object):
end_len = len('ControlTypeId')
self._control_types = [attr[start_len:-end_len] for attr in dir(self.UIA_dll) if attr.endswith('ControlTypeId')]
self.known_control_types = {} # string id: numeric id
self.known_control_type_ids = {} # numeric id: string id
self.known_control_types = { 'InvalidControlType': 0 } # string id: numeric id
self.known_control_type_ids = { 0: 'InvalidControlType' } # numeric id: string id
for ctrl_type in self._control_types:
type_id_name = 'UIA_' + ctrl_type + 'ControlTypeId'
@ -218,6 +218,8 @@ scroll_no_amount = IUIA().ui_automation_client.ScrollAmount_NoAmount
scroll_large_increment = IUIA().ui_automation_client.ScrollAmount_LargeIncrement
scroll_small_increment = IUIA().ui_automation_client.ScrollAmount_SmallIncrement
vt_empty = IUIA().ui_automation_client.VARIANT.empty.vt
vt_null = IUIA().ui_automation_client.VARIANT.null.vt
def get_elem_interface(element_info, pattern_name):
"""A helper to retrieve an element interface by the specified pattern name

@ -79,7 +79,6 @@ windll.user32.SetWindowsHookExA.restype = wintypes.HHOOK
windll.user32.SetWindowsHookExA.argtypes = [c_int, HOOKCB, wintypes.HINSTANCE, wintypes.DWORD]
windll.user32.SetWindowsHookExW.restype = wintypes.HHOOK
windll.user32.SetWindowsHookExW.argtypes = [c_int, HOOKCB, wintypes.HINSTANCE, wintypes.DWORD]
windll.user32.GetMessageW.argtypes = [POINTER(wintypes.MSG), wintypes.HWND, c_uint, c_uint]
windll.user32.TranslateMessage.argtypes = [POINTER(wintypes.MSG)]
windll.user32.DispatchMessageW.argtypes = [POINTER(wintypes.MSG)]
@ -452,7 +451,7 @@ class Hook(object):
al = ActionLogger()
al.log("_process_kbd_msg_type, bad event_type: {0}".format(event_type))
if event_type == 'key down':
if event_type == 'key down' and current_key not in self.pressed_keys:
self.pressed_keys.append(current_key)
elif event_type == 'key up':
if current_key in self.pressed_keys:

@ -31,192 +31,678 @@
"""Defines Windows(tm) functions"""
import ctypes
from ctypes import LibraryLoader
from ctypes import WinDLL
from ctypes import wintypes
from . import win32defines, win32structures
from .actionlogger import ActionLogger
from ctypes import c_uint, c_short, c_long
from ctypes import c_short
from ctypes import WINFUNCTYPE
from ctypes import c_void_p
from ctypes import c_int
from ctypes import byref
from ctypes import POINTER
from ctypes import c_ubyte
from ctypes import c_size_t
# Quote: "If you want cached libs without polluting ctypes.cdll or
# ctypes.windll, just create your own instance such as
# windll = ctypes.LibraryLoader(ctypes.WinDLL)."
# see https://bugs.python.org/issue22552
windll = LibraryLoader(WinDLL)
import sys
if sys.platform == "cygwin":
windll = ctypes.cdll
HRESULT = c_long
UINT = c_uint
SHORT = c_short
CreateBrushIndirect = ctypes.windll.gdi32.CreateBrushIndirect
CreateDC = ctypes.windll.gdi32.CreateDCW
CreateFontIndirect = ctypes.windll.gdi32.CreateFontIndirectW
CreatePen = ctypes.windll.gdi32.CreatePen
DeleteDC = ctypes.windll.gdi32.DeleteDC
GetObject = ctypes.windll.gdi32.GetObjectW
DeleteObject = ctypes.windll.gdi32.DeleteObject
DrawText = ctypes.windll.user32.DrawTextW
TextOut = ctypes.windll.gdi32.TextOutW
Rectangle = ctypes.windll.gdi32.Rectangle
SelectObject = ctypes.windll.gdi32.SelectObject
GetStockObject = ctypes.windll.gdi32.GetStockObject
GetSystemMetrics = ctypes.windll.user32.GetSystemMetrics
GetSystemMetrics.restype = ctypes.c_int
GetSystemMetrics.argtypes = (ctypes.c_int, )
GetTextMetrics = ctypes.windll.gdi32.GetTextMetricsW
EnumChildWindows = ctypes.windll.user32.EnumChildWindows
EnumDesktopWindows = ctypes.windll.user32.EnumDesktopWindows
EnumWindows = ctypes.windll.user32.EnumWindows
GetDC = ctypes.windll.user32.GetDC
GetDesktopWindow = ctypes.windll.user32.GetDesktopWindow
SendInput = ctypes.windll.user32.SendInput
SetCursorPos = ctypes.windll.user32.SetCursorPos
GetCursorPos = ctypes.windll.user32.GetCursorPos
GetCaretPos = ctypes.windll.user32.GetCaretPos
CreateBrushIndirect = windll.gdi32.CreateBrushIndirect
CreateBrushIndirect.restype = wintypes.HBRUSH
CreateBrushIndirect.argtypes = [
c_void_p,
]
CreateDC = windll.gdi32.CreateDCW
CreateDC.restype = wintypes.HDC
CreateDC.argtypes = [
wintypes.LPCWSTR,
wintypes.LPCWSTR,
wintypes.LPCWSTR,
c_void_p,
]
CreateFontIndirect = windll.gdi32.CreateFontIndirectW
CreateFontIndirect.restype = wintypes.HFONT
CreateFontIndirect.argtypes = [
POINTER(win32structures.LOGFONTW),
]
CreatePen = windll.gdi32.CreatePen
CreatePen.restype = wintypes.HPEN
CreatePen.argtypes = [
c_int,
c_int,
wintypes.COLORREF,
]
DeleteDC = windll.gdi32.DeleteDC
DeleteDC.restype = wintypes.BOOL
DeleteDC.argtypes = [
wintypes.HDC,
]
GetObject = windll.gdi32.GetObjectW
GetObject.restype = c_int
GetObject.argtypes = [
wintypes.HANDLE,
c_int,
wintypes.LPVOID,
]
DeleteObject = windll.gdi32.DeleteObject
DeleteObject.restype = wintypes.BOOL
DeleteObject.argtypes = [
wintypes.HGDIOBJ,
]
DrawText = windll.user32.DrawTextW
DrawText.restype = c_int
DrawText.argtypes = [
wintypes.HDC,
wintypes.LPCWSTR,
c_int,
POINTER(wintypes.RECT),
wintypes.UINT,
]
TextOut = windll.gdi32.TextOutW
TextOut.restype = wintypes.BOOL
TextOut.argtypes = [
wintypes.HDC,
c_int,
c_int,
wintypes.LPCWSTR,
c_int,
]
Rectangle = windll.gdi32.Rectangle
Rectangle.restype = wintypes.BOOL
Rectangle.argtypes = [
wintypes.HDC,
c_int,
c_int,
c_int,
c_int,
]
SelectObject = windll.gdi32.SelectObject
SelectObject.restype = wintypes.HGDIOBJ
SelectObject.argtypes = [
wintypes.HDC,
wintypes.HGDIOBJ,
]
GetStockObject = windll.gdi32.GetStockObject
GetStockObject.restype = wintypes.HGDIOBJ
GetStockObject.argtypes = [
c_int,
]
GetSystemMetrics = windll.user32.GetSystemMetrics
GetSystemMetrics.restype = c_int
GetSystemMetrics.argtypes = [
c_int,
]
GetTextMetrics = windll.gdi32.GetTextMetricsW
GetTextMetrics.restype = wintypes.BOOL
GetTextMetrics.argtypes = [
wintypes.HDC,
POINTER(win32structures.TEXTMETRICW),
]
EnumChildWindows = windll.user32.EnumChildWindows
EnumChildWindows.restype = wintypes.BOOL
EnumChildWindows.argtypes = [
wintypes.HWND,
WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM),
wintypes.LPARAM,
]
EnumDesktopWindows = windll.user32.EnumDesktopWindows
EnumDesktopWindows.restype = wintypes.BOOL
EnumDesktopWindows.argtypes = [
wintypes.LPVOID,
WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM),
wintypes.LPARAM,
]
EnumWindows = windll.user32.EnumWindows
EnumWindows.restype = wintypes.BOOL
EnumWindows.argtypes = [
WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM),
wintypes.LPARAM,
]
GetDC = windll.user32.GetDC
GetDC.restype = wintypes.LPVOID
GetDC.argtypes = [
wintypes.HWND,
]
GetDesktopWindow = windll.user32.GetDesktopWindow
GetDesktopWindow.restype = wintypes.HWND
GetDesktopWindow.argtypes = [
]
SendInput = windll.user32.SendInput
SendInput.restype = wintypes.UINT
SendInput.argtypes = [
wintypes.UINT,
c_void_p, # using POINTER(win32structures.INPUT) needs rework in keyboard.py
c_int,
]
SetCursorPos = windll.user32.SetCursorPos
SetCursorPos.restype = wintypes.BOOL
SetCursorPos.argtypes = [
c_int,
c_int,
]
GetCursorPos = windll.user32.GetCursorPos
GetCursorPos.restype = wintypes.BOOL
GetCursorPos.argtypes = [
POINTER(wintypes.POINT),
]
GetCaretPos = windll.user32.GetCaretPos
GetCaretPos.restype = wintypes.BOOL
GetCaretPos.argtypes = [
POINTER(wintypes.POINT),
]
GetKeyboardState = windll.user32.GetKeyboardState
GetKeyboardState.restype = wintypes.BOOL
GetKeyboardState.argtypes = [
POINTER(c_ubyte),
]
SetKeyboardState = windll.user32.SetKeyboardState
SetKeyboardState.restype = wintypes.BOOL
SetKeyboardState.argtypes = [
POINTER(c_ubyte),
]
GetKeyboardLayout = windll.user32.GetKeyboardLayout
GetKeyboardLayout.restype = wintypes.HKL
GetKeyboardLayout.argtypes = [
wintypes.DWORD,
]
VkKeyScanW = windll.user32.VkKeyScanW
VkKeyScanW.restype = SHORT
VkKeyScanW.argtypes = [
wintypes.WCHAR,
]
VkKeyScanExW = windll.user32.VkKeyScanExW
VkKeyScanExW.restype = SHORT
VkKeyScanExW.argtypes = [
wintypes.WCHAR,
wintypes.HKL,
]
GetMessageExtraInfo = windll.user32.GetMessageExtraInfo
MapVirtualKeyW = windll.user32.MapVirtualKeyW
# menu functions
DrawMenuBar = ctypes.windll.user32.DrawMenuBar
GetMenu = ctypes.windll.user32.GetMenu
GetMenuBarInfo = ctypes.windll.user32.GetMenuBarInfo
GetMenuInfo = ctypes.windll.user32.GetMenuInfo
GetMenuItemCount = ctypes.windll.user32.GetMenuItemCount
GetMenuItemInfo = ctypes.windll.user32.GetMenuItemInfoW
SetMenuItemInfo = ctypes.windll.user32.SetMenuItemInfoW
GetMenuItemRect = ctypes.windll.user32.GetMenuItemRect
CheckMenuItem = ctypes.windll.user32.CheckMenuItem
GetMenuState = ctypes.windll.user32.GetMenuState
GetSubMenu = ctypes.windll.user32.GetSubMenu
GetSystemMenu = ctypes.windll.user32.GetSystemMenu
HiliteMenuItem = ctypes.windll.user32.HiliteMenuItem
IsMenu = ctypes.windll.user32.IsMenu
MenuItemFromPoint = ctypes.windll.user32.MenuItemFromPoint
BringWindowToTop = ctypes.windll.user32.BringWindowToTop
GetVersion = ctypes.windll.kernel32.GetVersion
GetParent = ctypes.windll.user32.GetParent
GetWindow = ctypes.windll.user32.GetWindow
ShowWindow = ctypes.windll.user32.ShowWindow
GetWindowContextHelpId = ctypes.windll.user32.GetWindowContextHelpId
GetWindowLong = ctypes.windll.user32.GetWindowLongW
GetWindowPlacement = ctypes.windll.user32.GetWindowPlacement
GetWindowRect = ctypes.windll.user32.GetWindowRect
GetWindowText = ctypes.windll.user32.GetWindowTextW
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
GetClassName = ctypes.windll.user32.GetClassNameW
GetClassName.argtypes = [win32structures.HWND, wintypes.LPWSTR, ctypes.c_int]
GetClassName.restrype = ctypes.c_int
GetClientRect = ctypes.windll.user32.GetClientRect
IsChild = ctypes.windll.user32.IsChild
IsWindow = ctypes.windll.user32.IsWindow
IsWindow.argtypes = [win32structures.HWND]
IsWindow.restype = win32structures.BOOL
IsWindowUnicode = ctypes.windll.user32.IsWindowUnicode
IsWindowUnicode.argtypes = [win32structures.HWND]
IsWindowUnicode.restype = win32structures.BOOL
IsWindowVisible = ctypes.windll.user32.IsWindowVisible
IsWindowVisible.argtypes = [win32structures.HWND]
IsWindowVisible.restype = win32structures.BOOL
IsWindowEnabled = ctypes.windll.user32.IsWindowEnabled
IsWindowEnabled.argtypes = [win32structures.HWND]
IsWindowEnabled.restype = win32structures.BOOL
ClientToScreen = ctypes.windll.user32.ClientToScreen
ScreenToClient = ctypes.windll.user32.ScreenToClient
GetCurrentThreadId = ctypes.windll.Kernel32.GetCurrentThreadId
GetWindowThreadProcessId = ctypes.windll.user32.GetWindowThreadProcessId
GetGUIThreadInfo = ctypes.windll.user32.GetGUIThreadInfo
AttachThreadInput = ctypes.windll.user32.AttachThreadInput
AttachThreadInput.restype = win32structures.BOOL
AttachThreadInput.argtypes = [win32structures.DWORD, win32structures.DWORD, win32structures.BOOL]
#GetWindowThreadProcessId = ctypes.windll.user32.GetWindowThreadProcessId
GetLastError = ctypes.windll.kernel32.GetLastError
OpenProcess = ctypes.windll.kernel32.OpenProcess
CloseHandle = ctypes.windll.kernel32.CloseHandle
CreateProcess = ctypes.windll.kernel32.CreateProcessW
TerminateProcess = ctypes.windll.kernel32.TerminateProcess
ExitProcess = ctypes.windll.kernel32.ExitProcess
ReadProcessMemory = ctypes.windll.kernel32.ReadProcessMemory
GlobalAlloc = ctypes.windll.kernel32.GlobalAlloc
GlobalLock = ctypes.windll.kernel32.GlobalLock
GlobalUnlock = ctypes.windll.kernel32.GlobalUnlock
SendMessage = ctypes.windll.user32.SendMessageW
SendMessageTimeout = ctypes.windll.user32.SendMessageTimeoutW
SendMessageTimeout.argtypes = [win32structures.HWND, win32structures.UINT, win32structures.WPARAM,
win32structures.LPARAM, win32structures.UINT, win32structures.UINT,
win32structures.PDWORD_PTR]
SendMessageTimeout.restype = win32structures.LRESULT
SendMessageA = ctypes.windll.user32.SendMessageA
PostMessage = ctypes.windll.user32.PostMessageW
GetMessage = ctypes.windll.user32.GetMessageW
RegisterWindowMessage = ctypes.windll.user32.RegisterWindowMessageW
RegisterWindowMessage.restype = UINT
MoveWindow = ctypes.windll.user32.MoveWindow
EnableWindow = ctypes.windll.user32.EnableWindow
SetActiveWindow = ctypes.windll.user32.SetActiveWindow
GetFocus = ctypes.windll.user32.GetFocus
SetFocus = ctypes.windll.user32.SetFocus
SetForegroundWindow = ctypes.windll.user32.SetForegroundWindow
GetForegroundWindow = ctypes.windll.user32.GetForegroundWindow
SetWindowLong = ctypes.windll.user32.SetWindowLongW
DrawMenuBar = windll.user32.DrawMenuBar
DrawMenuBar.restype = wintypes.BOOL
DrawMenuBar.argstype = [
wintypes.HWND,
]
GetMenu = windll.user32.GetMenu
GetMenu.restype = wintypes.HMENU
GetMenu.argtypes = [
wintypes.HWND,
]
GetMenuBarInfo = windll.user32.GetMenuBarInfo
GetMenuBarInfo.restype = wintypes.BOOL
GetMenuBarInfo.argtypes = [
wintypes.HWND,
wintypes.LONG,
wintypes.LONG,
POINTER(win32structures.MENUBARINFO),
]
GetMenuInfo = windll.user32.GetMenuInfo
GetMenuInfo.restype = wintypes.BOOL
GetMenuInfo.argtypes = [
wintypes.HWND,
POINTER(win32structures.MENUINFO),
]
GetMenuItemCount = windll.user32.GetMenuItemCount
GetMenuItemCount.restype = c_int
GetMenuItemCount.argtypes = [
wintypes.HMENU,
]
GetMenuItemInfo = windll.user32.GetMenuItemInfoW
GetMenuItemInfo.restype = wintypes.BOOL
GetMenuItemInfo.argtypes = [
wintypes.HMENU,
wintypes.UINT,
wintypes.BOOL,
POINTER(win32structures.MENUITEMINFOW),
]
SetMenuItemInfo = windll.user32.SetMenuItemInfoW
SetMenuItemInfo.restype = wintypes.BOOL
SetMenuItemInfo.argtypes = [
wintypes.HMENU,
wintypes.UINT,
wintypes.BOOL,
POINTER(win32structures.MENUITEMINFOW),
]
GetMenuItemRect = windll.user32.GetMenuItemRect
GetMenuItemRect.restype = wintypes.BOOL
GetMenuItemRect.argtypes = [
wintypes.HWND,
wintypes.HMENU,
wintypes.UINT,
POINTER(wintypes.RECT),
]
CheckMenuItem = windll.user32.CheckMenuItem
CheckMenuItem.restype = wintypes.DWORD
CheckMenuItem.argtypes = [
wintypes.HMENU,
wintypes.UINT,
wintypes.UINT,
]
GetMenuState = windll.user32.GetMenuState
GetMenuState.restype = wintypes.UINT
GetMenuState.argtypes = [
wintypes.HMENU,
wintypes.UINT,
wintypes.UINT,
]
GetSubMenu = windll.user32.GetSubMenu
GetSubMenu.restype = wintypes.HMENU
GetSubMenu.argtypes = [
wintypes.HMENU,
c_int,
]
GetSystemMenu = windll.user32.GetSystemMenu
GetSystemMenu.restype = wintypes.HMENU
GetSystemMenu.argtypes = [
wintypes.HWND,
wintypes.BOOL,
]
HiliteMenuItem = windll.user32.HiliteMenuItem
HiliteMenuItem.restype = wintypes.BOOL
HiliteMenuItem.argtypes = [
wintypes.HWND,
wintypes.HMENU,
wintypes.UINT,
wintypes.UINT,
]
IsMenu = windll.user32.IsMenu
IsMenu.restype = wintypes.BOOL
IsMenu.argtypes = [
wintypes.HMENU,
]
MenuItemFromPoint = windll.user32.MenuItemFromPoint
MenuItemFromPoint.restype = c_int
MenuItemFromPoint.argtypes = [
wintypes.HWND,
wintypes.HMENU,
POINTER(wintypes.POINT),
]
BringWindowToTop = windll.user32.BringWindowToTop
BringWindowToTop.restype = wintypes.BOOL
BringWindowToTop.argtypes = [
wintypes.HWND,
]
GetParent = windll.user32.GetParent
GetParent.restype = wintypes.HWND
GetParent.argtypes = [
wintypes.HWND,
]
GetWindow = windll.user32.GetWindow
GetWindow.restype = wintypes.HWND
GetWindow.argtypes = [
wintypes.HWND,
wintypes.UINT,
]
ShowWindow = windll.user32.ShowWindow
ShowWindow.restype = wintypes.BOOL
ShowWindow.argtypes = [
wintypes.HWND,
c_int,
]
GetWindowContextHelpId = windll.user32.GetWindowContextHelpId
GetWindowContextHelpId.restype = wintypes.DWORD
GetWindowContextHelpId.argtypes = [
wintypes.HWND,
]
GetWindowLong = windll.user32.GetWindowLongW
GetWindowLong.restype = wintypes.LONG
GetWindowLong.argtypes = [
wintypes.HWND,
c_int,
]
GetWindowPlacement = windll.user32.GetWindowPlacement
GetWindowPlacement.restype = wintypes.BOOL
GetWindowPlacement.argtypes = [
wintypes.HWND,
POINTER(win32structures.WINDOWPLACEMENT),
]
GetWindowRect = windll.user32.GetWindowRect
GetWindowRect.restype = wintypes.BOOL
GetWindowRect.argtypes = [
wintypes.HWND,
POINTER(wintypes.RECT),
]
GetWindowText = windll.user32.GetWindowTextW
GetWindowText.restype = c_int
GetWindowText.argtypes = [
wintypes.HWND,
wintypes.LPWSTR,
c_int,
]
GetWindowTextLength = windll.user32.GetWindowTextLengthW
GetWindowTextLength.restype = c_int
GetWindowTextLength.argtypes = [
wintypes.HWND,
]
GetClassName = windll.user32.GetClassNameW
GetClassName.restype = c_int
GetClassName.argtypes = [
wintypes.HWND,
wintypes.LPWSTR,
c_int,
]
GetClientRect = windll.user32.GetClientRect
GetClientRect.restype = wintypes.BOOL
GetClientRect.argtypes = [
wintypes.HWND,
POINTER(wintypes.RECT),
]
IsChild = windll.user32.IsChild
IsChild.restype = wintypes.BOOL
IsChild.argtypes = [
wintypes.HWND,
wintypes.HWND,
]
IsWindow = windll.user32.IsWindow
IsWindow.restype = wintypes.BOOL
IsWindow.argtypes = [
wintypes.HWND,
]
IsWindowUnicode = windll.user32.IsWindowUnicode
IsWindowUnicode.restype = wintypes.BOOL
IsWindowUnicode.argtypes = [
wintypes.HWND,
]
IsWindowVisible = windll.user32.IsWindowVisible
IsWindowVisible.restype = wintypes.BOOL
IsWindowVisible.argtypes = [
wintypes.HWND,
]
IsWindowEnabled = windll.user32.IsWindowEnabled
IsWindowEnabled.restype = wintypes.BOOL
IsWindowEnabled.argtypes = [
wintypes.HWND,
]
ClientToScreen = windll.user32.ClientToScreen
ClientToScreen.restype = wintypes.BOOL
ClientToScreen.argtypes = [
wintypes.HWND,
POINTER(wintypes.POINT),
]
ScreenToClient = windll.user32.ScreenToClient
ScreenToClient.restype = wintypes.BOOL
ScreenToClient.argtypes = [
wintypes.HWND,
POINTER(wintypes.POINT),
]
GetCurrentThreadId = windll.kernel32.GetCurrentThreadId
GetCurrentThreadId.restype = wintypes.DWORD
GetCurrentThreadId.argtypes = [
]
GetWindowThreadProcessId = windll.user32.GetWindowThreadProcessId
GetWindowThreadProcessId.restype = wintypes.DWORD
GetWindowThreadProcessId.argtypes = [
wintypes.HWND,
POINTER(wintypes.DWORD),
]
GetGUIThreadInfo = windll.user32.GetGUIThreadInfo
GetGUIThreadInfo.restype = wintypes.BOOL
GetGUIThreadInfo.argtypes = [
wintypes.DWORD,
POINTER(win32structures.GUITHREADINFO),
]
AttachThreadInput = windll.user32.AttachThreadInput
AttachThreadInput.restype = wintypes.BOOL
AttachThreadInput.argtypes = [
wintypes.DWORD,
wintypes.DWORD,
wintypes.BOOL
]
OpenProcess = windll.kernel32.OpenProcess
OpenProcess.restype = wintypes.HANDLE
OpenProcess.argtypes = [
wintypes.DWORD,
wintypes.BOOL,
wintypes.DWORD,
]
CloseHandle = windll.kernel32.CloseHandle
CloseHandle.restype = wintypes.BOOL
CloseHandle.argtypes = [
wintypes.HANDLE,
]
CreateProcess = windll.kernel32.CreateProcessW
CreateProcess.restype = wintypes.BOOL
CreateProcess.argtypes = [
wintypes.LPCWSTR,
wintypes.LPWSTR,
POINTER(win32structures.SECURITY_ATTRIBUTES),
POINTER(win32structures.SECURITY_ATTRIBUTES),
wintypes.BOOL,
wintypes.DWORD,
wintypes.LPVOID,
wintypes.LPCWSTR,
POINTER(win32structures.STARTUPINFOW),
POINTER(win32structures.PROCESS_INFORMATION),
]
TerminateProcess = windll.kernel32.TerminateProcess
TerminateProcess.restype = wintypes.BOOL
TerminateProcess.argtypes = [
wintypes.HANDLE,
wintypes.UINT,
]
ExitProcess = windll.kernel32.ExitProcess
ExitProcess.restype = None
ExitProcess.argtypes = [
wintypes.UINT,
]
ReadProcessMemory = windll.kernel32.ReadProcessMemory
ReadProcessMemory.restype = wintypes.BOOL
ReadProcessMemory.argtypes = [
wintypes.HANDLE,
wintypes.LPVOID,
wintypes.LPVOID,
c_size_t,
POINTER(c_size_t),
]
GlobalAlloc = windll.kernel32.GlobalAlloc
GlobalLock = windll.kernel32.GlobalLock
GlobalUnlock = windll.kernel32.GlobalUnlock
SendMessage = windll.user32.SendMessageW
SendMessage.restype = wintypes.LPARAM
SendMessage.argtypes = [
wintypes.HWND,
wintypes.UINT,
wintypes.WPARAM,
wintypes.LPVOID,
]
SendMessageTimeout = windll.user32.SendMessageTimeoutW
SendMessageTimeout.restype = wintypes.LPARAM
SendMessageTimeout.argtypes = [
wintypes.HWND,
wintypes.UINT,
wintypes.WPARAM,
wintypes.LPARAM,
wintypes.UINT,
wintypes.UINT,
win32structures.PDWORD_PTR,
]
PostMessage = windll.user32.PostMessageW
PostMessage.restype = wintypes.BOOL
PostMessage.argtypes = [
wintypes.HWND,
wintypes.UINT,
wintypes.WPARAM,
wintypes.LPARAM,
]
GetMessage = windll.user32.GetMessageW
GetMessage.restype = wintypes.BOOL
GetMessage.argtypes = [
POINTER(wintypes.MSG),
wintypes.HWND,
wintypes.UINT,
wintypes.UINT,
]
RegisterWindowMessage = windll.user32.RegisterWindowMessageW
RegisterWindowMessage.restype = wintypes.UINT
RegisterWindowMessage.argtypes = [
wintypes.LPCWSTR,
]
MoveWindow = windll.user32.MoveWindow
MoveWindow.restype = wintypes.BOOL
MoveWindow.argtypes = [
wintypes.HWND,
c_int,
c_int,
c_int,
c_int,
wintypes.BOOL,
]
EnableWindow = windll.user32.EnableWindow
EnableWindow.restype = wintypes.BOOL
EnableWindow.argtypes = [
wintypes.HWND,
wintypes.BOOL,
]
SetFocus = windll.user32.SetFocus
SetFocus.restype = wintypes.HWND
SetFocus.argtypes = [
wintypes.HWND,
]
SetWindowLong = windll.user32.SetWindowLongW
SetWindowLong.restype = wintypes.LONG
SetWindowLong.argtypes = [
wintypes.HWND,
c_int,
wintypes.LONG,
]
try:
SetWindowLongPtr = ctypes.windll.user32.SetWindowLongPtrW
SetWindowLongPtr.argtypes = [win32structures.HWND, ctypes.c_int, win32structures.LONG_PTR]
SetWindowLongPtr.restype = win32structures.LONG_PTR
SetWindowLongPtr = windll.user32.SetWindowLongPtrW
SetWindowLongPtr.argtypes = [wintypes.HWND, c_int, wintypes.LONG_PTR]
SetWindowLongPtr.restype = wintypes.LONG_PTR
except AttributeError:
SetWindowLongPtr = SetWindowLong
SystemParametersInfo = ctypes.windll.user32.SystemParametersInfoW
VirtualAllocEx = ctypes.windll.kernel32.VirtualAllocEx
VirtualAllocEx.restype = ctypes.c_void_p
VirtualFreeEx = ctypes.windll.kernel32.VirtualFreeEx
DebugBreakProcess = ctypes.windll.kernel32.DebugBreakProcess
VirtualAlloc = ctypes.windll.kernel32.VirtualAlloc
VirtualFree = ctypes.windll.kernel32.VirtualFree
WriteProcessMemory = ctypes.windll.kernel32.WriteProcessMemory
GetActiveWindow = ctypes.windll.user32.GetActiveWindow
GetLastActivePopup = ctypes.windll.user32.GetLastActivePopup
FindWindow = ctypes.windll.user32.FindWindowW
GetTopWindow = ctypes.windll.user32.GetTopWindow
SetCapture = ctypes.windll.user32.SetCapture
ReleaseCapture = ctypes.windll.user32.ReleaseCapture
ShowOwnedPopups = ctypes.windll.user32.ShowOwnedPopups
WindowFromPoint = ctypes.windll.user32.WindowFromPoint
WideCharToMultiByte = ctypes.windll.kernel32.WideCharToMultiByte
GetACP = ctypes.windll.kernel32.GetACP
WaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject
WaitForInputIdle = ctypes.windll.user32.WaitForInputIdle
IsHungAppWindow = ctypes.windll.user32.IsHungAppWindow
IsHungAppWindow.restype = win32structures.BOOL
IsHungAppWindow.argtypes = [win32structures.HWND]
GetModuleFileNameEx = ctypes.windll.psapi.GetModuleFileNameExW
GetClipboardData = ctypes.windll.user32.GetClipboardData
OpenClipboard = ctypes.windll.user32.OpenClipboard
EmptyClipboard = ctypes.windll.user32.EmptyClipboard
CloseClipboard = ctypes.windll.user32.CloseClipboard
CountClipboardFormats = ctypes.windll.user32.CountClipboardFormats
EnumClipboardFormats = ctypes.windll.user32.EnumClipboardFormats
GetClipboardFormatName = ctypes.windll.user32.GetClipboardFormatNameW
SystemParametersInfo = windll.user32.SystemParametersInfoW
SystemParametersInfo.restype = wintypes.UINT
SystemParametersInfo.argtypes = [
wintypes.UINT,
wintypes.UINT,
wintypes.LPVOID, # should map well to PVOID
wintypes.UINT,
]
VirtualAllocEx = windll.kernel32.VirtualAllocEx
VirtualAllocEx.restype = wintypes.LPVOID
VirtualAllocEx.argtypes = [
wintypes.HANDLE,
wintypes.LPVOID,
c_size_t,
wintypes.DWORD,
wintypes.DWORD,
]
VirtualFreeEx = windll.kernel32.VirtualFreeEx
VirtualFreeEx.restype = wintypes.BOOL
VirtualFreeEx.argtypes = [
wintypes.HANDLE,
wintypes.LPVOID,
c_size_t,
wintypes.DWORD,
]
VirtualAlloc = windll.kernel32.VirtualAlloc
VirtualAlloc.restype = wintypes.LPVOID
VirtualAlloc.argtypes = [
wintypes.LPVOID,
c_size_t,
wintypes.DWORD,
wintypes.DWORD,
]
VirtualFree = windll.kernel32.VirtualFree
VirtualFree.retype = wintypes.BOOL
VirtualFree.argtypes = [
wintypes.LPVOID,
c_size_t,
wintypes.DWORD,
]
WriteProcessMemory = windll.kernel32.WriteProcessMemory
WriteProcessMemory.restype = wintypes.BOOL
WriteProcessMemory.argtypes = [
wintypes.HANDLE,
wintypes.LPVOID,
wintypes.LPVOID,
c_size_t,
POINTER(c_size_t),
]
ReleaseCapture = windll.user32.ReleaseCapture
ReleaseCapture.restype = wintypes.BOOL
ReleaseCapture.argtypes = [
]
WindowFromPoint = windll.user32.WindowFromPoint
WindowFromPoint.restype = wintypes.HWND
WindowFromPoint.argtypes = [
wintypes.POINT,
]
WaitForSingleObject = windll.kernel32.WaitForSingleObject
WaitForSingleObject.restype = wintypes.DWORD
WaitForSingleObject.argtypes = [
wintypes.HANDLE,
wintypes.DWORD,
]
WaitForInputIdle = windll.user32.WaitForInputIdle
WaitForInputIdle.restype = wintypes.DWORD
WaitForInputIdle.argtypes = [
wintypes.HANDLE,
wintypes.DWORD,
]
IsHungAppWindow = windll.user32.IsHungAppWindow
IsHungAppWindow.restype = wintypes.BOOL
IsHungAppWindow.argtypes = [
wintypes.HWND,
]
GetModuleFileNameEx = windll.psapi.GetModuleFileNameExW
GetModuleFileNameEx.restype = wintypes.DWORD
GetModuleFileNameEx.argtypes = [
wintypes.HANDLE,
wintypes.HMODULE,
wintypes.LPWSTR,
wintypes.DWORD,
]
GetClipboardData = windll.user32.GetClipboardData
GetClipboardData.restype = wintypes.HANDLE
GetClipboardData.argtypes = [
wintypes.UINT,
]
OpenClipboard = windll.user32.OpenClipboard
OpenClipboard.restype = wintypes.BOOL
OpenClipboard.argtypes = [
wintypes.HWND,
]
EmptyClipboard = windll.user32.EmptyClipboard
EmptyClipboard.restype = wintypes.BOOL
EmptyClipboard.argtypes = [
]
CloseClipboard = windll.user32.CloseClipboard
CloseClipboard.restype = wintypes.BOOL
CloseClipboard.argtypes = [
]
CountClipboardFormats = windll.user32.CountClipboardFormats
CountClipboardFormats.restype = c_int
CountClipboardFormats.argtypes = [
]
EnumClipboardFormats = windll.user32.EnumClipboardFormats
EnumClipboardFormats.restype = wintypes.UINT
EnumClipboardFormats.argtypes = [
wintypes.UINT,
]
GetClipboardFormatName = windll.user32.GetClipboardFormatNameW
GetClipboardFormatName.restype = c_int
GetClipboardFormatName.argtypes = [
wintypes.UINT,
wintypes.LPWSTR,
c_int,
]
# DPIAware API funcs are not available on WinXP
try:
IsProcessDPIAware = ctypes.windll.user32.IsProcessDPIAware
SetProcessDPIAware = ctypes.windll.user32.SetProcessDPIAware
IsProcessDPIAware = windll.user32.IsProcessDPIAware
SetProcessDPIAware = windll.user32.SetProcessDPIAware
except AttributeError:
IsProcessDPIAware = None
SetProcessDPIAware = None
@ -230,7 +716,7 @@ except AttributeError:
# Process_Per_Monitor_DPI_Aware = 2
# } Process_DPI_Awareness;
try:
shcore = ctypes.windll.LoadLibrary("Shcore.dll")
shcore = windll.LoadLibrary("Shcore.dll")
SetProcessDpiAwareness = shcore.SetProcessDpiAwareness
GetProcessDpiAwareness = shcore.GetProcessDpiAwareness
Process_DPI_Awareness = {
@ -252,26 +738,17 @@ elif SetProcessDPIAware:
ActionLogger().log("Call SetProcessDPIAware")
SetProcessDPIAware()
GetQueueStatus = ctypes.windll.user32.GetQueueStatus
GetQueueStatus = windll.user32.GetQueueStatus
LoadString = ctypes.windll.user32.LoadStringW
LoadString = windll.user32.LoadStringW
#def VkKeyScanW(p1):
# # C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4225
# return VkKeyScanW._api_(p1)
#VkKeyScan = stdcall(SHORT, 'user32', [c_wchar]) (VkKeyScanW)
#
#def MapVirtualKeyExW(p1, p2, p3):
# # C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4376
# return MapVirtualKeyExW._api_(p1, p2, p3)
#MapVirtualKeyEx = stdcall(
# UINT, 'user32', [c_uint, c_uint, c_long]) (MapVirtualKeyExW)
#
#def MapVirtualKeyW(p1, p2):
# # C:/PROGRA~1/MICROS~4/VC98/Include/winuser.h 4355
# return MapVirtualKeyW._api_(p1, p2)
#MapVirtualKey = stdcall(UINT, 'user32', [c_uint, c_uint]) (MapVirtualKeyW)
#====================================================================
@ -297,7 +774,7 @@ def LoWord(value):
def WaitGuiThreadIdle(handle):
"""Wait until the thread of the specified handle is ready"""
process_id = wintypes.DWORD(0)
GetWindowThreadProcessId(handle, ctypes.POINTER(wintypes.DWORD)(process_id))
GetWindowThreadProcessId(handle, byref(process_id))
# ask the control if it has finished processing the message
hprocess = OpenProcess(
@ -327,10 +804,10 @@ def GetDpiAwarenessByPid(pid):
return dpi_awareness
try:
dpi_awareness = ctypes.c_int()
dpi_awareness = c_int()
hRes = GetProcessDpiAwareness(
hProcess,
ctypes.byref(dpi_awareness))
byref(dpi_awareness))
CloseHandle(hProcess)
if hRes == 0:
return dpi_awareness.value

@ -32,19 +32,18 @@
"""Definition of Windows structures"""
import six
import ctypes
from ctypes import Structure as Struct
from ctypes import \
c_int, c_uint, c_long, c_ulong, c_void_p, c_wchar, c_char, \
c_ubyte, c_ushort, \
c_int, c_long, c_void_p, c_char, memmove, addressof, \
POINTER, sizeof, alignment, Union, c_longlong, c_size_t, wintypes
from .win32defines import LF_FACESIZE
from . import sysinfo
class Structure(ctypes.Structure):
class StructureMixIn(object):
"""Override the Structure class from ctypes to add printing and comparison"""
"""Define printing and comparison behaviors to be used for the Structure class from ctypes"""
#----------------------------------------------------------------
def __str__(self):
@ -52,47 +51,59 @@ class Structure(ctypes.Structure):
fields in exceptList will not be printed"""
lines = []
for f in self._fields_:
name = f[0]
lines.append("%20s\t%s"% (name, getattr(self, name)))
for field_name, _ in getattr(self, "_fields_", []):
lines.append("%20s\t%s"% (field_name, getattr(self, field_name)))
return "\n".join(lines)
#----------------------------------------------------------------
def __eq__(self, other_struct):
"""Return True if the two structures have the same coordinates"""
if isinstance(other_struct, ctypes.Structure):
def __eq__(self, other):
"""Return True if the two instances have the same coordinates"""
fields = getattr(self, "_fields_", [])
if isinstance(other, Struct):
try:
# pretend they are two structures - check that they both
# have the same value for all fields
are_equal = True
for field in self._fields_:
name = field[0]
if getattr(self, name) != getattr(other_struct, name):
are_equal = False
break
return are_equal
if len(fields) != len(getattr(other, "_fields_", [])):
return False
for field_name, _ in fields:
if getattr(self, field_name) != getattr(other, field_name):
return False
return True
except AttributeError:
return False
if isinstance(other_struct, (list, tuple)):
elif isinstance(other, (list, tuple)):
# Now try to see if we have been passed in a list or tuple
if len(fields) != len(other):
return False
try:
are_equal = True
for i, field in enumerate(self._fields_):
name = field[0]
if getattr(self, name) != other_struct[i]:
are_equal = False
break
return are_equal
for i, (field_name, _) in enumerate(fields):
if getattr(self, field_name) != other[i]:
return False
return True
except Exception:
return False
return False
#----------------------------------------------------------------
def __ne__(self, other):
"""Return False if the two instances have the same coordinates"""
return not self.__eq__(other)
__hash__ = None
class Structure(Struct, StructureMixIn):
"""Override the Structure class from ctypes to add printing and comparison"""
pass
##====================================================================
#def PrintCtypesStruct(struct, exceptList = []):
# """Print out the fields of the ctypes Structure
@ -110,7 +121,7 @@ class Structure(ctypes.Structure):
# e.g. RECT.__reduce__ = _reduce
def _construct(typ, buf):
obj = typ.__new__(typ)
ctypes.memmove(ctypes.addressof(obj), buf, len(buf))
memmove(addressof(obj), buf, len(buf))
return obj
def _reduce(self):
@ -119,21 +130,21 @@ def _reduce(self):
#LPTTTOOLINFOW = POINTER(tagTOOLINFOW)
#PTOOLINFOW = POINTER(tagTOOLINFOW)
BOOL = c_int
BYTE = c_ubyte
BOOL = wintypes.BOOL
BYTE = wintypes.BYTE
CHAR = c_char
DWORD = c_ulong
HANDLE = c_void_p
HBITMAP = c_long
LONG = c_long
LPVOID = c_void_p
DWORD = wintypes.DWORD
HANDLE = wintypes.HANDLE
HBITMAP = HANDLE
LONG = wintypes.LONG
LPVOID = wintypes.LPVOID
PVOID = c_void_p
UINT = c_uint
WCHAR = c_wchar
WORD = c_ushort
UINT = wintypes.UINT
WCHAR = wintypes.WCHAR
WORD = wintypes.WORD
LRESULT = wintypes.LPARAM
COLORREF = DWORD
COLORREF = wintypes.COLORREF
LPBYTE = POINTER(BYTE)
LPWSTR = c_size_t #POINTER(WCHAR)
DWORD_PTR = UINT_PTR = ULONG_PTR = c_size_t
@ -143,26 +154,20 @@ if sysinfo.is_x64_Python():
else:
INT_PTR = LONG_PTR = c_long
HBITMAP = LONG_PTR #LONG
HINSTANCE = LONG_PTR #LONG
HMENU = LONG_PTR #LONG
HBRUSH = LONG_PTR #LONG
HBRUSH = wintypes.HBRUSH # LONG_PTR #LONG
HTREEITEM = LONG_PTR #LONG
HWND = LONG_PTR #LONG
HWND = wintypes.HWND
# TODO: switch to ctypes.wintypes.LPARAM and ctypes.wintypes.WPARAM
# Notice that wintypes definition of LPARAM/WPARAM differs between 32/64 bit
LPARAM = LONG_PTR
WPARAM = UINT_PTR
LPARAM = wintypes.LPARAM
WPARAM = wintypes.WPARAM
class POINT(Structure):
_pack_ = 4
_fields_ = [
# C:/PROGRA~1/MIAF9D~1/VC98/Include/windef.h 307
('x', LONG),
('y', LONG),
]
class POINT(wintypes.POINT, StructureMixIn):
"""Wrap the POINT structure and add extra functionality"""
def __iter__(self):
"""Allow iteration through coordinates"""
@ -178,25 +183,18 @@ class POINT(Structure):
else:
raise IndexError("Illegal index")
assert sizeof(POINT) == 8, sizeof(POINT)
assert alignment(POINT) == 4, alignment(POINT)
# ====================================================================
class RECT(Structure):
class RECT(wintypes.RECT, StructureMixIn):
"""Wrap the RECT structure and add extra functionality"""
_fields_ = [
# C:/PROGRA~1/MIAF9D~1/VC98/Include/windef.h 287
('left', LONG),
('top', LONG),
('right', LONG),
('bottom', LONG),
]
# ----------------------------------------------------------------
def __init__(self, otherRect_or_left = 0, top = 0, right = 0, bottom = 0):
def __init__(self, otherRect_or_left=0, top=0, right=0, bottom=0):
"""Provide a constructor for RECT structures
A RECT can be constructed by:
@ -220,20 +218,6 @@ class RECT(Structure):
self.top = long_int(top)
self.bottom = long_int(bottom)
# # ----------------------------------------------------------------
# def __eq__(self, otherRect):
# "return true if the two rectangles have the same coordinates"
#
# try:
# return \
# self.left == otherRect.left and \
# self.top == otherRect.top and \
# self.right == otherRect.right and \
# self.bottom == otherRect.bottom
# except AttributeError:
# return False
# ----------------------------------------------------------------
def __str__(self):
"""Return a string representation of the RECT"""
@ -286,18 +270,17 @@ class RECT(Structure):
def mid_point(self):
"""Return a POINT structure representing the mid point"""
pt = POINT()
pt.x = self.left + int(float(self.width())/2.)
pt.y = self.top + int(float(self.height())/2.)
pt.x = self.left + int(float(self.width()) / 2.)
pt.y = self.top + int(float(self.height()) / 2.)
return pt
#def __hash__(self):
# return hash (self.left, self.top, self.right, self.bottom)
__reduce__ = _reduce
RECT.__reduce__ = _reduce
assert sizeof(RECT) == 16, sizeof(RECT)
assert alignment(RECT) == 4, alignment(RECT)
class SETTEXTEX(Structure):
_pack_ = 1
_fields_ = [

@ -3,7 +3,7 @@ r"""
The OpenRPA package (from UnicodeLabs)
"""
__version__ = 'v1.1.12'
__version__ = 'v1.1.13'
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from .Core import Robot

@ -2,7 +2,7 @@ from setuptools import setup, find_packages
import Version
import os
def LongDescriptionRead():
with open('pyOpenRPA/README.md') as f:
with open('pyOpenRPA/README.md', "r", encoding="utf-8") as f:
return f.read()
#Do pyOpenRPA package __init__ __version__ update
@ -31,18 +31,25 @@ setup(name='pyOpenRPA',
long_description=LongDescriptionRead(),
long_description_content_type='text/markdown',
classifiers=[
'Development Status :: 3 - Alpha',
'Development Status :: 5 - Production/Stable',
'License :: OSI Approved :: MIT License',
'Intended Audience :: Developers',
'Programming Language :: Python',
'Programming Language :: Python :: 3.7',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Software Development :: Testing',
'Topic :: Software Development :: User Interfaces',
'Topic :: Software Development :: Quality Assurance',
'Topic :: Home Automation'
],
keywords='OpenRPA RPA Robot Automation Robotization',
keywords='OpenRPA RPA Robot Automation Robotization OpenSource',
url='https://gitlab.com/UnicodeLabs/OpenRPA',
author='Ivan Maslov',
author_email='Ivan.Maslov@unicodelabs.ru',
license='MIT',
packages=find_packages(),
install_requires=[
'pywinauto>=0.6.6','WMI>=1.4.9','pillow>=6.0.0','keyboard>=0.13.3','pyautogui>=0.9.44','pywin32>=224', 'crypto>=1.4.1'
'pywinauto>=0.6.8','WMI>=1.4.9','pillow>=6.0.0','keyboard>=0.13.3','pyautogui>=0.9.44','pywin32>=224', 'crypto>=1.4.1'
],
include_package_data=True,
#data_files = datafiles,

Loading…
Cancel
Save