-
Notifications
You must be signed in to change notification settings - Fork 2
/
README.rml
222 lines (174 loc) · 6.98 KB
/
README.rml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
[title]winput[/]
[subtitle]Capture and send keyboard and mouse input on Windows[/]
[b]winput[/] is a small [b]extension[/] that gives you the ability to [b]capture[/] and [b]send[/] any [b]keyboard and mouse input[/].
It does this by providing a [b]simple interface[/] to [b]user32.dll[/]
[s1]Tiny documentation[/]
[s2]About winput[/]
[b]winput must not be used to record the user's input without their consent![/]
[b]winput[/] is supposed to [b]replace[/] the outdated extension [url=https://pypi.org/project/pyHook/]PyHook[/].
[s2]Using winput[/]
To install winput you can use the [url=https://packaging.python.org/tutorials/installing-packages/]PyPI[/url]:
[code]pip install winput[/]
To use winput in a script, you have to import the package [code]winput[/] using
[code]import winput[/]
or a wildcard import:
[code]from winput import *[/]
[s3]Capturing mouse input[/]
There are two ways you can get input from the mouse.
1. You can get the current position of the mouse cursor using
[code]get_mouse_pos() -> (x, y)[/code]
2. You can hook onto the Windows message system to receive an Event every time
the state of the mouse changes:
[code]hook_mouse( callback_function )[/]
The function will be supplied with a [b]MouseEvent[/] as it's only argument.
[code]class MouseEvent:
position # \[length-2-tuple\] the screen coordinates at which the event occured
action # \[int\] which type of event occured - can be any of the mouse-wParams (see below)
time # \[int\] time in ms since system startup
additional_data # \[int\] information for specific mouse events (which X-Button, amount of mouse-wheel-movement)
type # \[string\] = "MouseEvent"[/]
You [b]have to run a message loop[/] to use a hook! (see [b]\[Running a message loop\][/] below)
Remember to unhook when you're done capturing by using:
[code]unhook_mouse()[/]
The following mouse-wParams exist:
[code]
WM_MOUSEMOVE = 0x0200 # the mouse has been moved
WM_LBUTTONDOWN = 0x0201 # left mouse button pressed
WM_LBTTONUP = 0x0202 # left mouse button released
WM_RBUTTONDOWN = 0x0204 # right mouse button pressed
WM_RBUTTONUP = 0x0205 # right mouse button released
WM_MBUTTONDOWN = 0x0207 # middle mouse button pressed
WM_MBUTTONUP = 0x0208 # middle mouse button released
WM_MOUSEWHEEL = 0x020A # mouse wheel moved
WM_MOUSEHWHEEL = 0x020E # mouse wheel moved (horizontal)
WM_XBUTTONDOWN = 0x020B # extra button pressed
WM_XBUTTONUP = 0x020C # extra button released
[/]
[s3]Capturing keyboard input[/]
If you want to monitor keyboard input you also have to hook onto the Windows message system.
[code]hook_keyboard( callback_function )[/]
The function will be supplied with a [b]KeyboardEvent[/] as it's only argument.
[code]class KeyboardEvent:
action # \[int\] which type of event occured - can be any of the keyboard-wParams
vkCode # \[int\] virtual key code -- which key has been pressed
time # \[int\] time in ms since system startup
type # \[string\] = "KeyboardEvent"[/]
You [b]have to run a message loop[/] to use a hook! (see [i]Running a message loop[/] below)
Again, remember to unhook when you're done capturing by using:
[code]unhook_keyboard()[/]
The following keyboard-wParams exist:
[code]
WM_KEYDOWN = 0x0100 # key pressed
WM_KEYUP = 0x0101 # key released
WM_SYSKEYDOWN = 0x0104 # system-key pressed
WM_SYSKEYUP = 0x0105 # system-key released
[/]
[s3]Running a message loop[/]
If you're using a hook, you have to keep updating the Windows messages.
You can either do this by using
[code]wait_messages()[/]
to enter an infinite message loop, which you can stop by calling
[code]stop()[/]
Or you can have your own loop that repeatedly (at least 100x per second) calls
[code]get_message()[/]
[s3]Virtual Key Codes (VK codes)[/]
Virtual key codes or vk_codes are numerical representations of given keys.
To get a list of all virtual key codes, take a look over [url=https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes]here[/].
All VK codes are members of the main [code]winput[/code] module and the submodule [code]winput.vk_codes[/code].
If you want to import all the VK codes without performing a package-wide wildcard import, you can use
[code]from winput.vk_codes import *[/]
You can also convert the virtual key codes to a literal representation using a predefined dict.
[code]vk_code_dict.get(vk_code, "VK_UNKNOWN") -> string[/]
[s3]Sending mouse input[/]
To set the position of the mouse cursor, you can use
[code]set_mouse_pos(x, y)[/]
To make sure this also works with high DPI values, please use the DPI awareness functions below.
To move the mouse cursor by a given amount, you can use
[code]move_mouse(dx, dy)[/]
A mouse button can be pressed using
[code]press_mouse_button(mouse_button)[/]
and released using
[code]release_mouse_button(mouse_button)[/]
or pressed and released using
[code]click_mouse_button(mouse_button)[/]
The following mouse buttons exist:
[code]
LEFT_MOUSE_BUTTON = LMB = 1
RIGHT_MOUSE_BUTTON = RMB = 2
MIDDLE_MOUSE_BUTTON = MMB = 4
EXTRA_MOUSE_BUTTON1 = XMB1 = 8
EXTRA_MOUSE_BUTTON2 = XMB2 = 16[/]
The mousewheel can be moved using
[code]move_mousewheel(amount[, horizontal = False])[/]
[s3]Sending keyboard input[/]
To press a key, you can use
[code]press_key(vk_code)[/]
to release it, you can use
[code]release_key(vk_code)[/]
and to press and release it, you can use
[code]click_key(vk_code)[/]
[s3]DPI awareness[/]
To make the process running winput DPI aware, use the following function:
[code]set_DPI_aware(per_monitor=True)[/]
To get the DPI scaling factor for a given window handle (HWND), use
[code]get_window_scaling_factor(hwnd)[/]
[s2]Example[/]
[s3]Capturing the mouse and keyboard[/]
[code]
import winput
def mouse_callback( event ):
if event.action == winput.WM_LBUTTONDOWN:
print("Left mouse button press at {}".format( event.position ))
def keyboard_callback( event ):
if event.vkCode == winput.VK_ESCAPE: # quit on pressing escape
winput.stop()
print("Press escape to quit")
# hook input
winput.hook_mouse( mouse_callback )
winput.hook_keyboard( keyboard_callback )
# enter message loop
winput.wait_messages()
# remove input hook
winput.unhook_mouse()
winput.unhook_keyboard()
[/]
[s3]Sending input[/]
[code]
import winput
from winput.vk_codes import *
import time
def slow_click(vk_code): # delay each keypress by 1/10 of a second
time.sleep(0.1)
winput.click_key(vk_code)
# open the RUN menu (WIN + R)
winput.press_key(VK_LWIN)
winput.click_key(VK_R)
winput.release_key(VK_LWIN)
time.sleep(0.5)
# enter "notepad.exe"
slow_click(VK_N)
slow_click(VK_O)
slow_click(VK_T)
slow_click(VK_E)
slow_click(VK_P)
slow_click(VK_A)
slow_click(VK_D)
slow_click(VK_OEM_PERIOD)
slow_click(VK_E)
slow_click(VK_X)
slow_click(VK_E)
slow_click(VK_RETURN)
time.sleep(1)
# enter "hello world"
slow_click(VK_H)
slow_click(VK_E)
slow_click(VK_L)
slow_click(VK_L)
slow_click(VK_O)
slow_click(VK_SPACE)
slow_click(VK_W)
slow_click(VK_O)
slow_click(VK_R)
slow_click(VK_L)
slow_click(VK_D)
[/]