special_input_device 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  #include "special_input_device.h"
2
+ #include "_mouse.h"
2
3
  #include "_screen.h"
3
4
  #include "interception.h"
4
5
  #include "point.h"
@@ -9,23 +10,26 @@ inline BOOL ruby___mouse_is_locked() {
9
10
  return cLocked;
10
11
  }
11
12
 
13
+ #define RUBY___LOCK(flag) \
14
+ cLocked = flag;\
15
+ switch (ruby___special_input_device_get_mode_identifier()) {\
16
+ case MODE_INTERCEPTION:\
17
+ break;\
18
+ case MODE_WIN_API:\
19
+ rb_raise(rb_eRuntimeError, "WinAPI mode does not support lock mouse function.");\
20
+ default: {\
21
+ PCHAR cModeName = ruby___special_input_device_get_mode_name();\
22
+ rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);\
23
+ }\
24
+ }\
25
+ return self;
26
+
12
27
  /*
13
28
  * Lock the mouse.
14
29
  * @return [Module] self
15
30
  */
16
31
  static VALUE ruby__lock(VALUE self) {
17
- cLocked = TRUE;
18
- switch (ruby___special_input_device_get_mode_identifier()) {
19
- case MODE_INTERCEPTION:
20
- break;
21
- case MODE_WIN_API:
22
- rb_raise(rb_eRuntimeError, "WinAPI mode does not support lock mouse function.");
23
- default: {
24
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
25
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
26
- }
27
- }
28
- return self;
32
+ RUBY___LOCK(TRUE)
29
33
  }
30
34
 
31
35
  /*
@@ -33,18 +37,7 @@ static VALUE ruby__lock(VALUE self) {
33
37
  * @return [Module] self
34
38
  */
35
39
  static VALUE ruby__unlock(VALUE self) {
36
- cLocked = FALSE;
37
- switch (ruby___special_input_device_get_mode_identifier()) {
38
- case MODE_INTERCEPTION:
39
- break;
40
- case MODE_WIN_API:
41
- rb_raise(rb_eRuntimeError, "WinAPI mode does not support lock mouse function.");
42
- default: {
43
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
44
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
45
- }
46
- }
47
- return self;
40
+ RUBY___LOCK(FALSE)
48
41
  }
49
42
 
50
43
  //region cursor
@@ -60,6 +53,50 @@ static VALUE ruby__cursor_position(VALUE self) {
60
53
  return ruby___point_new_from_point(&cPoint);
61
54
  }
62
55
 
56
+ #define RUBY___MOVE_TO(xValue, yValue) \
57
+ LONG cX = xValue;\
58
+ LONG cY = yValue;\
59
+ POINT cPoint = {cX, cY};\
60
+ ULONG cVirtualX = (((ULONG) (cX - getVirtualScreenX())) * 0xFFFF + 0x7FFF) / ((ULONG) getVirtualScreenWidth());\
61
+ ULONG cVirtualY = (((ULONG) (cY - getVirtualScreenY())) * 0xFFFF + 0x7FFF) / ((ULONG) getVirtualScreenHeight());\
62
+ if (!MonitorFromPoint(cPoint, MONITOR_DEFAULTTONULL))\
63
+ rb_raise(rb_eRuntimeError, "Point at (%d, %d) is out of screen.", cX, cY);\
64
+ switch (ruby___special_input_device_get_mode_identifier()) {\
65
+ case MODE_INTERCEPTION: {\
66
+ InterceptionContext cContext = ruby___interception_get_context();\
67
+ InterceptionDevice cDevice = ruby___interception_find_mouse();\
68
+ InterceptionMouseStroke cStroke;\
69
+ cStroke.flags = INTERCEPTION_MOUSE_MOVE_ABSOLUTE | INTERCEPTION_MOUSE_VIRTUAL_DESKTOP;\
70
+ cStroke.information = 0;\
71
+ cStroke.rolling = 0;\
72
+ cStroke.state = 0;\
73
+ cStroke.x = (INT) cVirtualX;\
74
+ cStroke.y = (INT) cVirtualY;\
75
+ interceptionSend(cContext, cDevice, (InterceptionStroke *) &cStroke, 1);\
76
+ break;\
77
+ }\
78
+ case MODE_WIN_API: {\
79
+ INPUT input;\
80
+ input.type = INPUT_MOUSE;\
81
+ input.mi.dwExtraInfo = 0;\
82
+ input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK;\
83
+ input.mi.dx = (LONG) cVirtualX;\
84
+ input.mi.dy = (LONG) cVirtualY;\
85
+ input.mi.mouseData = 0;\
86
+ input.mi.time = 0;\
87
+ if (!SendInput(1, &input, sizeof(INPUT)))\
88
+ RAISE_WIN32_ERROR();\
89
+ break;\
90
+ }\
91
+ default: {\
92
+ PCHAR cModeName = ruby___special_input_device_get_mode_name();\
93
+ rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);\
94
+ }\
95
+ }\
96
+ rb_thread_schedule();\
97
+ return self;\
98
+
99
+
63
100
  /*
64
101
  * @overload move_relatively(x, y)
65
102
  * Move the cursor position relative to current position.
@@ -70,41 +107,7 @@ static VALUE ruby__cursor_position(VALUE self) {
70
107
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
71
108
  */
72
109
  static VALUE ruby__move_relatively(VALUE self, VALUE x, VALUE y) {
73
- LONG cX = NUM2LONG(x);
74
- LONG cY = NUM2LONG(y);
75
- switch (ruby___special_input_device_get_mode_identifier()) {
76
- case MODE_INTERCEPTION: {
77
- InterceptionContext cContext = ruby___interception_get_context();
78
- InterceptionDevice cDevice = ruby___interception_find_mouse();
79
- InterceptionMouseStroke cStroke;
80
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
81
- cStroke.information = 0;
82
- cStroke.rolling = 0;
83
- cStroke.state = 0;
84
- cStroke.x = cX;
85
- cStroke.y = cY;
86
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
87
- break;
88
- }
89
- case MODE_WIN_API: {
90
- INPUT input;
91
- input.type = INPUT_MOUSE;
92
- input.mi.dwExtraInfo = 0;
93
- input.mi.dwFlags = MOUSEEVENTF_MOVE;
94
- input.mi.dx = cX;
95
- input.mi.dy = cY;
96
- input.mi.mouseData = 0;
97
- input.mi.time = 0;
98
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
99
- RAISE_WIN32_ERROR();
100
- break;
101
- }
102
- default: {
103
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
104
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
105
- }
106
- }
107
- return self;
110
+ RUBY___MOVE_TO(getCursorPrimaryX() + NUM2LONG(x), getCursorPrimaryY() + NUM2LONG(y))
108
111
  }
109
112
 
110
113
  /*
@@ -119,41 +122,7 @@ static VALUE ruby__move_relatively(VALUE self, VALUE x, VALUE y) {
119
122
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
120
123
  */
121
124
  static VALUE ruby__move_to_primary(VALUE self, VALUE x, VALUE y) {
122
- LONG cX = NUM2LONG(x) * 0xFFFF / getPrimaryScreenWidth();
123
- LONG cY = NUM2LONG(y) * 0xFFFF / getPrimaryScreenHeight();
124
- switch (ruby___special_input_device_get_mode_identifier()) {
125
- case MODE_INTERCEPTION: {
126
- InterceptionContext cContext = ruby___interception_get_context();
127
- InterceptionDevice cDevice = ruby___interception_find_mouse();
128
- InterceptionMouseStroke cStroke;
129
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_ABSOLUTE;
130
- cStroke.information = 0;
131
- cStroke.rolling = 0;
132
- cStroke.state = 0;
133
- cStroke.x = cX;
134
- cStroke.y = cY;
135
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
136
- break;
137
- }
138
- case MODE_WIN_API: {
139
- INPUT input;
140
- input.type = INPUT_MOUSE;
141
- input.mi.dwExtraInfo = 0;
142
- input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
143
- input.mi.dx = cX;
144
- input.mi.dy = cY;
145
- input.mi.mouseData = 0;
146
- input.mi.time = 0;
147
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
148
- RAISE_WIN32_ERROR();
149
- break;
150
- }
151
- default: {
152
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
153
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
154
- }
155
- }
156
- return self;
125
+ RUBY___MOVE_TO(NUM2LONG(x), NUM2LONG(y));
157
126
  }
158
127
 
159
128
  /*
@@ -169,100 +138,118 @@ static VALUE ruby__move_to_primary(VALUE self, VALUE x, VALUE y) {
169
138
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
170
139
  */
171
140
  static VALUE ruby__move_to_virtual(VALUE self, VALUE x, VALUE y) {
172
- LONG cX = NUM2LONG(x) * 0xFFFF / getVirtualScreenWidth();
173
- LONG cY = NUM2LONG(y) * 0xFFFF / getVirtualScreenHeight();
174
- switch (ruby___special_input_device_get_mode_identifier()) {
175
- case MODE_INTERCEPTION: {
176
- InterceptionContext cContext = ruby___interception_get_context();
177
- InterceptionDevice cDevice = ruby___interception_find_mouse();
178
- InterceptionMouseStroke cStroke;
179
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_ABSOLUTE | INTERCEPTION_MOUSE_VIRTUAL_DESKTOP;
180
- cStroke.information = 0;
181
- cStroke.rolling = 0;
182
- cStroke.state = 0;
183
- cStroke.x = cX;
184
- cStroke.y = cY;
185
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
186
- break;
187
- }
188
- case MODE_WIN_API: {
189
- INPUT input;
190
- input.type = INPUT_MOUSE;
191
- input.mi.dwExtraInfo = 0;
192
- input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK | MOUSEEVENTF_MOVE;
193
- input.mi.dx = cX;
194
- input.mi.dy = cY;
195
- input.mi.mouseData = 0;
196
- input.mi.time = 0;
197
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
198
- RAISE_WIN32_ERROR();
199
- break;
200
- }
201
- default: {
202
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
203
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
204
- }
205
- }
206
- return self;
141
+ RUBY___MOVE_TO(NUM2LONG(x) + getVirtualScreenX(), NUM2LONG(y) + getVirtualScreenY());
207
142
  }
208
143
 
209
144
  //endregion cursor
210
145
 
146
+ #define RUBY___CLICK(interceptionStatePrefix, winAPIFlagPrefix, winAPIMouseData) \
147
+ VALUE times;\
148
+ UINT cTimes;\
149
+ UINT cT;\
150
+ SCAN_ARGUMENTS("01", &times);\
151
+ if (times == Qnil)\
152
+ cTimes = 1;\
153
+ else\
154
+ cTimes = NUM2UINT(times);\
155
+ switch (ruby___special_input_device_get_mode_identifier()) {\
156
+ case MODE_INTERCEPTION: {\
157
+ InterceptionContext cContext = ruby___interception_get_context();\
158
+ InterceptionDevice cDevice = ruby___interception_find_mouse();\
159
+ InterceptionMouseStroke cStroke[cTimes * 2];\
160
+ for (cT = 0; cT < cTimes; cT++) {\
161
+ cStroke[cT * 2 + 0].flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;\
162
+ cStroke[cT * 2 + 0].information = 0;\
163
+ cStroke[cT * 2 + 0].rolling = 0;\
164
+ cStroke[cT * 2 + 0].state = interceptionStatePrefix ## DOWN;\
165
+ cStroke[cT * 2 + 0].x = 0;\
166
+ cStroke[cT * 2 + 0].y = 0;\
167
+ cStroke[cT * 2 + 1].flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;\
168
+ cStroke[cT * 2 + 1].information = 0;\
169
+ cStroke[cT * 2 + 1].rolling = 0;\
170
+ cStroke[cT * 2 + 1].state = interceptionStatePrefix ## UP;\
171
+ cStroke[cT * 2 + 1].x = 0;\
172
+ cStroke[cT * 2 + 1].y = 0;\
173
+ }\
174
+ interceptionSend(cContext, cDevice, (InterceptionStroke *) cStroke, cTimes * 2);\
175
+ break;\
176
+ }\
177
+ case MODE_WIN_API: {\
178
+ INPUT input[cTimes * 2];\
179
+ for (cT = 0; cT < cTimes; cT++) {\
180
+ input[cT * 2 + 0].type = INPUT_MOUSE;\
181
+ input[cT * 2 + 0].mi.dwExtraInfo = 0;\
182
+ input[cT * 2 + 0].mi.dwFlags = winAPIFlagPrefix ## DOWN;\
183
+ input[cT * 2 + 0].mi.dx = 0;\
184
+ input[cT * 2 + 0].mi.dy = 0;\
185
+ input[cT * 2 + 0].mi.mouseData = winAPIMouseData;\
186
+ input[cT * 2 + 0].mi.time = 0;\
187
+ input[cT * 2 + 1].type = INPUT_MOUSE;\
188
+ input[cT * 2 + 1].mi.dwExtraInfo = 0;\
189
+ input[cT * 2 + 1].mi.dwFlags = winAPIFlagPrefix ## UP;\
190
+ input[cT * 2 + 1].mi.dx = 0;\
191
+ input[cT * 2 + 1].mi.dy = 0;\
192
+ input[cT * 2 + 1].mi.mouseData = winAPIMouseData;\
193
+ input[cT * 2 + 1].mi.time = 0;\
194
+ }\
195
+ if (!SendInput(cTimes * 2, input, sizeof(INPUT)))\
196
+ RAISE_WIN32_ERROR();\
197
+ break;\
198
+ }\
199
+ default: {\
200
+ PCHAR cModeName = ruby___special_input_device_get_mode_name();\
201
+ rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);\
202
+ }\
203
+ }\
204
+ return self;
205
+
206
+ #define RUBY___UP_DOWN(upDown, interceptionStatePrefix, winAPIFlagPrefix, winAPIMouseData) \
207
+ switch (ruby___special_input_device_get_mode_identifier()) {\
208
+ case MODE_INTERCEPTION: {\
209
+ InterceptionContext cContext = ruby___interception_get_context();\
210
+ InterceptionDevice cDevice = ruby___interception_find_mouse();\
211
+ InterceptionMouseStroke cStroke;\
212
+ cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;\
213
+ cStroke.information = 0;\
214
+ cStroke.rolling = 0;\
215
+ cStroke.state = interceptionStatePrefix ## upDown;\
216
+ cStroke.x = 0;\
217
+ cStroke.y = 0;\
218
+ interceptionSend(cContext, cDevice, (InterceptionStroke *) &cStroke, 1);\
219
+ break;\
220
+ }\
221
+ case MODE_WIN_API: {\
222
+ INPUT input;\
223
+ input.type = INPUT_MOUSE;\
224
+ input.mi.dwExtraInfo = 0;\
225
+ input.mi.dwFlags = winAPIFlagPrefix ## upDown;\
226
+ input.mi.dx = 0;\
227
+ input.mi.dy = 0;\
228
+ input.mi.mouseData = winAPIMouseData;\
229
+ input.mi.time = 0;\
230
+ if (!SendInput(1, &input, sizeof(INPUT)))\
231
+ RAISE_WIN32_ERROR();\
232
+ break;\
233
+ }\
234
+ default: {\
235
+ PCHAR cModeName = ruby___special_input_device_get_mode_name();\
236
+ rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);\
237
+ }\
238
+ }\
239
+ return self;
240
+
211
241
  //region left_button
212
242
 
213
243
  /*
214
- * Simulate clicking the left button on the mouse.
244
+ * @overload left_click(times = 1)
245
+ * Simulate clicking the left button on the mouse.
246
+ * @param [Integer] times click times
215
247
  * @return [Module] self
216
248
  * @see SpecialInputDevice::Window#mouse_left_click
217
249
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
218
250
  */
219
- static VALUE ruby__left_click(VALUE self) {
220
- switch (ruby___special_input_device_get_mode_identifier()) {
221
- case MODE_INTERCEPTION: {
222
- InterceptionContext cContext = ruby___interception_get_context();
223
- InterceptionDevice cDevice = ruby___interception_find_mouse();
224
- InterceptionMouseStroke cStroke[2];
225
- cStroke[0].flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
226
- cStroke[0].information = 0;
227
- cStroke[0].rolling = 0;
228
- cStroke[0].state = INTERCEPTION_MOUSE_LEFT_BUTTON_DOWN;
229
- cStroke[0].x = 0;
230
- cStroke[0].y = 0;
231
- cStroke[1].flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
232
- cStroke[1].information = 0;
233
- cStroke[1].rolling = 0;
234
- cStroke[1].state = INTERCEPTION_MOUSE_LEFT_BUTTON_UP;
235
- cStroke[1].x = 0;
236
- cStroke[1].y = 0;
237
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) cStroke, 2);
238
- break;
239
- }
240
- case MODE_WIN_API: {
241
- INPUT input[2];
242
- input[0].type = INPUT_MOUSE;
243
- input[0].mi.dwExtraInfo = 0;
244
- input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
245
- input[0].mi.dx = 0;
246
- input[0].mi.dy = 0;
247
- input[0].mi.mouseData = 0;
248
- input[0].mi.time = 0;
249
- input[1].type = INPUT_MOUSE;
250
- input[1].mi.dwExtraInfo = 0;
251
- input[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
252
- input[1].mi.dx = 0;
253
- input[1].mi.dy = 0;
254
- input[1].mi.mouseData = 0;
255
- input[1].mi.time = 0;
256
- if (SendInput(2, input, sizeof(INPUT)) == 0)
257
- RAISE_WIN32_ERROR();
258
- break;
259
- }
260
- default: {
261
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
262
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
263
- }
264
- }
265
- return self;
251
+ static VALUE ruby__left_click(VARIABLE_ARGUMENTS_C) {
252
+ RUBY___CLICK(INTERCEPTION_MOUSE_LEFT_BUTTON_, MOUSEEVENTF_LEFT, 0)
266
253
  }
267
254
 
268
255
  /*
@@ -272,39 +259,7 @@ static VALUE ruby__left_click(VALUE self) {
272
259
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
273
260
  */
274
261
  static VALUE ruby__left_down(VALUE self) {
275
- switch (ruby___special_input_device_get_mode_identifier()) {
276
- case MODE_INTERCEPTION: {
277
- InterceptionContext cContext = ruby___interception_get_context();
278
- InterceptionDevice cDevice = ruby___interception_find_mouse();
279
- InterceptionMouseStroke cStroke;
280
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
281
- cStroke.information = 0;
282
- cStroke.rolling = 0;
283
- cStroke.state = INTERCEPTION_MOUSE_LEFT_BUTTON_DOWN;
284
- cStroke.x = 0;
285
- cStroke.y = 0;
286
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
287
- break;
288
- }
289
- case MODE_WIN_API: {
290
- INPUT input;
291
- input.type = INPUT_MOUSE;
292
- input.mi.dwExtraInfo = 0;
293
- input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
294
- input.mi.dx = 0;
295
- input.mi.dy = 0;
296
- input.mi.mouseData = 0;
297
- input.mi.time = 0;
298
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
299
- RAISE_WIN32_ERROR();
300
- break;
301
- }
302
- default: {
303
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
304
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
305
- }
306
- }
307
- return self;
262
+ RUBY___UP_DOWN(DOWN, INTERCEPTION_MOUSE_LEFT_BUTTON_, MOUSEEVENTF_LEFT, 0)
308
263
  }
309
264
 
310
265
  /*
@@ -314,39 +269,7 @@ static VALUE ruby__left_down(VALUE self) {
314
269
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
315
270
  */
316
271
  static VALUE ruby__left_up(VALUE self) {
317
- switch (ruby___special_input_device_get_mode_identifier()) {
318
- case MODE_INTERCEPTION: {
319
- InterceptionContext cContext = ruby___interception_get_context();
320
- InterceptionDevice cDevice = ruby___interception_find_mouse();
321
- InterceptionMouseStroke cStroke;
322
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
323
- cStroke.information = 0;
324
- cStroke.rolling = 0;
325
- cStroke.state = INTERCEPTION_MOUSE_LEFT_BUTTON_UP;
326
- cStroke.x = 0;
327
- cStroke.y = 0;
328
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
329
- break;
330
- }
331
- case MODE_WIN_API: {
332
- INPUT input;
333
- input.type = INPUT_MOUSE;
334
- input.mi.dwExtraInfo = 0;
335
- input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
336
- input.mi.dx = 0;
337
- input.mi.dy = 0;
338
- input.mi.mouseData = 0;
339
- input.mi.time = 0;
340
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
341
- RAISE_WIN32_ERROR();
342
- break;
343
- }
344
- default: {
345
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
346
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
347
- }
348
- }
349
- return self;
272
+ RUBY___UP_DOWN(UP, INTERCEPTION_MOUSE_LEFT_BUTTON_, MOUSEEVENTF_LEFT, 0)
350
273
  }
351
274
 
352
275
  //endregion left_button
@@ -354,58 +277,15 @@ static VALUE ruby__left_up(VALUE self) {
354
277
  //region right_button
355
278
 
356
279
  /*
357
- * Simulate clicking the right button on the mouse.
280
+ * @overload right_click(times = 1)
281
+ * Simulate clicking the right button on the mouse.
282
+ * @param [Integer] times click times
358
283
  * @return [Module] self
359
284
  * @see SpecialInputDevice::Window#mouse_right_click
360
285
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
361
286
  */
362
- static VALUE ruby__right_click(VALUE self) {
363
- switch (ruby___special_input_device_get_mode_identifier()) {
364
- case MODE_INTERCEPTION: {
365
- InterceptionContext cContext = ruby___interception_get_context();
366
- InterceptionDevice cDevice = ruby___interception_find_mouse();
367
- InterceptionMouseStroke cStroke[2];
368
- cStroke[0].flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
369
- cStroke[0].information = 0;
370
- cStroke[0].rolling = 0;
371
- cStroke[0].state = INTERCEPTION_MOUSE_RIGHT_BUTTON_DOWN;
372
- cStroke[0].x = 0;
373
- cStroke[0].y = 0;
374
- cStroke[1].flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
375
- cStroke[1].information = 0;
376
- cStroke[1].rolling = 0;
377
- cStroke[1].state = INTERCEPTION_MOUSE_RIGHT_BUTTON_UP;
378
- cStroke[1].x = 0;
379
- cStroke[1].y = 0;
380
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) cStroke, 2);
381
- break;
382
- }
383
- case MODE_WIN_API: {
384
- INPUT input[2];
385
- input[0].type = INPUT_MOUSE;
386
- input[0].mi.dwExtraInfo = 0;
387
- input[0].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
388
- input[0].mi.dx = 0;
389
- input[0].mi.dy = 0;
390
- input[0].mi.mouseData = 0;
391
- input[0].mi.time = 0;
392
- input[1].type = INPUT_MOUSE;
393
- input[1].mi.dwExtraInfo = 0;
394
- input[1].mi.dwFlags = MOUSEEVENTF_RIGHTUP;
395
- input[1].mi.dx = 0;
396
- input[1].mi.dy = 0;
397
- input[1].mi.mouseData = 0;
398
- input[1].mi.time = 0;
399
- if (SendInput(2, input, sizeof(INPUT)) == 0)
400
- RAISE_WIN32_ERROR();
401
- break;
402
- }
403
- default: {
404
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
405
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
406
- }
407
- }
408
- return self;
287
+ static VALUE ruby__right_click(VARIABLE_ARGUMENTS_C) {
288
+ RUBY___CLICK(INTERCEPTION_MOUSE_RIGHT_BUTTON_, MOUSEEVENTF_RIGHT, 0)
409
289
  }
410
290
 
411
291
  /*
@@ -415,39 +295,7 @@ static VALUE ruby__right_click(VALUE self) {
415
295
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
416
296
  */
417
297
  static VALUE ruby__right_down(VALUE self) {
418
- switch (ruby___special_input_device_get_mode_identifier()) {
419
- case MODE_INTERCEPTION: {
420
- InterceptionContext cContext = ruby___interception_get_context();
421
- InterceptionDevice cDevice = ruby___interception_find_mouse();
422
- InterceptionMouseStroke cStroke;
423
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
424
- cStroke.information = 0;
425
- cStroke.rolling = 0;
426
- cStroke.state = INTERCEPTION_MOUSE_RIGHT_BUTTON_DOWN;
427
- cStroke.x = 0;
428
- cStroke.y = 0;
429
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
430
- break;
431
- }
432
- case MODE_WIN_API: {
433
- INPUT input;
434
- input.type = INPUT_MOUSE;
435
- input.mi.dwExtraInfo = 0;
436
- input.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
437
- input.mi.dx = 0;
438
- input.mi.dy = 0;
439
- input.mi.mouseData = 0;
440
- input.mi.time = 0;
441
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
442
- RAISE_WIN32_ERROR();
443
- break;
444
- }
445
- default: {
446
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
447
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
448
- }
449
- }
450
- return self;
298
+ RUBY___UP_DOWN(DOWN, INTERCEPTION_MOUSE_RIGHT_BUTTON_, MOUSEEVENTF_RIGHT, 0)
451
299
  }
452
300
 
453
301
  /*
@@ -457,39 +305,7 @@ static VALUE ruby__right_down(VALUE self) {
457
305
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
458
306
  */
459
307
  static VALUE ruby__right_up(VALUE self) {
460
- switch (ruby___special_input_device_get_mode_identifier()) {
461
- case MODE_INTERCEPTION: {
462
- InterceptionContext cContext = ruby___interception_get_context();
463
- InterceptionDevice cDevice = ruby___interception_find_mouse();
464
- InterceptionMouseStroke cStroke;
465
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
466
- cStroke.information = 0;
467
- cStroke.rolling = 0;
468
- cStroke.state = INTERCEPTION_MOUSE_RIGHT_BUTTON_UP;
469
- cStroke.x = 0;
470
- cStroke.y = 0;
471
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
472
- break;
473
- }
474
- case MODE_WIN_API: {
475
- INPUT input;
476
- input.type = INPUT_MOUSE;
477
- input.mi.dwExtraInfo = 0;
478
- input.mi.dwFlags = MOUSEEVENTF_RIGHTUP;
479
- input.mi.dx = 0;
480
- input.mi.dy = 0;
481
- input.mi.mouseData = 0;
482
- input.mi.time = 0;
483
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
484
- RAISE_WIN32_ERROR();
485
- break;
486
- }
487
- default: {
488
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
489
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
490
- }
491
- }
492
- return self;
308
+ RUBY___UP_DOWN(UP, INTERCEPTION_MOUSE_RIGHT_BUTTON_, MOUSEEVENTF_RIGHT, 0)
493
309
  }
494
310
 
495
311
  //endregion right_button
@@ -497,58 +313,15 @@ static VALUE ruby__right_up(VALUE self) {
497
313
  //region middle_button
498
314
 
499
315
  /*
500
- * Simulate clicking the middle button on the mouse.
316
+ * @overload middle_click(times = 1)
317
+ * Simulate clicking the middle button on the mouse.
318
+ * @param [Integer] times click times
501
319
  * @return [Module] self
502
320
  * @see SpecialInputDevice::Window#mouse_middle_click
503
321
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
504
322
  */
505
- static VALUE ruby__middle_click(VALUE self) {
506
- switch (ruby___special_input_device_get_mode_identifier()) {
507
- case MODE_INTERCEPTION: {
508
- InterceptionContext cContext = ruby___interception_get_context();
509
- InterceptionDevice cDevice = ruby___interception_find_mouse();
510
- InterceptionMouseStroke cStroke[2];
511
- cStroke[0].flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
512
- cStroke[0].information = 0;
513
- cStroke[0].rolling = 0;
514
- cStroke[0].state = INTERCEPTION_MOUSE_MIDDLE_BUTTON_DOWN;
515
- cStroke[0].x = 0;
516
- cStroke[0].y = 0;
517
- cStroke[1].flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
518
- cStroke[1].information = 0;
519
- cStroke[1].rolling = 0;
520
- cStroke[1].state = INTERCEPTION_MOUSE_MIDDLE_BUTTON_UP;
521
- cStroke[1].x = 0;
522
- cStroke[1].y = 0;
523
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) cStroke, 2);
524
- break;
525
- }
526
- case MODE_WIN_API: {
527
- INPUT input[2];
528
- input[0].type = INPUT_MOUSE;
529
- input[0].mi.dwExtraInfo = 0;
530
- input[0].mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
531
- input[0].mi.dx = 0;
532
- input[0].mi.dy = 0;
533
- input[0].mi.mouseData = 0;
534
- input[0].mi.time = 0;
535
- input[1].type = INPUT_MOUSE;
536
- input[1].mi.dwExtraInfo = 0;
537
- input[1].mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
538
- input[1].mi.dx = 0;
539
- input[1].mi.dy = 0;
540
- input[1].mi.mouseData = 0;
541
- input[1].mi.time = 0;
542
- if (SendInput(2, input, sizeof(INPUT)) == 0)
543
- RAISE_WIN32_ERROR();
544
- break;
545
- }
546
- default: {
547
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
548
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
549
- }
550
- }
551
- return self;
323
+ static VALUE ruby__middle_click(VARIABLE_ARGUMENTS_C) {
324
+ RUBY___CLICK(INTERCEPTION_MOUSE_MIDDLE_BUTTON_, MOUSEEVENTF_MIDDLE, 0)
552
325
  }
553
326
 
554
327
  /*
@@ -558,39 +331,7 @@ static VALUE ruby__middle_click(VALUE self) {
558
331
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
559
332
  */
560
333
  static VALUE ruby__middle_down(VALUE self) {
561
- switch (ruby___special_input_device_get_mode_identifier()) {
562
- case MODE_INTERCEPTION: {
563
- InterceptionContext cContext = ruby___interception_get_context();
564
- InterceptionDevice cDevice = ruby___interception_find_mouse();
565
- InterceptionMouseStroke cStroke;
566
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
567
- cStroke.information = 0;
568
- cStroke.rolling = 0;
569
- cStroke.state = INTERCEPTION_MOUSE_MIDDLE_BUTTON_DOWN;
570
- cStroke.x = 0;
571
- cStroke.y = 0;
572
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
573
- break;
574
- }
575
- case MODE_WIN_API: {
576
- INPUT input;
577
- input.type = INPUT_MOUSE;
578
- input.mi.dwExtraInfo = 0;
579
- input.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
580
- input.mi.dx = 0;
581
- input.mi.dy = 0;
582
- input.mi.mouseData = 0;
583
- input.mi.time = 0;
584
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
585
- RAISE_WIN32_ERROR();
586
- break;
587
- }
588
- default: {
589
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
590
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
591
- }
592
- }
593
- return self;
334
+ RUBY___UP_DOWN(DOWN, INTERCEPTION_MOUSE_MIDDLE_BUTTON_, MOUSEEVENTF_MIDDLE, 0)
594
335
  }
595
336
 
596
337
  /*
@@ -600,39 +341,7 @@ static VALUE ruby__middle_down(VALUE self) {
600
341
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
601
342
  */
602
343
  static VALUE ruby__middle_up(VALUE self) {
603
- switch (ruby___special_input_device_get_mode_identifier()) {
604
- case MODE_INTERCEPTION: {
605
- InterceptionContext cContext = ruby___interception_get_context();
606
- InterceptionDevice cDevice = ruby___interception_find_mouse();
607
- InterceptionMouseStroke cStroke;
608
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
609
- cStroke.information = 0;
610
- cStroke.rolling = 0;
611
- cStroke.state = INTERCEPTION_MOUSE_MIDDLE_BUTTON_UP;
612
- cStroke.x = 0;
613
- cStroke.y = 0;
614
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
615
- break;
616
- }
617
- case MODE_WIN_API: {
618
- INPUT input;
619
- input.type = INPUT_MOUSE;
620
- input.mi.dwExtraInfo = 0;
621
- input.mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
622
- input.mi.dx = 0;
623
- input.mi.dy = 0;
624
- input.mi.mouseData = 0;
625
- input.mi.time = 0;
626
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
627
- RAISE_WIN32_ERROR();
628
- break;
629
- }
630
- default: {
631
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
632
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
633
- }
634
- }
635
- return self;
344
+ RUBY___UP_DOWN(UP, INTERCEPTION_MOUSE_MIDDLE_BUTTON_, MOUSEEVENTF_MIDDLE, 0)
636
345
  }
637
346
 
638
347
  //endregion middle_button
@@ -640,58 +349,15 @@ static VALUE ruby__middle_up(VALUE self) {
640
349
  //region x_button
641
350
 
642
351
  /*
643
- * Simulate clicking the x1 button on the mouse.
352
+ * @overload x1_click(times = 1)
353
+ * Simulate clicking the x1 button on the mouse.
354
+ * @param [Integer] times click times
644
355
  * @return [Module] self
645
356
  * @see SpecialInputDevice::Window#mouse_x1_click
646
357
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
647
358
  */
648
- static VALUE ruby__x1_click(VALUE self) {
649
- switch (ruby___special_input_device_get_mode_identifier()) {
650
- case MODE_INTERCEPTION: {
651
- InterceptionContext cContext = ruby___interception_get_context();
652
- InterceptionDevice cDevice = ruby___interception_find_mouse();
653
- InterceptionMouseStroke cStroke[2];
654
- cStroke[0].flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
655
- cStroke[0].information = 0;
656
- cStroke[0].rolling = 0;
657
- cStroke[0].state = INTERCEPTION_MOUSE_BUTTON_4_DOWN;
658
- cStroke[0].x = 0;
659
- cStroke[0].y = 0;
660
- cStroke[1].flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
661
- cStroke[1].information = 0;
662
- cStroke[1].rolling = 0;
663
- cStroke[1].state = INTERCEPTION_MOUSE_BUTTON_4_UP;
664
- cStroke[1].x = 0;
665
- cStroke[1].y = 0;
666
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) cStroke, 2);
667
- break;
668
- }
669
- case MODE_WIN_API: {
670
- INPUT input[2];
671
- input[0].type = INPUT_MOUSE;
672
- input[0].mi.dwExtraInfo = 0;
673
- input[0].mi.dwFlags = MOUSEEVENTF_XDOWN;
674
- input[0].mi.dx = 0;
675
- input[0].mi.dy = 0;
676
- input[0].mi.mouseData = XBUTTON1;
677
- input[0].mi.time = 0;
678
- input[1].type = INPUT_MOUSE;
679
- input[1].mi.dwExtraInfo = 0;
680
- input[1].mi.dwFlags = MOUSEEVENTF_XUP;
681
- input[1].mi.dx = 0;
682
- input[1].mi.dy = 0;
683
- input[1].mi.mouseData = XBUTTON1;
684
- input[1].mi.time = 0;
685
- if (SendInput(2, input, sizeof(INPUT)) == 0)
686
- RAISE_WIN32_ERROR();
687
- break;
688
- }
689
- default: {
690
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
691
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
692
- }
693
- }
694
- return self;
359
+ static VALUE ruby__x1_click(VARIABLE_ARGUMENTS_C) {
360
+ RUBY___CLICK(INTERCEPTION_MOUSE_BUTTON_4_, MOUSEEVENTF_X, XBUTTON1)
695
361
  }
696
362
 
697
363
  /*
@@ -701,39 +367,7 @@ static VALUE ruby__x1_click(VALUE self) {
701
367
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
702
368
  */
703
369
  static VALUE ruby__x1_down(VALUE self) {
704
- switch (ruby___special_input_device_get_mode_identifier()) {
705
- case MODE_INTERCEPTION: {
706
- InterceptionContext cContext = ruby___interception_get_context();
707
- InterceptionDevice cDevice = ruby___interception_find_mouse();
708
- InterceptionMouseStroke cStroke;
709
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
710
- cStroke.information = 0;
711
- cStroke.rolling = 0;
712
- cStroke.state = INTERCEPTION_MOUSE_BUTTON_4_DOWN;
713
- cStroke.x = 0;
714
- cStroke.y = 0;
715
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
716
- break;
717
- }
718
- case MODE_WIN_API: {
719
- INPUT input;
720
- input.type = INPUT_MOUSE;
721
- input.mi.dwExtraInfo = 0;
722
- input.mi.dwFlags = MOUSEEVENTF_XDOWN;
723
- input.mi.dx = 0;
724
- input.mi.dy = 0;
725
- input.mi.mouseData = XBUTTON1;
726
- input.mi.time = 0;
727
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
728
- RAISE_WIN32_ERROR();
729
- break;
730
- }
731
- default: {
732
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
733
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
734
- }
735
- }
736
- return self;
370
+ RUBY___UP_DOWN(DOWN, INTERCEPTION_MOUSE_BUTTON_4_, MOUSEEVENTF_X, XBUTTON1)
737
371
  }
738
372
 
739
373
  /*
@@ -743,94 +377,19 @@ static VALUE ruby__x1_down(VALUE self) {
743
377
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
744
378
  */
745
379
  static VALUE ruby__x1_up(VALUE self) {
746
- switch (ruby___special_input_device_get_mode_identifier()) {
747
- case MODE_INTERCEPTION: {
748
- InterceptionContext cContext = ruby___interception_get_context();
749
- InterceptionDevice cDevice = ruby___interception_find_mouse();
750
- InterceptionMouseStroke cStroke;
751
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
752
- cStroke.information = 0;
753
- cStroke.rolling = 0;
754
- cStroke.state = INTERCEPTION_MOUSE_BUTTON_4_UP;
755
- cStroke.x = 0;
756
- cStroke.y = 0;
757
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
758
- break;
759
- }
760
- case MODE_WIN_API: {
761
- INPUT input;
762
- input.type = INPUT_MOUSE;
763
- input.mi.dwExtraInfo = 0;
764
- input.mi.dwFlags = MOUSEEVENTF_XUP;
765
- input.mi.dx = 0;
766
- input.mi.dy = 0;
767
- input.mi.mouseData = XBUTTON1;
768
- input.mi.time = 0;
769
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
770
- RAISE_WIN32_ERROR();
771
- break;
772
- }
773
- default: {
774
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
775
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
776
- }
777
- }
778
- return self;
380
+ RUBY___UP_DOWN(UP, INTERCEPTION_MOUSE_BUTTON_4_, MOUSEEVENTF_X, XBUTTON1)
779
381
  }
780
382
 
781
383
  /*
782
- * Simulate clicking the x2 button on the mouse.
384
+ * @overload x2_click(times = 1)
385
+ * Simulate clicking the x2 button on the mouse.
386
+ * @param [Integer] times click times
783
387
  * @return [Module] self
784
388
  * @see SpecialInputDevice::Window#mouse_x2_click
785
389
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
786
390
  */
787
- static VALUE ruby__x2_click(VALUE self) {
788
- switch (ruby___special_input_device_get_mode_identifier()) {
789
- case MODE_INTERCEPTION: {
790
- InterceptionContext cContext = ruby___interception_get_context();
791
- InterceptionDevice cDevice = ruby___interception_find_mouse();
792
- InterceptionMouseStroke cStroke[2];
793
- cStroke[0].flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
794
- cStroke[0].information = 0;
795
- cStroke[0].rolling = 0;
796
- cStroke[0].state = INTERCEPTION_MOUSE_BUTTON_5_DOWN;
797
- cStroke[0].x = 0;
798
- cStroke[0].y = 0;
799
- cStroke[1].flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
800
- cStroke[1].information = 0;
801
- cStroke[1].rolling = 0;
802
- cStroke[1].state = INTERCEPTION_MOUSE_BUTTON_5_UP;
803
- cStroke[1].x = 0;
804
- cStroke[1].y = 0;
805
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) cStroke, 2);
806
- break;
807
- }
808
- case MODE_WIN_API: {
809
- INPUT input[2];
810
- input[0].type = INPUT_MOUSE;
811
- input[0].mi.dwExtraInfo = 0;
812
- input[0].mi.dwFlags = MOUSEEVENTF_XDOWN;
813
- input[0].mi.dx = 0;
814
- input[0].mi.dy = 0;
815
- input[0].mi.mouseData = XBUTTON2;
816
- input[0].mi.time = 0;
817
- input[1].type = INPUT_MOUSE;
818
- input[1].mi.dwExtraInfo = 0;
819
- input[1].mi.dwFlags = MOUSEEVENTF_XUP;
820
- input[1].mi.dx = 0;
821
- input[1].mi.dy = 0;
822
- input[1].mi.mouseData = XBUTTON2;
823
- input[1].mi.time = 0;
824
- if (SendInput(2, input, sizeof(INPUT)) == 0)
825
- RAISE_WIN32_ERROR();
826
- break;
827
- }
828
- default: {
829
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
830
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
831
- }
832
- }
833
- return self;
391
+ static VALUE ruby__x2_click(VARIABLE_ARGUMENTS_C) {
392
+ RUBY___CLICK(INTERCEPTION_MOUSE_BUTTON_5_, MOUSEEVENTF_X, XBUTTON2)
834
393
  }
835
394
 
836
395
  /*
@@ -840,39 +399,7 @@ static VALUE ruby__x2_click(VALUE self) {
840
399
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
841
400
  */
842
401
  static VALUE ruby__x2_down(VALUE self) {
843
- switch (ruby___special_input_device_get_mode_identifier()) {
844
- case MODE_INTERCEPTION: {
845
- InterceptionContext cContext = ruby___interception_get_context();
846
- InterceptionDevice cDevice = ruby___interception_find_mouse();
847
- InterceptionMouseStroke cStroke;
848
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
849
- cStroke.information = 0;
850
- cStroke.rolling = 0;
851
- cStroke.state = INTERCEPTION_MOUSE_BUTTON_5_DOWN;
852
- cStroke.x = 0;
853
- cStroke.y = 0;
854
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
855
- break;
856
- }
857
- case MODE_WIN_API: {
858
- INPUT input;
859
- input.type = INPUT_MOUSE;
860
- input.mi.dwExtraInfo = 0;
861
- input.mi.dwFlags = MOUSEEVENTF_XDOWN;
862
- input.mi.dx = 0;
863
- input.mi.dy = 0;
864
- input.mi.mouseData = XBUTTON2;
865
- input.mi.time = 0;
866
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
867
- RAISE_WIN32_ERROR();
868
- break;
869
- }
870
- default: {
871
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
872
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
873
- }
874
- }
875
- return self;
402
+ RUBY___UP_DOWN(DOWN, INTERCEPTION_MOUSE_BUTTON_5_, MOUSEEVENTF_X, XBUTTON2)
876
403
  }
877
404
 
878
405
  /*
@@ -882,216 +409,110 @@ static VALUE ruby__x2_down(VALUE self) {
882
409
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
883
410
  */
884
411
  static VALUE ruby__x2_up(VALUE self) {
885
- switch (ruby___special_input_device_get_mode_identifier()) {
886
- case MODE_INTERCEPTION: {
887
- InterceptionContext cContext = ruby___interception_get_context();
888
- InterceptionDevice cDevice = ruby___interception_find_mouse();
889
- InterceptionMouseStroke cStroke;
890
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
891
- cStroke.information = 0;
892
- cStroke.rolling = 0;
893
- cStroke.state = INTERCEPTION_MOUSE_BUTTON_5_UP;
894
- cStroke.x = 0;
895
- cStroke.y = 0;
896
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
897
- break;
898
- }
899
- case MODE_WIN_API: {
900
- INPUT input;
901
- input.type = INPUT_MOUSE;
902
- input.mi.dwExtraInfo = 0;
903
- input.mi.dwFlags = MOUSEEVENTF_XUP;
904
- input.mi.dx = 0;
905
- input.mi.dy = 0;
906
- input.mi.mouseData = XBUTTON2;
907
- input.mi.time = 0;
908
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
909
- RAISE_WIN32_ERROR();
910
- break;
911
- }
912
- default: {
913
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
914
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
915
- }
916
- }
917
- return self;
412
+ RUBY___UP_DOWN(UP, INTERCEPTION_MOUSE_BUTTON_5_, MOUSEEVENTF_X, XBUTTON2)
918
413
  }
919
414
 
920
415
  //endregion x_button
921
416
 
922
417
  //region wheel
923
418
 
419
+ #define RUBY___SCROLL_NEGATIVE_DIRECTION(oppositeDirection) \
420
+ VALUE times = cCount ? rb_funcall(cArguments[0], rb_intern_const("-@"), 0) : INT2FIX(-1);\
421
+ return oppositeDirection(1, &times, self);
422
+
423
+ #define RUBY___SCROLL_POSITIVE_DIRECTION(directionPrefix) \
424
+ VALUE times;\
425
+ SHORT cTimes;\
426
+ SCAN_ARGUMENTS("01", &times);\
427
+ if (times == Qnil)\
428
+ cTimes = 1;\
429
+ else\
430
+ cTimes = NUM2SHORT(times);\
431
+ switch (ruby___special_input_device_get_mode_identifier()) {\
432
+ case MODE_INTERCEPTION: {\
433
+ InterceptionContext cContext = ruby___interception_get_context();\
434
+ InterceptionDevice cDevice = ruby___interception_find_mouse();\
435
+ InterceptionMouseStroke cStroke;\
436
+ cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;\
437
+ cStroke.information = 0;\
438
+ cStroke.rolling = (SHORT) (WHEEL_DELTA * cTimes);\
439
+ cStroke.state = INTERCEPTION_MOUSE_ ## directionPrefix ## WHEEL;\
440
+ cStroke.x = 0;\
441
+ cStroke.y = 0;\
442
+ interceptionSend(cContext, cDevice, (InterceptionStroke *) &cStroke, 1);\
443
+ break;\
444
+ }\
445
+ case MODE_WIN_API: {\
446
+ INPUT input;\
447
+ input.type = INPUT_MOUSE;\
448
+ input.mi.dwExtraInfo = 0;\
449
+ input.mi.dwFlags = MOUSEEVENTF_ ## directionPrefix ## WHEEL;\
450
+ input.mi.dx = 0;\
451
+ input.mi.dy = 0;\
452
+ input.mi.mouseData = (DWORD) (WHEEL_DELTA * cTimes);\
453
+ input.mi.time = 0;\
454
+ if (!SendInput(1, &input, sizeof(INPUT)))\
455
+ RAISE_WIN32_ERROR();\
456
+ break;\
457
+ }\
458
+ default: {\
459
+ PCHAR cModeName = ruby___special_input_device_get_mode_name();\
460
+ rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);\
461
+ }\
462
+ }\
463
+ return self;
464
+
465
+ static VALUE ruby__scroll_wheel_forward(VARIABLE_ARGUMENTS_C);
466
+
924
467
  /*
925
- * Simulate wheeling the scroll backward.
468
+ * @overload scroll_wheel_backward(times = 1)
469
+ * Simulate wheeling the scroll backward.
470
+ * @param [Integer] times click times
926
471
  * @return [Module] self
927
472
  * @see SpecialInputDevice::Window#mouse_scroll_wheel_backward
928
473
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
929
474
  */
930
- static VALUE ruby__scroll_wheel_backward(VALUE self) {
931
- switch (ruby___special_input_device_get_mode_identifier()) {
932
- case MODE_INTERCEPTION: {
933
- InterceptionContext cContext = ruby___interception_get_context();
934
- InterceptionDevice cDevice = ruby___interception_find_mouse();
935
- InterceptionMouseStroke cStroke;
936
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
937
- cStroke.information = 0;
938
- cStroke.rolling = -WHEEL_DELTA;
939
- cStroke.state = INTERCEPTION_MOUSE_WHEEL;
940
- cStroke.x = 0;
941
- cStroke.y = 0;
942
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
943
- break;
944
- }
945
- case MODE_WIN_API: {
946
- INPUT input;
947
- input.type = INPUT_MOUSE;
948
- input.mi.dwExtraInfo = 0;
949
- input.mi.dwFlags = MOUSEEVENTF_WHEEL;
950
- input.mi.dx = 0;
951
- input.mi.dy = 0;
952
- input.mi.mouseData = (DWORD) -WHEEL_DELTA;
953
- input.mi.time = 0;
954
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
955
- RAISE_WIN32_ERROR();
956
- break;
957
- }
958
- default: {
959
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
960
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
961
- }
962
- }
963
- return self;
475
+ static VALUE ruby__scroll_wheel_backward(VARIABLE_ARGUMENTS_C) {
476
+ RUBY___SCROLL_NEGATIVE_DIRECTION(ruby__scroll_wheel_forward)
964
477
  }
965
478
 
966
479
  /*
967
- * Simulate wheeling the scroll forward.
480
+ * @overload scroll_wheel_forward(times = 1)
481
+ * Simulate wheeling the scroll forward.
482
+ * @param [Integer] times click times
968
483
  * @return [Module] self
969
484
  * @see SpecialInputDevice::Window#mouse_scroll_wheel_forward
970
485
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
971
486
  */
972
- static VALUE ruby__scroll_wheel_forward(VALUE self) {
973
- switch (ruby___special_input_device_get_mode_identifier()) {
974
- case MODE_INTERCEPTION: {
975
- InterceptionContext cContext = ruby___interception_get_context();
976
- InterceptionDevice cDevice = ruby___interception_find_mouse();
977
- InterceptionMouseStroke cStroke;
978
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
979
- cStroke.information = 0;
980
- cStroke.rolling = WHEEL_DELTA;
981
- cStroke.state = INTERCEPTION_MOUSE_WHEEL;
982
- cStroke.x = 0;
983
- cStroke.y = 0;
984
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
985
- break;
986
- }
987
- case MODE_WIN_API: {
988
- INPUT input;
989
- input.type = INPUT_MOUSE;
990
- input.mi.dwExtraInfo = 0;
991
- input.mi.dwFlags = MOUSEEVENTF_WHEEL;
992
- input.mi.dx = 0;
993
- input.mi.dy = 0;
994
- input.mi.mouseData = WHEEL_DELTA;
995
- input.mi.time = 0;
996
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
997
- RAISE_WIN32_ERROR();
998
- break;
999
- }
1000
- default: {
1001
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
1002
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
1003
- }
1004
- }
1005
- return self;
487
+ static VALUE ruby__scroll_wheel_forward(VARIABLE_ARGUMENTS_C) {
488
+ RUBY___SCROLL_POSITIVE_DIRECTION()
1006
489
  }
1007
490
 
491
+ static VALUE ruby__scroll_wheel_to_right(VARIABLE_ARGUMENTS_C);
492
+
1008
493
  /*
1009
- * Simulate wheeling the scroll to left hand side.
494
+ * @overload scroll_wheel_to_left(times = 1)
495
+ * Simulate wheeling the scroll to left hand side.
496
+ * @param [Integer] times click times
1010
497
  * @return [Module] self
1011
498
  * @see SpecialInputDevice::Window#mouse_scroll_wheel_to_left
1012
499
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
1013
500
  */
1014
- static VALUE ruby__scroll_wheel_to_left(VALUE self) {
1015
- #ifdef MOUSEEVENTF_HWHEEL
1016
- switch (ruby___special_input_device_get_mode_identifier()) {
1017
- case MODE_INTERCEPTION: {
1018
- InterceptionContext cContext = ruby___interception_get_context();
1019
- InterceptionDevice cDevice = ruby___interception_find_mouse();
1020
- InterceptionMouseStroke cStroke;
1021
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
1022
- cStroke.information = 0;
1023
- cStroke.rolling = -WHEEL_DELTA;
1024
- cStroke.state = INTERCEPTION_MOUSE_HWHEEL;
1025
- cStroke.x = 0;
1026
- cStroke.y = 0;
1027
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
1028
- break;
1029
- }
1030
- case MODE_WIN_API: {
1031
- INPUT input;
1032
- input.type = INPUT_MOUSE;
1033
- input.mi.dwExtraInfo = 0;
1034
- input.mi.dwFlags = MOUSEEVENTF_HWHEEL;
1035
- input.mi.dx = 0;
1036
- input.mi.dy = 0;
1037
- input.mi.mouseData = (DWORD) -WHEEL_DELTA;
1038
- input.mi.time = 0;
1039
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
1040
- RAISE_WIN32_ERROR();
1041
- break;
1042
- }
1043
- default: {
1044
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
1045
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
1046
- }
1047
- }
1048
- return self;
1049
- #else
1050
- rb_raise(rb_eRuntimeError, "Error! Your system not support horizontal wheel.");
1051
- #endif
501
+ static VALUE ruby__scroll_wheel_to_left(VARIABLE_ARGUMENTS_C) {
502
+ RUBY___SCROLL_NEGATIVE_DIRECTION(ruby__scroll_wheel_to_right)
1052
503
  }
1053
504
 
1054
505
  /*
1055
- * Simulate wheeling the scroll to right hand side.
506
+ * @overload scroll_wheel_to_right(times = 1)
507
+ * Simulate wheeling the scroll to right hand side.
508
+ * @param [Integer] times click times
1056
509
  * @return [Module] self
1057
510
  * @see SpecialInputDevice::Window#mouse_scroll_wheel_to_right
1058
511
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
1059
512
  */
1060
- static VALUE ruby__scroll_wheel_to_right(VALUE self) {
513
+ static VALUE ruby__scroll_wheel_to_right(VARIABLE_ARGUMENTS_C) {
1061
514
  #ifdef MOUSEEVENTF_HWHEEL
1062
- switch (ruby___special_input_device_get_mode_identifier()) {
1063
- case MODE_INTERCEPTION: {
1064
- InterceptionContext cContext = ruby___interception_get_context();
1065
- InterceptionDevice cDevice = ruby___interception_find_mouse();
1066
- InterceptionMouseStroke cStroke;
1067
- cStroke.flags = INTERCEPTION_MOUSE_MOVE_RELATIVE;
1068
- cStroke.information = 0;
1069
- cStroke.rolling = WHEEL_DELTA;
1070
- cStroke.state = INTERCEPTION_MOUSE_HWHEEL;
1071
- cStroke.x = 0;
1072
- cStroke.y = 0;
1073
- interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
1074
- break;
1075
- }
1076
- case MODE_WIN_API: {
1077
- INPUT input;
1078
- input.type = INPUT_MOUSE;
1079
- input.mi.dwExtraInfo = 0;
1080
- input.mi.dwFlags = MOUSEEVENTF_HWHEEL;
1081
- input.mi.dx = 0;
1082
- input.mi.dy = 0;
1083
- input.mi.mouseData = WHEEL_DELTA;
1084
- input.mi.time = 0;
1085
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
1086
- RAISE_WIN32_ERROR();
1087
- break;
1088
- }
1089
- default: {
1090
- PCHAR cModeName = ruby___special_input_device_get_mode_name();
1091
- rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
1092
- }
1093
- }
1094
- return self;
515
+ RUBY___SCROLL_POSITIVE_DIRECTION(H)
1095
516
  #else
1096
517
  rb_raise(rb_eRuntimeError, "Error! Your system not support horizontal wheel.");
1097
518
  #endif
@@ -1115,23 +536,23 @@ VOID Init_mouse() {
1115
536
  rb_define_singleton_method(specialInputDevice_mouse, "move_relatively", ruby__move_relatively, 2);
1116
537
  rb_define_singleton_method(specialInputDevice_mouse, "move_to_primary", ruby__move_to_primary, 2);
1117
538
  rb_define_singleton_method(specialInputDevice_mouse, "move_to_virtual", ruby__move_to_virtual, 2);
1118
- rb_define_singleton_method(specialInputDevice_mouse, "left_click", ruby__left_click, 0);
539
+ rb_define_singleton_method(specialInputDevice_mouse, "left_click", ruby__left_click, -1);
1119
540
  rb_define_singleton_method(specialInputDevice_mouse, "left_down", ruby__left_down, 0);
1120
541
  rb_define_singleton_method(specialInputDevice_mouse, "left_up", ruby__left_up, 0);
1121
- rb_define_singleton_method(specialInputDevice_mouse, "right_click", ruby__right_click, 0);
542
+ rb_define_singleton_method(specialInputDevice_mouse, "right_click", ruby__right_click, -1);
1122
543
  rb_define_singleton_method(specialInputDevice_mouse, "right_down", ruby__right_down, 0);
1123
544
  rb_define_singleton_method(specialInputDevice_mouse, "right_up", ruby__right_up, 0);
1124
- rb_define_singleton_method(specialInputDevice_mouse, "middle_click", ruby__middle_click, 0);
545
+ rb_define_singleton_method(specialInputDevice_mouse, "middle_click", ruby__middle_click, -1);
1125
546
  rb_define_singleton_method(specialInputDevice_mouse, "middle_down", ruby__middle_down, 0);
1126
547
  rb_define_singleton_method(specialInputDevice_mouse, "middle_up", ruby__middle_up, 0);
1127
- rb_define_singleton_method(specialInputDevice_mouse, "x1_click", ruby__x1_click, 0);
548
+ rb_define_singleton_method(specialInputDevice_mouse, "x1_click", ruby__x1_click, -1);
1128
549
  rb_define_singleton_method(specialInputDevice_mouse, "x1_down", ruby__x1_down, 0);
1129
550
  rb_define_singleton_method(specialInputDevice_mouse, "x1_up", ruby__x1_up, 0);
1130
- rb_define_singleton_method(specialInputDevice_mouse, "x2_click", ruby__x2_click, 0);
551
+ rb_define_singleton_method(specialInputDevice_mouse, "x2_click", ruby__x2_click, -1);
1131
552
  rb_define_singleton_method(specialInputDevice_mouse, "x2_down", ruby__x2_down, 0);
1132
553
  rb_define_singleton_method(specialInputDevice_mouse, "x2_up", ruby__x2_up, 0);
1133
- rb_define_singleton_method(specialInputDevice_mouse, "scroll_wheel_backward", ruby__scroll_wheel_backward, 0);
1134
- rb_define_singleton_method(specialInputDevice_mouse, "scroll_wheel_forward", ruby__scroll_wheel_forward, 0);
1135
- rb_define_singleton_method(specialInputDevice_mouse, "scroll_wheel_to_left", ruby__scroll_wheel_to_left, 0);
1136
- rb_define_singleton_method(specialInputDevice_mouse, "scroll_wheel_to_right", ruby__scroll_wheel_to_right, 0);
554
+ rb_define_singleton_method(specialInputDevice_mouse, "scroll_wheel_backward", ruby__scroll_wheel_backward, -1);
555
+ rb_define_singleton_method(specialInputDevice_mouse, "scroll_wheel_forward", ruby__scroll_wheel_forward, -1);
556
+ rb_define_singleton_method(specialInputDevice_mouse, "scroll_wheel_to_left", ruby__scroll_wheel_to_left, -1);
557
+ rb_define_singleton_method(specialInputDevice_mouse, "scroll_wheel_to_right", ruby__scroll_wheel_to_right, -1);
1137
558
  }