-
Notifications
You must be signed in to change notification settings - Fork 476
Expand file tree
/
Copy pathMouse.cs
More file actions
286 lines (246 loc) · 10.4 KB
/
Mouse.cs
File metadata and controls
286 lines (246 loc) · 10.4 KB
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using TestStack.White.Configuration;
using TestStack.White.Drawing;
using TestStack.White.UIA;
using TestStack.White.UIItems;
using TestStack.White.UIItems.Actions;
using TestStack.White.WindowsAPI;
using Action = TestStack.White.UIItems.Actions.Action;
namespace TestStack.White.InputDevices
{
public class Mouse : IMouse
{
[DllImport("user32", EntryPoint = "SendInput")]
static extern int SendInput(uint numberOfInputs, ref Input input, int structSize);
[DllImport("user32", EntryPoint = "SendInput")]
static extern int SendInput64(int numberOfInputs, ref Input64 input, int structSize);
[DllImport("user32.dll")]
static extern IntPtr GetMessageExtraInfo();
[DllImport("user32.dll")]
static extern bool GetCursorPos(ref System.Drawing.Point cursorInfo);
[DllImport("user32.dll")]
static extern bool SetCursorPos(int x, int y);
[DllImport("user32.dll")]
static extern bool GetCursorInfo(ref CursorInfo cursorInfo);
[DllImport("user32.dll")]
static extern short GetDoubleClickTime();
[DllImport("user32.dll")]
static extern int GetSystemMetrics(SystemMetric smIndex);
public static Mouse Instance = new Mouse();
DateTime lastClickTime = DateTime.Now;
readonly short doubleClickTime = GetDoubleClickTime();
Point lastClickLocation;
const int ExtraMillisecondsBecauseOfBugInWindows = 13;
Mouse() { }
public virtual Point Location
{
get
{
var point = new System.Drawing.Point();
GetCursorPos(ref point);
return point.ConvertToWindowsPoint();
}
set
{
if (value.IsInvalid())
{
throw new WhiteException(string.Format("Trying to set location outside the screen. {0}", value));
}
SetCursorPos((int)value.X, (int)value.Y);
}
}
public virtual MouseCursor Cursor
{
get
{
CursorInfo cursorInfo = CursorInfo.New();
GetCursorInfo(ref cursorInfo);
int i = cursorInfo.handle.ToInt32();
return new MouseCursor(i);
}
}
private static int RightMouseButtonDown
{
get { return GetSystemMetrics(SystemMetric.SM_SWAPBUTTON) == 0 ? WindowsConstants.MOUSEEVENTF_RIGHTDOWN : WindowsConstants.MOUSEEVENTF_LEFTDOWN; }
}
private static int RightMouseButtonUp
{
get { return GetSystemMetrics(SystemMetric.SM_SWAPBUTTON) == 0 ? WindowsConstants.MOUSEEVENTF_RIGHTUP : WindowsConstants.MOUSEEVENTF_LEFTUP; }
}
private static int LeftMouseButtonDown
{
get { return GetSystemMetrics(SystemMetric.SM_SWAPBUTTON) == 0 ? WindowsConstants.MOUSEEVENTF_LEFTDOWN : WindowsConstants.MOUSEEVENTF_RIGHTDOWN; }
}
private static int LeftMouseButtonUp
{
get { return GetSystemMetrics(SystemMetric.SM_SWAPBUTTON) == 0 ? WindowsConstants.MOUSEEVENTF_LEFTUP : WindowsConstants.MOUSEEVENTF_RIGHTUP; }
}
public virtual void RightClick()
{
SendInput(InputFactory.Mouse(MouseInput(RightMouseButtonDown)));
SendInput(InputFactory.Mouse(MouseInput(RightMouseButtonUp)));
}
public virtual void Click()
{
Point clickLocation = Location;
if (lastClickLocation.Equals(clickLocation))
{
int timeout = doubleClickTime - DateTime.Now.Subtract(lastClickTime).Milliseconds;
if (timeout > 0) Thread.Sleep(timeout + ExtraMillisecondsBecauseOfBugInWindows);
}
MouseLeftButtonUpAndDown();
lastClickTime = DateTime.Now;
lastClickLocation = Location;
}
public static void LeftUp()
{
SendInput(InputFactory.Mouse(MouseInput(LeftMouseButtonUp)));
}
public static void LeftDown()
{
SendInput(InputFactory.Mouse(MouseInput(LeftMouseButtonDown)));
}
public virtual void DoubleClick(Point point)
{
DoubleClick(point, new NullActionListener());
}
public virtual void DoubleClick(Point point, ActionListener actionListener)
{
Location = point;
MouseLeftButtonUpAndDown();
Thread.Sleep(CoreAppXmlConfiguration.Instance.DoubleClickInterval);
MouseLeftButtonUpAndDown();
ActionPerformed(actionListener);
}
public virtual void Wheel(int delta)
{
SendInput(InputFactory.Mouse(new MouseInput(120 * delta, WindowsConstants.MOUSEEVENTF_WHEEL, GetMessageExtraInfo())));
}
private static void SendInput(Input input)
{
// Added check for 32/64 bit
if (IntPtr.Size == 4)
SendInput(1, ref input, Marshal.SizeOf(typeof(Input)));
else
{
var input64 = new Input64(input);
SendInput64(1, ref input64, Marshal.SizeOf(typeof(Input)));
}
}
private static MouseInput MouseInput(int command)
{
return new MouseInput(command, GetMessageExtraInfo());
}
public virtual void RightClick(Point point, ActionListener actionListener)
{
Location = point;
RightClickHere(actionListener);
}
public virtual void RightClick(Point point)
{
RightClick(point, new NullActionListener());
}
internal virtual void RightClickHere(ActionListener actionListener)
{
RightClick();
actionListener.ActionPerformed(Action.WindowMessage);
}
public virtual void Click(Point point)
{
Click(point, new NullActionListener());
}
public virtual void Click(Point point, ActionListener actionListener)
{
Location = point;
Click();
ActionPerformed(actionListener);
}
public virtual void Wheel(Point point, int delta, ActionListener actionListener)
{
Location = point;
Wheel(delta);
ActionPerformed(actionListener);
}
private static void ActionPerformed(ActionListener actionListener)
{
actionListener.ActionPerformed(new Action(ActionType.WindowMessage));
}
/// <summary>
/// Drags the dragged item and drops it on the drop item. This can be used for any two UIItems
/// whether they are same application or different. To drop items on desktop use Desktop
/// class's Drop method. White starts and ends the drag from center of the UIItems.
/// Some drag and drop operation need to wait for application to process something while item is being dragged.
/// This can be set but configuring DragStepCount property. This is by default set to 1.
/// </summary>
/// <param name="draggedItem"></param>
/// <param name="dropItem"></param>
public virtual void DragAndDrop(IUIItem draggedItem, IUIItem dropItem)
{
Point startPosition = draggedItem.Bounds.Center();
Point endPosition = dropItem.Bounds.Center();
DragAndDrop(draggedItem, startPosition, dropItem, endPosition);
}
/// <summary>
/// Drags the dragged item and drops it on the drop item. This can be used for any two UIItems
/// whether they are same application or different. To drop items on desktop use Desktop
/// class's Drop method. White starts and ends the drag from center of the UIItems.
/// Some drag and drop operation need to wait for application to process something while item is being dragged.
/// This can be set but configuring DragStepCount property. This is by default set to 1.
/// </summary>
/// <param name="draggedItem"></param>
/// <param name="startPosition">Start point of the drag. You can do uiItem.Bounds to get bounds of the UIItem and use RectX extension class in White.Core.UIA namespace to find different points</param>
/// <param name="dropItem"></param>
/// <param name="endPosition">End point of the drag. You can do uiItem.Bounds to get bounds of the UIItem and use RectX extension class in White.Core.UIA namespace to find different points</param>
public virtual void DragAndDrop(IUIItem draggedItem, Point startPosition, IUIItem dropItem, Point endPosition)
{
Location = startPosition;
HoldForDrag();
var dragStepFraction = (float)(1.0 / CoreAppXmlConfiguration.Instance.DragStepCount);
for (int i = 1; i <= CoreAppXmlConfiguration.Instance.DragStepCount; i++)
{
double newX = startPosition.X + (endPosition.X - startPosition.X) * (dragStepFraction * i);
double newY = startPosition.Y + (endPosition.Y - startPosition.Y) * (dragStepFraction * i);
var newPoint = new Point((int)newX, (int)newY);
Location = newPoint;
}
LeftUp();
dropItem.ActionPerformed(Action.WindowMessage);
}
private void HoldForDrag()
{
LeftDown();
}
public static void MouseLeftButtonUpAndDown()
{
LeftDown();
LeftUp();
}
public virtual void MoveOut()
{
Location = new Point(0, 0);
}
public virtual void DragHorizontally(UIItem uiItem, int distance)
{
Location = uiItem.Bounds.Center();
double currentXLocation = Location.X;
double currentYLocation = Location.Y;
HoldForDrag();
ActionPerformed(uiItem);
Location = new Point(currentXLocation + distance, currentYLocation);
LeftUp();
}
public virtual void DragVertically(UIItem uiItem, int distance)
{
Location = uiItem.Bounds.Center();
double currentXLocation = Location.X;
double currentYLocation = Location.Y;
HoldForDrag();
ActionPerformed(uiItem);
Location = new Point(currentXLocation, currentYLocation + distance);
LeftUp();
}
}
}