Forums: Forum d’aide (Thread #45725)

Windows: Sending keystrokes to TeraTerm (2022-04-21 07:20 by zitt #89537)

I am using Teraterm extensively to automate some interactions with the serial port. Teraterm effectively waits for a specific string then exits via a TTL macro.

I'm seeing some instability where sometimes the serial port has already sent the string I'm looking for and the macro just times out. However, if I send an enter key to the terminal window; the string is received and the macro completes successfully.

For reasons that I won't go into; I don't want to just automatically send the enter key from the macro as it can lead to other issues.

I have teraterm being launched from a python script which then looks at the log file when teraterm exits to determine where the macro was successful. What I want to do now is when I detect this rare 2% condition; I want to be able to send an enter key to the teraterm window for the "workaround" to trigger. I thought this would be easy as I've done it in the past scripts. However, I must be doing something wrong but can't figure out what it might be.

I've proven that if I manually interact with the Teraterm window and press a key; the intended action occurs.
However, if I use the example script below... I never see either the Enter key or the A key (used as a sanity check).

#
import pprint, time
import win32gui, win32con, win32api, win32process
from win32gui import SendMessage, GetWindowText, PostMessage, GetWindow

def get_hwnds_for_pid (pid):
print("in get_hwnds_for_pid(%d)" % pid)
def callback (hwnd, hwnds):
if win32gui.IsWindowVisible (hwnd) and win32gui.IsWindowEnabled (hwnd):
_, found_pid = win32process.GetWindowThreadProcessId (hwnd)
if found_pid == pid:
hwnds.append (hwnd)
return True

hwnds = []
win32gui.EnumWindows (callback, hwnds)
print(" returns: ", end='')
pprint.pprint(hwnds)
return hwnds

pid=12728
hwnd = get_hwnds_for_pid( pid )
for ahwnd in hwnd:
fval = win32api.SendMessage(ahwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
time.sleep(0.1)
fval2 = win32api.SendMessage(ahwnd, win32con.WM_KEYUP, win32con.VK_RETURN, 0)
print('Sent VK_RETURN(%x) to %x calculated from %x: %x %x' % (win32con.VK_RETURN, ahwnd, pid, fval, fval2))
win32api.PostMessage(ahwnd, win32con.WM_CHAR, 'A', 0)
print('Sent %x,A to %x calculated from %x: %x %x' % (win32con.WM_CHAR, ahwnd, pid, fval, fval2))



What am I missing? Why isn't the SendMessage Windows API successful in sending the keystroke to TeraTerm?

Re: Windows: Sending keystrokes to TeraTerm (2022-04-21 13:35 by zitt #89538)

Reply To Message #89537

Never mind; I did some more reading... using Spy++ to track down the messages / differences between physical interaction and my code. It turned out that TeraTerm seems to look at the cRepeat field of the message. I'm guess if zero there is some code to ignore the message.

So:
fval = win32api.SendMessage(ahwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
should be
fval = win32api.SendMessage(ahwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0x1)

see:
https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keydown

The entire loop now look like this:

for ahwnd in hwnd:
fval = win32api.SendMessage(ahwnd, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0x1)
time.sleep(0.051)
win32api.PostMessage(ahwnd, win32con.WM_CHAR, 13, 0)
time.sleep(0.051)
fval3 = win32api.SendMessage(ahwnd, win32con.WM_KEYUP, win32con.VK_RETURN+1, 0x1)

and seems to work properly. Note: Using PostMessage() for the WM_CHAR message is on purpose; if I used SendMessage() instead; the window wouldn't update until some other event fired to the teraterm window. IE a mouse move or something else.
Meilleure réponse Répondre à #89537