# Use Pandas to find and interact with handles, windows, and elements
### This library doesn't need Pywin32, it uses ctypes!
#### Inspired by [pywinauto](https://github.com/pywinauto/pywinauto), but [Pandas ](https://pandas.pydata.org/)is used to localize
#### elements and call functions. Sounds weird, but it is
#### extremely efficient and will save you a lot of time. Try it.
##### Here is a vídeo (in Brazilian Portuguese)
[![YT](https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/mcll.png)](https://www.youtube.com/watch?v=c3MaVFzqAvw)
[https://www.youtube.com/watch?v=c3MaVFzqAvw]()
```python
$pip install pdwinauto
# How to get the DataFrames (Tested with Windows 10 - Python 3.9.13)
from pdwinauto import (mkey, get_window_frame, get_automation_frame, get_automation_frame_from_pid,
get_automation_frame_from_filenames, get_automation_frame_from_all_pids, )
mkey.enable_failsafekill("ctrl+e") #Always use a failsafe
# Here are some way you can use to get the DataFrame
df1 = get_automation_frame_from_pid(pids=[12720, 3684], uia=True, screenshot_folder='f:\\screenshotstestx1', timeout=30)
df2 = get_automation_frame_from_filenames(["chrome.exe", "mspaint.exe"], uia=True, screenshot_folder=None, timeout=30)
df3 = get_automation_frame_from_all_pids(uia=True, screenshot_folder=None)
df4 = get_window_frame(pid=0)
df5 = get_automation_frame(df4,uia=True, screenshot_folder=None)
```
```python
# How to click on an element without moving the mouse:
# technically it is not a mouse click, but the results are the same
# You might encounter elements that don't work with these methods:
# 1) Sometimes the results are better using:
df.iloc[1].ff_Invoke()
df1.dropna(subset='ff_Invoke').iloc[0].ff_Invoke() # another example
# 2) and other times, this function works better (Uses PostMessage)
df.d_loc_no_exception('str.contains','Cancel',na=False,flags=re.I).aa_direct_click.iloc[0]()
```
```python
# How to click on an element with the mouse cursor:
# 1)
# The click does always work since it uses the coordinates instead of the handle.
# You don't have to pass the coordinates. The module takes care of it.
# Be careful: The function is executed at maximum speed.
df.mm_left_click_xy_direct.iloc[0]()
# If you want, you can pass an offset (from the center):
df.mm_left_click_xy_direct.iloc[0](offset_x=100,offset_y=100)
#-------------------------------------------------------------------------------------------#
# 2)
# If you prefer a slower, natural mouse movement:
df.mm_left_click_xy_natural.iloc[0](
delay=0.1, # duration of the mouse click (down - up)
min_variation=-3, # a random value will be added to each pixel - define the minimum here
max_variation=3, # a random value will be added to each pixel - define the maximum here
use_every=4, # use every nth pixel
sleeptime=(0.005, 0.009), # delay between each coordinate
print_coords=True, # console output
percent=90, # if you want to speed up the execution, lower this number
offset_x=50, # offset from the center
offset_y=100,) # offset from the center
# Also available for middle/right mouse click:
# Some examples:
df.mm_middle_click_xy_natural.iloc[0](offset_x=50, offset_y=100)
df.mm_right_click_xy_natural.iloc[0](offset_x=50, offset_y=100)
df.mm_right_click_xy_direct.iloc[0](offset_x=100,offset_y=100)
```
```python
# How to move the cursor to an element
df.mm_move_to_natural.iloc[0](offset_x=50, offset_y=100) # takes longer
df.mm_move_to_natural.iloc[0](use_every=10,offset_x=100, offset_y=100) # if you want to speed it up, lower the value of use_every
df.mm_moveto.iloc[0](offset_x=50, offset_y=100) # immediately
```
```python
# How to save all screenshots to the HDD:
df1.screenshot_save.apply(lambda x:x())
```
```python
# How to send keystrokes
# 1)
# The Window cannot be minimized if you use this function.
# You can find all valid keys here: mkey.show_all_keys,
df.mm_press_key.iloc[0]('b',delay=1)
#-------------------------------------------------------------------------------------------#
# 2)
# This function works when the window is minimized,
# it restores the window, and sets focus, but it also moves the mouse.
df.mm_press_key_force_activate.iloc[0]('a',1)
#-------------------------------------------------------------------------------------------#
# 3)
# Code based on:
# https://pywinauto.readthedocs.io
# The key codes are the same.
df.mm_send_keystrokes.iloc[0]('%{F4}') # Closing the window: '%{F4}' (alt+f4)
#-------------------------------------------------------------------------------------------#
# 4) Send as many keystrokes as you want simultaneously
# Use force activate to make sure that the strokes go to the right window
df.mm_press_keys_simultaneously.iloc[0](["alt", "f4"], 1.1)
df.mm_press_keys_simultaneously_force_activate.iloc[0](["alt", "f4"], 1.1) # better
#-------------------------------------------------------------------------------------------#
# 5) Send Unicode
df.mm_send_unicode.iloc[0]('HGax&&öp')
# Use force activate to make sure that it goes to the right window
df.mm_send_unicode_force_activate.iloc[0]('HGax&&öp')
```
```python
# How to activate (set focus to) a window
# works most of the time and doesn't change mouse position
df.mm_activate_window.iloc[0]()
#-------------------------------------------------------------------------------------------#
# This function has been working for me without any problem.
# It always activates the window and sets focus,
# But it changes the mouse position
df.mm_force_activate_window.iloc[0]()
# You can also try this:
df.ff_Select.iloc[0](1)
```
### More useful stuff:
```python
# How to close the window/app
df.dropna(subset='ff_Close').iloc[0].ff_Close()
##############################################################################################
# move the window to (10,10) without resizing
df.dropna(subset='ff_Move').iloc[1].ff_Move(10,10)
##############################################################################################
# get a DataFrame with all children from an element:
df.dropna(subset='aa_all_children').iloc[1].aa_show_children()
##############################################################################################
# If you want to search in the whole DataFrame without getting any Exception ;-) :
df.d_loc_no_exception('str.contains','Cancel',na=False,flags=re.I).aa_direct_click.iloc[0]()
##############################################################################################
# maximize a window
df.window_maximize.iloc[0]()
##############################################################################################
# minimize a window
df.window_minimize.iloc[0]()
##############################################################################################
# restore windows
df.window_restore.iloc[0]()
##############################################################################################
# hide window
df.window_hide.iloc[0]()
##############################################################################################
# show window
df.window_show.iloc[0]()
##############################################################################################
# window to normal size
df.window_normal.iloc[0]()
##############################################################################################
# force minimize
df.window_forceminimize.iloc[0]()
##############################################################################################
# resizing a window:
df.iloc[0].resize_window( (0,0,100,100))
##############################################################################################
```
## Here is an example with Notepad:
```python
from pdwinauto import (
mkey,
click_on_main_menu,
click_on_submenu,
get_automation_frame_from_pid,
sleep
)
mkey.enable_failsafekill("ctrl+e")
n1,n2 = "&File","&Save\tCtrl+S"
filepath = "F:\\tesa\\testtext1.txt"
text = "Hallo, mein Freund, wie geht es dir?"
pid = 11660
gdf = lambda: get_automation_frame_from_pid(pid)
df = gdf()
df.mm_send_unicode_force_activate.iloc[0](text)
sleep(1)
df4 = df.dropna(subset="aa_menu_items")
click_on_main_menu(df4[:1], menu1text=n1)
sleep(1)
df2 = gdf()
click_on_submenu(df2.dropna(subset="aa_menu_items"
), menu1text=n1, menu2text=n2)
while True:
sleep(2)
try:
df = gdf()
f1 = df.d_loc_no_exception("str.contains",r"\.txt",
regex=True)
f2 = f1.d_loc_no_exception("str.contains",r"Edit")
f2.iloc[0].mm_send_unicode_force_activate(filepath)
sleep(2)
df.loc[df.ff_CurrentDefaultAction ==
"Save"].iloc[0].ff_DoDefaultAction()
sleep(1)
(df.loc[~df.ff_Close.isna() &
(df.aa_title == 'Notepad')]
.iloc[0].ff_Close())
break
except Exception as fe:
continue
```
<img title="" src="https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000000.png" alt="">
<img title="" src="https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000001.png" alt="">
<img title="" src="https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000002.png" alt="">
<img title="" src="https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000003.png" alt="">
<img title="" src="https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000004.png" alt="">
<img title="" src="https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000005.png" alt="">
<img title="" src="https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000006.png" alt="">
Raw data
{
"_id": null,
"home_page": "https://github.com/hansalemaos/pdwinauto",
"name": "pdwinauto",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "automation,pandas,pyautogui,pywinauto,win32,uia",
"author": "Johannes Fischer",
"author_email": "<aulasparticularesdealemaosp@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/90/2c/82448857670026400c0fef917af2c635e8f6f919d4379a78d955acb25c11/pdwinauto-0.11.tar.gz",
"platform": null,
"description": "\n# Use Pandas to find and interact with handles, windows, and elements\n\n\n\n### This library doesn't need Pywin32, it uses ctypes!\n\n\n\n#### Inspired by [pywinauto](https://github.com/pywinauto/pywinauto), but [Pandas ](https://pandas.pydata.org/)is used to localize\n\n\n\n#### elements and call functions. Sounds weird, but it is\n\n\n\n#### extremely efficient and will save you a lot of time. Try it.\n\n\n\n##### Here is a v\u00eddeo (in Brazilian Portuguese)\n\n\n\n[![YT](https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/mcll.png)](https://www.youtube.com/watch?v=c3MaVFzqAvw)\n\n\n\n[https://www.youtube.com/watch?v=c3MaVFzqAvw]()\n\n\n\n```python\n\n$pip install pdwinauto\n\n# How to get the DataFrames (Tested with Windows 10 - Python 3.9.13)\n\n\n\nfrom pdwinauto import (mkey, get_window_frame, get_automation_frame, get_automation_frame_from_pid,\n\n get_automation_frame_from_filenames, get_automation_frame_from_all_pids, )\n\nmkey.enable_failsafekill(\"ctrl+e\") #Always use a failsafe \n\n\n\n# Here are some way you can use to get the DataFrame\n\ndf1 = get_automation_frame_from_pid(pids=[12720, 3684], uia=True, screenshot_folder='f:\\\\screenshotstestx1', timeout=30)\n\ndf2 = get_automation_frame_from_filenames([\"chrome.exe\", \"mspaint.exe\"], uia=True, screenshot_folder=None, timeout=30)\n\ndf3 = get_automation_frame_from_all_pids(uia=True, screenshot_folder=None)\n\ndf4 = get_window_frame(pid=0)\n\ndf5 = get_automation_frame(df4,uia=True, screenshot_folder=None)\n\n```\n\n\n\n```python\n\n# How to click on an element without moving the mouse:\n\n# technically it is not a mouse click, but the results are the same \n\n# You might encounter elements that don't work with these methods:\n\n\n\n# 1) Sometimes the results are better using:\n\ndf.iloc[1].ff_Invoke()\n\ndf1.dropna(subset='ff_Invoke').iloc[0].ff_Invoke() # another example\n\n\n\n# 2) and other times, this function works better (Uses PostMessage)\n\ndf.d_loc_no_exception('str.contains','Cancel',na=False,flags=re.I).aa_direct_click.iloc[0]()\n\n```\n\n\n\n```python\n\n# How to click on an element with the mouse cursor:\n\n# 1)\n\n# The click does always work since it uses the coordinates instead of the handle.\n\n# You don't have to pass the coordinates. The module takes care of it. \n\n# Be careful: The function is executed at maximum speed. \n\ndf.mm_left_click_xy_direct.iloc[0]()\n\n# If you want, you can pass an offset (from the center):\n\ndf.mm_left_click_xy_direct.iloc[0](offset_x=100,offset_y=100)\n\n#-------------------------------------------------------------------------------------------#\n\n# 2) \n\n# If you prefer a slower, natural mouse movement:\n\ndf.mm_left_click_xy_natural.iloc[0]( \n\n delay=0.1, # duration of the mouse click (down - up)\n\n min_variation=-3, # a random value will be added to each pixel - define the minimum here\n\n max_variation=3, # a random value will be added to each pixel - define the maximum here\n\n use_every=4, # use every nth pixel\n\n sleeptime=(0.005, 0.009), # delay between each coordinate\n\n print_coords=True, # console output\n\n percent=90, # if you want to speed up the execution, lower this number\n\n offset_x=50, # offset from the center \n\n offset_y=100,) # offset from the center \n\n\n\n# Also available for middle/right mouse click:\n\n# Some examples:\n\ndf.mm_middle_click_xy_natural.iloc[0](offset_x=50, offset_y=100)\n\ndf.mm_right_click_xy_natural.iloc[0](offset_x=50, offset_y=100)\n\ndf.mm_right_click_xy_direct.iloc[0](offset_x=100,offset_y=100)\n\n```\n\n\n\n```python\n\n# How to move the cursor to an element \n\ndf.mm_move_to_natural.iloc[0](offset_x=50, offset_y=100) # takes longer \n\ndf.mm_move_to_natural.iloc[0](use_every=10,offset_x=100, offset_y=100) # if you want to speed it up, lower the value of use_every\n\ndf.mm_moveto.iloc[0](offset_x=50, offset_y=100) # immediately\n\n```\n\n\n\n```python\n\n# How to save all screenshots to the HDD:\n\ndf1.screenshot_save.apply(lambda x:x())\n\n```\n\n\n\n```python\n\n# How to send keystrokes \n\n# 1) \n\n# The Window cannot be minimized if you use this function. \n\n# You can find all valid keys here: mkey.show_all_keys,\n\ndf.mm_press_key.iloc[0]('b',delay=1) \n\n#-------------------------------------------------------------------------------------------#\n\n# 2)\n\n# This function works when the window is minimized,\n\n# it restores the window, and sets focus, but it also moves the mouse.\n\ndf.mm_press_key_force_activate.iloc[0]('a',1)\n\n#-------------------------------------------------------------------------------------------#\n\n# 3)\n\n# Code based on:\n\n# https://pywinauto.readthedocs.io\n\n# The key codes are the same. \n\ndf.mm_send_keystrokes.iloc[0]('%{F4}') # Closing the window: '%{F4}' (alt+f4)\n\n#-------------------------------------------------------------------------------------------#\n\n# 4) Send as many keystrokes as you want simultaneously\n\n# Use force activate to make sure that the strokes go to the right window\n\ndf.mm_press_keys_simultaneously.iloc[0]([\"alt\", \"f4\"], 1.1) \n\ndf.mm_press_keys_simultaneously_force_activate.iloc[0]([\"alt\", \"f4\"], 1.1) # better \n\n#-------------------------------------------------------------------------------------------#\n\n# 5) Send Unicode\n\ndf.mm_send_unicode.iloc[0]('HGax&&\u00f6p')\n\n# Use force activate to make sure that it goes to the right window\n\ndf.mm_send_unicode_force_activate.iloc[0]('HGax&&\u00f6p')\n\n```\n\n\n\n```python\n\n# How to activate (set focus to) a window \n\n\n\n# works most of the time and doesn't change mouse position\n\ndf.mm_activate_window.iloc[0]()\n\n#-------------------------------------------------------------------------------------------#\n\n\n\n# This function has been working for me without any problem. \n\n# It always activates the window and sets focus, \n\n# But it changes the mouse position\n\ndf.mm_force_activate_window.iloc[0]()\n\n\n\n# You can also try this:\n\ndf.ff_Select.iloc[0](1)\n\n```\n\n\n\n### More useful stuff:\n\n\n\n```python\n\n# How to close the window/app\n\ndf.dropna(subset='ff_Close').iloc[0].ff_Close()\n\n##############################################################################################\n\n# move the window to (10,10) without resizing\n\ndf.dropna(subset='ff_Move').iloc[1].ff_Move(10,10)\n\n##############################################################################################\n\n# get a DataFrame with all children from an element:\n\ndf.dropna(subset='aa_all_children').iloc[1].aa_show_children()\n\n##############################################################################################\n\n# If you want to search in the whole DataFrame without getting any Exception ;-) :\n\ndf.d_loc_no_exception('str.contains','Cancel',na=False,flags=re.I).aa_direct_click.iloc[0]()\n\n##############################################################################################\n\n# maximize a window\n\ndf.window_maximize.iloc[0]()\n\n##############################################################################################\n\n# minimize a window\n\ndf.window_minimize.iloc[0]()\n\n##############################################################################################\n\n# restore windows\n\ndf.window_restore.iloc[0]()\n\n##############################################################################################\n\n# hide window\n\ndf.window_hide.iloc[0]()\n\n##############################################################################################\n\n# show window\n\ndf.window_show.iloc[0]()\n\n##############################################################################################\n\n# window to normal size\n\ndf.window_normal.iloc[0]()\n\n##############################################################################################\n\n# force minimize\n\ndf.window_forceminimize.iloc[0]()\n\n##############################################################################################\n\n# resizing a window:\n\ndf.iloc[0].resize_window( (0,0,100,100))\n\n##############################################################################################\n\n```\n\n\n\n## Here is an example with Notepad:\n\n\n\n```python\n\nfrom pdwinauto import (\n\n mkey,\n\n click_on_main_menu,\n\n click_on_submenu,\n\n get_automation_frame_from_pid,\n\n sleep\n\n)\n\nmkey.enable_failsafekill(\"ctrl+e\")\n\nn1,n2 = \"&File\",\"&Save\\tCtrl+S\"\n\nfilepath = \"F:\\\\tesa\\\\testtext1.txt\"\n\ntext = \"Hallo, mein Freund, wie geht es dir?\"\n\npid = 11660\n\ngdf = lambda: get_automation_frame_from_pid(pid)\n\ndf = gdf()\n\ndf.mm_send_unicode_force_activate.iloc[0](text)\n\nsleep(1)\n\ndf4 = df.dropna(subset=\"aa_menu_items\")\n\nclick_on_main_menu(df4[:1], menu1text=n1)\n\nsleep(1)\n\ndf2 = gdf()\n\nclick_on_submenu(df2.dropna(subset=\"aa_menu_items\"\n\n ), menu1text=n1, menu2text=n2)\n\nwhile True:\n\n sleep(2)\n\n try:\n\n df = gdf()\n\n f1 = df.d_loc_no_exception(\"str.contains\",r\"\\.txt\",\n\n regex=True)\n\n f2 = f1.d_loc_no_exception(\"str.contains\",r\"Edit\")\n\n f2.iloc[0].mm_send_unicode_force_activate(filepath)\n\n sleep(2)\n\n df.loc[df.ff_CurrentDefaultAction ==\n\n \"Save\"].iloc[0].ff_DoDefaultAction()\n\n sleep(1)\n\n (df.loc[~df.ff_Close.isna() &\n\n (df.aa_title == 'Notepad')]\n\n .iloc[0].ff_Close())\n\n break\n\n except Exception as fe:\n\n continue\n\n```\n\n\n\n<img title=\"\" src=\"https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000000.png\" alt=\"\">\n\n\n\n<img title=\"\" src=\"https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000001.png\" alt=\"\">\n\n\n\n<img title=\"\" src=\"https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000002.png\" alt=\"\">\n\n\n\n<img title=\"\" src=\"https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000003.png\" alt=\"\">\n\n\n\n<img title=\"\" src=\"https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000004.png\" alt=\"\">\n\n\n\n<img title=\"\" src=\"https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000005.png\" alt=\"\">\n\n\n\n<img title=\"\" src=\"https://github.com/hansalemaos/screenshots/raw/main/pdwinauto/00000006.png\" alt=\"\">\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Use Pandas to find and interact with handles, windows, and elements",
"version": "0.11",
"split_keywords": [
"automation",
"pandas",
"pyautogui",
"pywinauto",
"win32",
"uia"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "e72065fda04dd978730ea7bc0de497459c00237dc6f6df61a8021889fc862cb4",
"md5": "a64efe0ba9efbc76c83ecfc2f4a7fc8a",
"sha256": "f6c06ec9c530a53c27353ce996af8f92ab662342d8c674b74773857acc6d2dd3"
},
"downloads": -1,
"filename": "pdwinauto-0.11-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a64efe0ba9efbc76c83ecfc2f4a7fc8a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 21155,
"upload_time": "2023-01-31T22:45:31",
"upload_time_iso_8601": "2023-01-31T22:45:31.069358Z",
"url": "https://files.pythonhosted.org/packages/e7/20/65fda04dd978730ea7bc0de497459c00237dc6f6df61a8021889fc862cb4/pdwinauto-0.11-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "902c82448857670026400c0fef917af2c635e8f6f919d4379a78d955acb25c11",
"md5": "e0b2bdff83dc3afa3007ed761f37f83e",
"sha256": "9c8b59598e4f303e6753d87c247b3e6c70b2c1cff8920c63ad730c1ee135ff10"
},
"downloads": -1,
"filename": "pdwinauto-0.11.tar.gz",
"has_sig": false,
"md5_digest": "e0b2bdff83dc3afa3007ed761f37f83e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 20786,
"upload_time": "2023-01-31T22:45:32",
"upload_time_iso_8601": "2023-01-31T22:45:32.396201Z",
"url": "https://files.pythonhosted.org/packages/90/2c/82448857670026400c0fef917af2c635e8f6f919d4379a78d955acb25c11/pdwinauto-0.11.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-01-31 22:45:32",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "hansalemaos",
"github_project": "pdwinauto",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [],
"lcname": "pdwinauto"
}