spyoungtech / ahk

Python wrapper for AutoHotkey with full type support. Harness the automation power of AutoHotkey with the beauty of Python.
MIT License
887 stars 66 forks source link

After locating a window, unable to send key presses to window. #278

Closed newbiemate closed 7 months ago

newbiemate commented 7 months ago

describe your issue

I am trying to send key presses to a specific window. ahk is able to find the window, but doing win.send('f') doesn't actually do anything.

Here is an example:

The code:

from ahk import AHK

ahk = AHK()
win = ahk.find_window(title='a.txt - Notepad')

# This will grab the window too:
#win = ahk.win_get(title='a.txt - Notepad')

print(f'{win}')    # will print: <Window ahk_id='4064636'>

# Doing this brings Notepad.exe to focus, but still no text inside. But this should be working anyway without needing to focus the window.
# win.activate() 

while True:
    win.send('f')

Based on the README "Working with windows" section in the repo, this should be working? Or am I missing something?

I'm using this python binding: ahk==v1.5.3

ahk.version

2.0.12

AutoHotkey version

v2

Code to reproduce the issue

No response

Traceback/Error message

No response

spyoungtech commented 7 months ago

In AutoHotkey v2, the behavior of ControlSend (the underlying functionality of Window.send) changed to send keystrokes to the Window, rather than its topmost control (the previous behavior in v1). As noted in the README, under Differences when using AutoHotkey v1 vs AutoHotkey v2:

The behavior of ControlSend (ahk.control_send or Window.send or Control.send) differs in AutoHotkey v2 when the control parameter is not specified. In v1, keys are sent to the topmost controls, which is usually the correct behavior. In v2, keys are sent directly to the window. This means in many cases, you need to specify the control explicitly when using V2.

This is one of those cases that, when using AutoHotkey v2, you will need to specify the control explicitly. In the case of notepad, you would send keys to the control Edit1:

- win.send('f')
+ win.send('f', control='Edit1')

If you're not sure what the controls are for the window you're using, you can use win.list_controls() which will return a set of Control objects. You can also use the .send method on these objects, too.

controls = win.list_controls()
edit1 = controls[0]
edit1.send('f')
newbiemate commented 7 months ago

@spyoungtech you are right!

Thanks for the clarification. What happens if the window has no controls? ie, win.list_controls() returns []? Does this mean there is no way to send keys to that window?

spyoungtech commented 7 months ago

You can still send keys directly to the window with win.send. Whether that works as indented depends on how the application was developed. Another option might be to use ahk.send with the window active.