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
|
#!/usr/bin/python2.4
# Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""SiteCompare module for simulating mouse input.
This module contains functions that can be used to simulate a user
navigating using a pointing device. This includes mouse movement,
clicking with any button, and dragging.
"""
import time # for sleep
import win32api # for mouse_event
import win32con # Windows constants
import win32gui # for window functions
def ScreenToMouse(pt):
"""Convert a value in screen coordinates to mouse coordinates.
Mouse coordinates are specified as a percentage of screen dimensions,
normalized to 16 bits. 0 represents the far left/top of the screen,
65535 represents the far right/bottom. This function assumes that
the size of the screen is fixed at module load time and does not change
Args:
pt: the point of the coords to convert
Returns:
the converted point
"""
# Initialize the screen dimensions on first execution. Note that this
# function assumes that the screen dimensions do not change during run.
if not ScreenToMouse._SCREEN_DIMENSIONS:
desktop = win32gui.GetClientRect(win32gui.GetDesktopWindow())
ScreenToMouse._SCREEN_DIMENSIONS = (desktop[2], desktop[3])
return ((65535 * pt[0]) / ScreenToMouse._SCREEN_DIMENSIONS[0],
(65535 * pt[1]) / ScreenToMouse._SCREEN_DIMENSIONS[1])
ScreenToMouse._SCREEN_DIMENSIONS = None
def PressButton(down, button='left'):
"""Simulate a mouse button press or release at the current mouse location.
Args:
down: whether the button is pressed or released
button: which button is pressed
Returns:
None
"""
# Put the mouse_event flags in a convenient dictionary by button
flags = {
'left': (win32con.MOUSEEVENTF_LEFTUP, win32con.MOUSEEVENTF_LEFTDOWN),
'middle': (win32con.MOUSEEVENTF_MIDDLEUP, win32con.MOUSEEVENTF_MIDDLEDOWN),
'right': (win32con.MOUSEEVENTF_RIGHTUP, win32con.MOUSEEVENTF_RIGHTDOWN)
}
# hit the button
win32api.mouse_event(flags[button][down], 0, 0)
def ClickButton(button='left', click_time=0):
"""Press and release a mouse button at the current mouse location.
Args:
button: which button to click
click_time: duration between press and release
Returns:
None
"""
PressButton(True, button)
time.sleep(click_time)
PressButton(False, button)
def DoubleClickButton(button='left', click_time=0, time_between_clicks=0):
"""Double-click a mouse button at the current mouse location.
Args:
button: which button to click
click_time: duration between press and release
time_between_clicks: time to pause between clicks
Returns:
None
"""
ClickButton(button, click_time)
time.sleep(time_between_clicks)
ClickButton(button, click_time)
def MoveToLocation(pos, duration=0, tick=0.01):
"""Move the mouse cursor to a specified location, taking the specified time.
Args:
pos: position (in screen coordinates) to move to
duration: amount of time the move should take
tick: amount of time between successive moves of the mouse
Returns:
None
"""
# calculate the number of moves to reach the destination
num_steps = (duration/tick)+1
# get the current and final mouse position in mouse coords
current_location = ScreenToMouse(win32gui.GetCursorPos())
end_location = ScreenToMouse(pos)
# Calculate the step size
step_size = ((end_location[0]-current_location[0])/num_steps,
(end_location[1]-current_location[1])/num_steps)
step = 0
while step < num_steps:
# Move the mouse one step
current_location = (current_location[0]+step_size[0],
current_location[1]+step_size[1])
# Coerce the coords to int to avoid a warning from pywin32
win32api.mouse_event(
win32con.MOUSEEVENTF_MOVE|win32con.MOUSEEVENTF_ABSOLUTE,
int(current_location[0]), int(current_location[1]))
step += 1
time.sleep(tick)
def ClickAtLocation(pos, button='left', click_time=0):
"""Simulate a mouse click in a particular location, in screen coordinates.
Args:
pos: position in screen coordinates (x,y)
button: which button to click
click_time: duration of the click
Returns:
None
"""
MoveToLocation(pos)
ClickButton(button, click_time)
def ClickInWindow(hwnd, offset=None, button='left', click_time=0):
"""Simulate a user mouse click in the center of a window.
Args:
hwnd: handle of the window to click in
offset: where to click, defaults to dead center
button: which button to click
click_time: duration of the click
Returns:
Nothing
"""
rect = win32gui.GetClientRect(hwnd)
if offset is None: offset = (rect[2]/2, rect[3]/2)
# get the screen coordinates of the window's center
pos = win32gui.ClientToScreen(hwnd, offset)
ClickAtLocation(pos, button, click_time)
def DoubleClickInWindow(
hwnd, offset=None, button='left', click_time=0, time_between_clicks=0.1):
"""Simulate a user mouse double click in the center of a window.
Args:
hwnd: handle of the window to click in
offset: where to click, defaults to dead center
button: which button to click
click_time: duration of the clicks
time_between_clicks: length of time to pause between clicks
Returns:
Nothing
"""
ClickInWindow(hwnd, offset, button, click_time)
time.sleep(time_between_clicks)
ClickInWindow(hwnd, offset, button, click_time)
if __name__ == "__main__":
# We're being invoked rather than imported. Let's do some tests
screen_size = win32gui.GetClientRect(win32gui.GetDesktopWindow())
screen_size = (screen_size[2], screen_size[3])
# move the mouse (instantly) to the upper right corner
MoveToLocation((screen_size[0], 0))
# move the mouse (over five seconds) to the lower left corner
MoveToLocation((0, screen_size[1]), 5)
# click the left mouse button. This will open up the Start menu
# if the taskbar is at the bottom
ClickButton()
# wait a bit, then click the right button to open the context menu
time.sleep(3)
ClickButton('right')
# move the mouse away and then click the left button to dismiss the
# context menu
MoveToLocation((screen_size[0]/2, screen_size[1]/2), 3)
MoveToLocation((0, 0), 3)
ClickButton()
|