我试图跟踪用户的按键次数,但我已经意识到与Steam无关,无论是客户端本身还是通过它发起的游戏,它停止工作。如果使用GetKeyState
而不是GetAsyncKeyState
,它可以拾取键盘边缘的位,例如ctrl,shift,tab,backspace,enter,但没有别的。我还在少数其他程序中发现了相同的行为,例如任务管理器和Discord。
我使用ctypes
和pywin32
同时尝试GetKeyState
和GetAsyncKeyState
。
在IInspectable建议查看低级键盘挂钩后,我尝试了两个不同的版本,发现他们遇到了完全相同的问题。
这里有一些代码用于演示所有功能的问题:
import ctypes
try:
import win32api
except ImportError:
win32api = None
def get_key_press1(key):
return win32api.GetAsyncKeyState(key)
def get_key_press2(key):
return win32api.GetKeyState(key) < 0
def get_key_press3(key):
return ctypes.windll.user32.GetKeyState(key) > 1
def get_key_press4(key):
return ctypes.windll.user32.GetAsyncKeyState(key)
KEYS = {
'BACK': 8,
'TAB': 9,
'CLEAR': 12,
'RETURN': 13,
'PAUSE': 19,
'CAPSLOCK': 20,
'ESC': 27,
'SPACE': 32,
'PGUP': 33,
'PGDOWN': 34,
'END': 35,
'HOME': 36,
'LEFT': 37,
'UP': 38,
'RIGHT': 39,
'DOWN': 40,
'INSERT': 45,
'DELETE': 46,
'LWIN': 91,
'RWIN': 92,
'MENU': 93,
'NUM0': 96,
'NUM1': 97,
'NUM2': 98,
'NUM3': 99,
'NUM4': 100,
'NUM5': 101,
'NUM6': 102,
'NUM7': 103,
'NUM8': 104,
'NUM9': 105,
'MULTIPLY': 106,
'ADD': 107,
'SUBTRACT': 109,
'DECIMAL': 110,
'DIVIDE': 111,
'F1': 112,
'F2': 113,
'F3': 114,
'F4': 115,
'F5': 116,
'F6': 117,
'F7': 118,
'F8': 119,
'F9': 120,
'F10': 121,
'F11': 122,
'F12': 123,
'F13': 124,
'F14': 125,
'F15': 126,
'F16': 127,
'F17': 128,
'F18': 129,
'F19': 130,
'F20': 131,
'F21': 132,
'F22': 133,
'F23': 134,
'F24': 135,
'NUMLOCK': 144,
'SCROLLLOCK': 145,
'LSHIFT': 160,
'RSHIFT': 161,
'LCTRL': 162,
'RCTRL': 163,
'LALT': 164,
'RALT': 165,
'COLON': 186,
'EQUALS': 187,
'COMMA': 188,
'UNDERSCORE': 189,
'PERIOD': 190,
'FORWARDSLASH': 191,
'AT': 192,
'LBRACKET': 219,
'BACKSLASH': 220,
'RBRACKET': 221,
'HASH': 222,
'TILDE': 223
}
for c in list('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'):
KEYS[c] = ord(c)
while True:
all_pressed = []
for k in KEYS:
if win32api:
if get_key_press1(KEYS[k]):
all_pressed.append((k, 1))
if get_key_press2(KEYS[k]):
all_pressed.append((k, 2))
if get_key_press3(KEYS[k]):
all_pressed.append((k, 3))
if get_key_press4(KEYS[k]):
all_pressed.append((k, 4))
if all_pressed:
print all_pressed
从计算机的任何位置,如果您要按&#34; c&#34;例如,你会得到[('C', 1), ('C', 2), ('C', 3), ('C', 4)]
,这表明所有4个函数都在拾取它。当关注与Steam有关的任何内容时都按下它,没有任何显示。但是,如果您要点击其中一个工作按钮,则会获得[('LCTRL', 2), ('LCTRL', 3)]
,这意味着只有GetKeyState
个功能正在启动它。
在过去的几个月里,我已经在大约30场比赛中测试了这个剧本,而且没有失败,Steam的是那些没有工作键盘跟踪的人。我甚至刚刚下载了独立版的Factorio来与Steam版本进行比较,它运行得很完美。
是否有一些明显缺失的东西,或者是否有更好的方法来获得按键?它有点烦人,因为它应该是脚本中最简单的部分,但它是看似无法修复的部分。
为了澄清一下,我理想的是要坚持使用函数返回True
/ False
,具体取决于当时是否按下了键。
答案 0 :(得分:0)
经过整整3个月的多次尝试找到修复程序后,我发现了问题 - 它并没有以管理员身份运行,而是Steam。
如果其他人偶然发现了这一点,那么这就是我最终得到的代码。您在脚本开头运行elevate()
,但如果您正在使用freeze_support
,请确保它def elevate(console=True):
arg = 'forced_elevate'
if sys.argv[-1] != arg and not win32com.shell.shell.IsUserAnAdmin():
script = os.path.abspath(sys.argv[0])
params = ' '.join([script] + sys.argv[1:] + [arg])
try:
win32com.shell.shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters=params, nShow=5 if console else 0)
except pywintypes.error:
pass
else:
sys.exit(0)
。
pywin32:
def elevate(console=True):
arg = 'forced_elevate'
if sys.argv[-1] != arg and not ctypes.windll.shell32.IsUserAnAdmin():
script = os.path.abspath(sys.argv[0])
params = u' '.join([script] + sys.argv[1:] + [arg])
ret = ctypes.windll.shell32.ShellExecuteW(None, u'runas', unicode(sys.executable), params, None, 5 if console else 0)
if int(ret) > 32:
sys.exit(0)
ctypes的:
<label for="{{all.type}}" ng-if="x.type === 'ALL'" >{{x.type}}</label>