gpt4 book ai didi

python - Windows 上 Python 3.1 的 SendKeys

转载 作者:太空宇宙 更新时间:2023-11-03 12:16:45 25 4
gpt4 key购买 nike

最新的 Python Sendkeys 模块适用于 Python 2.6。我不能自己升级它,因为它需要重新编译 C 模块。

有谁知道将 key 发送到窗口的相当简单的替代方法?

我可以使用 win32ui.FindWindow() 找到正确的窗口,然后使用 PyCWnd.SetActiveWindow() 将其激活,因此所需要的只是一种将击键发送到事件窗口的简单方法。

目的是执行一个菜单项。

该应用程序是用 Delphi 编写的,没有我所知道的任何进程间接口(interface)。

最佳答案

这是一个调用 user32.SendInput() 的工作模块。

不完美,但可用。

编辑:

昨天我做了一个带有类的版本,并在一个工作的 tkinter 应用程序中使用它。当我有时间清理它时会把它放在这里。

在下面的文档字符串中添加了这个:

[ 如果我在个人资料中的文件夹中工作,那没问题。
这些问题发生在处理另一个分区时。
文件权限还可以,所以不知道是什么阻止了 SendInput。 ]

SciTE 仍然需要完全准确的窗口标题。

#!/usr/bin/python
# -*- coding: utf-8 -*-

''' send_input for python 3, from jh45dev@gmail.com

code from Daniel F is adapted here. The original is at:
http://mail.python.org/pipermail/python-win32/2005-April/003131.html


SendInput sends to the window that has the keyboard focus.
That window must not be minimized.


There seem to be some strange limitations with user32.SendInput()
Here is what happened in my testing (on Vista sp2).

[edit: It is OK if I work from a folder within my profile.
These problems happened when working on another partition.
File permissions were OK, so do not know what blocked SendInput.]

1
I opened Notepad from the Start menu,
then in Notepad opened test.txt,
and all worked fine.

2
I opened Notepad by opening test.txt in Explorer.
find_window() found Notepad, but user32.SendInput() had no effect.
If Notepad was minimized, it did not get restored or focussed.

The same happened with SciTE and Notepad2.


Another strangeness:
For SciTE I had to put in the whole window title, eg "test.txt - SciTE",
but for Notepad and Notepad2, only the app name, eg "Notepad".


'''

import ctypes as ct
from win32con import SW_MINIMIZE, SW_RESTORE
from win32ui import FindWindow, error as ui_err
from time import sleep


class cls_KeyBdInput(ct.Structure):
_fields_ = [
("wVk", ct.c_ushort),
("wScan", ct.c_ushort),
("dwFlags", ct.c_ulong),
("time", ct.c_ulong),
("dwExtraInfo", ct.POINTER(ct.c_ulong) )
]

class cls_HardwareInput(ct.Structure):
_fields_ = [
("uMsg", ct.c_ulong),
("wParamL", ct.c_short),
("wParamH", ct.c_ushort)
]

class cls_MouseInput(ct.Structure):
_fields_ = [
("dx", ct.c_long),
("dy", ct.c_long),
("mouseData", ct.c_ulong),
("dwFlags", ct.c_ulong),
("time", ct.c_ulong),
("dwExtraInfo", ct.POINTER(ct.c_ulong) )
]

class cls_Input_I(ct.Union):
_fields_ = [
("ki", cls_KeyBdInput),
("mi", cls_MouseInput),
("hi", cls_HardwareInput)
]

class cls_Input(ct.Structure):
_fields_ = [
("type", ct.c_ulong),
("ii", cls_Input_I)
]


def find_window( s_app_name ):

try:
window1 = FindWindow( None, s_app_name,)
return window1
except ui_err:
pass
except:
raise

try:
window1 = FindWindow( s_app_name, None, )
return window1
except ui_err:
return None
except:
raise


def make_input_objects( l_keys ):

p_ExtraInfo_0 = ct.pointer(ct.c_ulong(0))

l_inputs = [ ]
for n_key, n_updown in l_keys:
ki = cls_KeyBdInput( n_key, 0, n_updown, 0, p_ExtraInfo_0 )
ii = cls_Input_I()
ii.ki = ki
l_inputs.append( ii )

n_inputs = len(l_inputs)

l_inputs_2=[]
for ndx in range( 0, n_inputs ):
s2 = "(1, l_inputs[%s])" % ndx
l_inputs_2.append(s2)
s_inputs = ', '.join(l_inputs_2)


cls_input_array = cls_Input * n_inputs
o_input_array = eval( "cls_input_array( %s )" % s_inputs )

p_input_array = ct.pointer( o_input_array )
n_size_0 = ct.sizeof( o_input_array[0] )

# these are the args for user32.SendInput()
return ( n_inputs, p_input_array, n_size_0 )

'''It is interesting that o_input_array has gone out of scope
by the time p_input_array is used, but it works.'''


def send_input( window1, t_inputs, b_minimize=True ):

tpl1 = window1.GetWindowPlacement()
was_min = False
if tpl1[1] == 2:
was_min = True
window1.ShowWindow(SW_RESTORE)
sleep(0.2)

window1.SetForegroundWindow()
sleep(0.2)
window1.SetFocus()
sleep(0.2)
rv = ct.windll.user32.SendInput( *t_inputs )

if was_min and b_minimize:
sleep(0.3) # if the last input was Save, it may need time to take effect
window1.ShowWindow(SW_MINIMIZE)

return rv



# define some commonly-used key sequences
t_ctrl_s = ( # save in many apps
( 0x11, 0 ),
( 0x53, 0 ),
( 0x11, 2 ),
)
t_ctrl_r = ( # reload in some apps
( 0x11, 0 ),
( 0x52, 0 ),
( 0x11, 2 ),
)


def test():

# file > open; a non-invasive way to test
t_ctrl_o = ( ( 0x11, 0 ), ( 0x4F, 0 ), ( 0x11, 2 ), )

# writes "Hello\n"
# 0x10 is shift. note that to repeat a key, as with 4C here, you have to release it after the first press
t_hello = ( ( 0x10, 0 ), ( 0x48, 0 ), ( 0x10, 2 ), ( 0x45, 0 ), ( 0x4C, 0 ), ( 0x4C, 2 ), ( 0x4C, 0 ), ( 0x4F, 0 ), ( 0x0D, 0 ), )


l_keys = [ ]
## l_keys.extend( t_ctrl_o )
l_keys.extend( t_hello )
l_keys.extend( t_ctrl_s )

## s_app_name = "SciTE"
## s_app_name = "(Untitled) - SciTE"
s_app_name = "test.txt - SciTE"
## s_app_name = "Notepad2"
## s_app_name = "Notepad"

window1 = find_window( s_app_name )
if window1 == None:
print( "%r has no window." % s_app_name )
input( 'press enter to close' )
exit()

t_inputs = make_input_objects( l_keys )

n = send_input( window1, t_inputs )

## print( "SendInput returned: %r" % n )
## print( "GetLastError: %r" % ct.windll.kernel32.GetLastError() )
## input( 'press enter to close' )



if __name__ == '__main__':
test()

关于python - Windows 上 Python 3.1 的 SendKeys,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1823762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com