special_input_device 0.0.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.
- checksums.yaml +7 -0
- data/ext/special_input_device/_screen.c +25 -0
- data/ext/special_input_device/_screen.h +16 -0
- data/ext/special_input_device/_system_time.c +10 -0
- data/ext/special_input_device/_system_time.h +6 -0
- data/ext/special_input_device/_vendor__interception.c +331 -0
- data/ext/special_input_device/_vendor__interception.h +196 -0
- data/ext/special_input_device/color.c +25 -0
- data/ext/special_input_device/color.h +10 -0
- data/ext/special_input_device/extconf.rb +6 -0
- data/ext/special_input_device/interception_connector.c +75 -0
- data/ext/special_input_device/interception_connector.h +13 -0
- data/ext/special_input_device/keyboard.c +152 -0
- data/ext/special_input_device/mouse.c +1137 -0
- data/ext/special_input_device/point.c +17 -0
- data/ext/special_input_device/point.h +10 -0
- data/ext/special_input_device/rectangle.c +25 -0
- data/ext/special_input_device/rectangle.h +10 -0
- data/ext/special_input_device/ruby_macro.h +84 -0
- data/ext/special_input_device/screen.c +302 -0
- data/ext/special_input_device/special_input_device.c +40 -0
- data/ext/special_input_device/special_input_device.h +42 -0
- data/ext/special_input_device/win32error.c +69 -0
- data/ext/special_input_device/win32error.h +8 -0
- data/ext/special_input_device/window.c +1108 -0
- data/lib/special_input_device/attributes_equal_checker.rb +13 -0
- data/lib/special_input_device/color.rb +156 -0
- data/lib/special_input_device/image.rb +170 -0
- data/lib/special_input_device/image/bmp.rb +89 -0
- data/lib/special_input_device/image/error/damaged_image_error.rb +4 -0
- data/lib/special_input_device/image/error/image_error.rb +3 -0
- data/lib/special_input_device/image/error/unsupported_image_format_error.rb +4 -0
- data/lib/special_input_device/key_code.rb +268 -0
- data/lib/special_input_device/point.rb +48 -0
- data/lib/special_input_device/rectangle.rb +187 -0
- data/lib/special_input_device/special_input_device.rb +67 -0
- data/lib/special_input_device/table_2d.rb +157 -0
- data/stab/keyboard.rb +35 -0
- data/stab/mouse.rb +189 -0
- data/stab/screen.rb +56 -0
- data/stab/win32_error.rb +20 -0
- data/stab/window.rb +398 -0
- metadata +85 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#include "special_input_device.h"
|
|
2
|
+
#include "color.h"
|
|
3
|
+
|
|
4
|
+
VALUE ruby___color_new(INT cRed, INT cGreen, INT cBlue) {
|
|
5
|
+
VALUE newColorArguments[3];
|
|
6
|
+
newColorArguments[0] = INT2NUM(cRed);
|
|
7
|
+
newColorArguments[1] = INT2NUM(cGreen);
|
|
8
|
+
newColorArguments[2] = INT2NUM(cBlue);
|
|
9
|
+
return rb_class_new_instance(3, newColorArguments, specialInputDevice_color);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
VALUE ruby___color_new_from_color_ref(COLORREF cColor) {
|
|
13
|
+
VALUE newColorArguments[3];
|
|
14
|
+
newColorArguments[0] = INT2NUM(GetRValue(cColor));
|
|
15
|
+
newColorArguments[1] = INT2NUM(GetGValue(cColor));
|
|
16
|
+
newColorArguments[2] = INT2NUM(GetBValue(cColor));
|
|
17
|
+
return rb_class_new_instance(3, newColorArguments, specialInputDevice_color);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
COLORREF ruby___color_to_color_ref(VALUE color) {
|
|
21
|
+
BYTE cRed = (BYTE) FIX2UINT(rb_iv_get(color, "@red"));
|
|
22
|
+
BYTE cGreen = (BYTE) FIX2UINT(rb_iv_get(color, "@green"));
|
|
23
|
+
BYTE cBlue = (BYTE) FIX2UINT(rb_iv_get(color, "@blue"));
|
|
24
|
+
return RGB(cRed, cGreen, cBlue);
|
|
25
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#ifndef SPECIAL_INPUT_DEVICE_COLOR_H
|
|
2
|
+
#define SPECIAL_INPUT_DEVICE_COLOR_H
|
|
3
|
+
|
|
4
|
+
VALUE ruby___color_new(INT cRed, INT cGreen, INT cBlue);
|
|
5
|
+
|
|
6
|
+
VALUE ruby___color_new_from_color_ref(COLORREF cColor);
|
|
7
|
+
|
|
8
|
+
COLORREF ruby___color_to_color_ref(VALUE color);
|
|
9
|
+
|
|
10
|
+
#endif //SPECIAL_INPUT_DEVICE_COLOR_H
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#include "special_input_device.h"
|
|
2
|
+
#include "_vendor__interception.h"
|
|
3
|
+
|
|
4
|
+
#define MAXIMUM_HARDWARE_IDENTIFIER_LENGTH 512
|
|
5
|
+
|
|
6
|
+
typedef struct {
|
|
7
|
+
InterceptionContext context;
|
|
8
|
+
InterceptionDevice keyboard;
|
|
9
|
+
InterceptionDevice mouse;
|
|
10
|
+
} SID_INTERCEPTION_DATA;
|
|
11
|
+
|
|
12
|
+
static SID_INTERCEPTION_DATA *cData;
|
|
13
|
+
|
|
14
|
+
inline InterceptionContext ruby___interception_get_context() {
|
|
15
|
+
return cData->context;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
InterceptionDevice ruby___interception_find_keyboard() {
|
|
19
|
+
TCHAR cHardwareIdentifier[MAXIMUM_HARDWARE_IDENTIFIER_LENGTH];
|
|
20
|
+
if (interceptionGetHardwareIdentifier(cData->context, cData->keyboard, cHardwareIdentifier,
|
|
21
|
+
MAXIMUM_HARDWARE_IDENTIFIER_LENGTH))
|
|
22
|
+
return cData->keyboard;
|
|
23
|
+
for (cData->keyboard = INTERCEPTION_KEYBOARD(0);
|
|
24
|
+
cData->keyboard < INTERCEPTION_KEYBOARD(INTERCEPTION_MAX_KEYBOARD); cData->keyboard++) {
|
|
25
|
+
if (interceptionGetHardwareIdentifier(cData->context, cData->keyboard, cHardwareIdentifier,
|
|
26
|
+
MAXIMUM_HARDWARE_IDENTIFIER_LENGTH))
|
|
27
|
+
return cData->keyboard;
|
|
28
|
+
}
|
|
29
|
+
rb_raise(rb_eRuntimeError, "Can not find any keyboard connected.");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
InterceptionDevice ruby___interception_find_mouse() {
|
|
33
|
+
TCHAR cHardwareIdentifier[MAXIMUM_HARDWARE_IDENTIFIER_LENGTH];
|
|
34
|
+
if (interceptionGetHardwareIdentifier(cData->context, cData->mouse, cHardwareIdentifier,
|
|
35
|
+
MAXIMUM_HARDWARE_IDENTIFIER_LENGTH))
|
|
36
|
+
return cData->mouse;
|
|
37
|
+
for (cData->mouse = INTERCEPTION_MOUSE(0);
|
|
38
|
+
cData->mouse < INTERCEPTION_MOUSE(INTERCEPTION_MAX_MOUSE); cData->mouse++) {
|
|
39
|
+
if (interceptionGetHardwareIdentifier(cData->context, cData->mouse, cHardwareIdentifier,
|
|
40
|
+
MAXIMUM_HARDWARE_IDENTIFIER_LENGTH))
|
|
41
|
+
return cData->mouse;
|
|
42
|
+
}
|
|
43
|
+
rb_raise(rb_eRuntimeError, "Can not find any mouse connected.");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static VOID callback_interception_free(SID_INTERCEPTION_DATA *cData) {
|
|
47
|
+
interceptionDestroyContext(cData->context);
|
|
48
|
+
free(cData);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static VALUE ruby__alloc(VALUE self) {
|
|
52
|
+
VALUE instance = Data_Make_Struct(self, SID_INTERCEPTION_DATA, NULL, callback_interception_free, cData);
|
|
53
|
+
cData->context = interceptionCreateContext();
|
|
54
|
+
return instance;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
VOID Init_interception() {
|
|
58
|
+
#ifdef YARD
|
|
59
|
+
specialInputDevice = rb_define_module("SpecialInputDevice");
|
|
60
|
+
#endif
|
|
61
|
+
VALUE singleton;
|
|
62
|
+
/*
|
|
63
|
+
* Document-module: SpecialInputDevice::Interception
|
|
64
|
+
*
|
|
65
|
+
* The <code>Interception</code> module contain some important data about interception library. Do not touch this
|
|
66
|
+
* module.
|
|
67
|
+
*/
|
|
68
|
+
VALUE specialInputDevice_interception = rb_define_class_under(specialInputDevice, "Interception", rb_cData);
|
|
69
|
+
rb_define_alloc_func(specialInputDevice_interception, (rb_alloc_func_t) ruby__alloc);
|
|
70
|
+
|
|
71
|
+
rb_require("singleton");
|
|
72
|
+
singleton = RUBY_MODULE_CONST_GET(rb_mKernel, rb_intern_const("Singleton"));
|
|
73
|
+
rb_funcall(singleton, rb_intern_const("included"), 1, specialInputDevice_interception);
|
|
74
|
+
rb_funcall(specialInputDevice_interception, rb_intern_const("instance"), 0);
|
|
75
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#include <windows.h>
|
|
2
|
+
#include "_vendor__interception.h"
|
|
3
|
+
|
|
4
|
+
#ifndef SPECIAL_INPUT_DEVICE_INTERCEPTION_H
|
|
5
|
+
#define SPECIAL_INPUT_DEVICE_INTERCEPTION_H
|
|
6
|
+
|
|
7
|
+
InterceptionContext ruby___interception_get_context();
|
|
8
|
+
|
|
9
|
+
InterceptionDevice ruby___interception_find_keyboard();
|
|
10
|
+
|
|
11
|
+
InterceptionDevice ruby___interception_find_mouse();
|
|
12
|
+
|
|
13
|
+
#endif //SPECIAL_INPUT_DEVICE_INTERCEPTION_H
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#include "special_input_device.h"
|
|
2
|
+
#include "interception_connector.h"
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* @overload hold(key_code)
|
|
6
|
+
* Simulate holding the specified key down.
|
|
7
|
+
* @param [Integer] key_code virtual key code. Use a value of constant in {SpecialInputDevice::KeyCode}.
|
|
8
|
+
* @return [Module] self
|
|
9
|
+
* @see SpecialInputDevice::Window#key_hold
|
|
10
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
11
|
+
*/
|
|
12
|
+
static VALUE ruby__hold(VALUE self, VALUE keyCode) {
|
|
13
|
+
WORD cKeyCode = NUM2USHORT(keyCode);
|
|
14
|
+
UINT cScanCode = MapVirtualKeyA(cKeyCode, MAPVK_VK_TO_VSC);
|
|
15
|
+
switch (ruby___special_input_device_get_mode_identifier()) {
|
|
16
|
+
case MODE_INTERCEPTION: {
|
|
17
|
+
InterceptionContext cContext = ruby___interception_get_context();
|
|
18
|
+
InterceptionDevice cDevice = ruby___interception_find_keyboard();
|
|
19
|
+
InterceptionKeyStroke cStroke;
|
|
20
|
+
cStroke.code = (USHORT) cScanCode;
|
|
21
|
+
cStroke.information = 0;
|
|
22
|
+
cStroke.state = INTERCEPTION_KEY_DOWN;
|
|
23
|
+
interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 1);
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
case MODE_WIN_API: {
|
|
27
|
+
INPUT cInput;
|
|
28
|
+
cInput.type = INPUT_KEYBOARD;
|
|
29
|
+
cInput.ki.dwExtraInfo = (ULONG_PTR) GetMessageExtraInfo();
|
|
30
|
+
cInput.ki.dwFlags = 0;
|
|
31
|
+
cInput.ki.time = 0;
|
|
32
|
+
cInput.ki.wScan = (WORD) cScanCode;
|
|
33
|
+
cInput.ki.wVk = cKeyCode;
|
|
34
|
+
if (SendInput(1, &cInput, sizeof(INPUT)) == 0)
|
|
35
|
+
RAISE_WIN32_ERROR;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
default: {
|
|
39
|
+
PCHAR cModeName = ruby___special_input_device_get_mode_name();
|
|
40
|
+
rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return self;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/*
|
|
47
|
+
* @overload press(key_code)
|
|
48
|
+
* Simulate pressing the specified key.
|
|
49
|
+
* @param [Integer] key_code virtual key code. Use a value of constant in {SpecialInputDevice::KeyCode}.
|
|
50
|
+
* @return [Module] self
|
|
51
|
+
* @see SpecialInputDevice::Window#key_press
|
|
52
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
53
|
+
*/
|
|
54
|
+
static VALUE ruby__press(VALUE self, VALUE keyCode) {
|
|
55
|
+
WORD cKeyCode = NUM2USHORT(keyCode);
|
|
56
|
+
UINT cScanCode = MapVirtualKeyA(cKeyCode, MAPVK_VK_TO_VSC);
|
|
57
|
+
switch (ruby___special_input_device_get_mode_identifier()) {
|
|
58
|
+
case MODE_INTERCEPTION: {
|
|
59
|
+
InterceptionContext cContext = ruby___interception_get_context();
|
|
60
|
+
InterceptionDevice cDevice = ruby___interception_find_keyboard();
|
|
61
|
+
InterceptionKeyStroke cStroke[2];
|
|
62
|
+
cStroke[0].code = (USHORT) cScanCode;
|
|
63
|
+
cStroke[0].information = 0;
|
|
64
|
+
cStroke[0].state = INTERCEPTION_KEY_DOWN;
|
|
65
|
+
cStroke[1].code = (USHORT) cScanCode;
|
|
66
|
+
cStroke[1].information = 0;
|
|
67
|
+
cStroke[1].state = INTERCEPTION_KEY_UP;
|
|
68
|
+
interceptionSend(cContext, cDevice, (InterceptionStroke const *) cStroke, 2);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case MODE_WIN_API: {
|
|
72
|
+
INPUT cInput[2];
|
|
73
|
+
cInput[0].type = INPUT_KEYBOARD;
|
|
74
|
+
cInput[0].ki.dwExtraInfo = (ULONG_PTR) GetMessageExtraInfo();
|
|
75
|
+
cInput[0].ki.dwFlags = 0;
|
|
76
|
+
cInput[0].ki.time = 0;
|
|
77
|
+
cInput[0].ki.wScan = (WORD) cScanCode;
|
|
78
|
+
cInput[0].ki.wVk = cKeyCode;
|
|
79
|
+
cInput[1].type = INPUT_KEYBOARD;
|
|
80
|
+
cInput[1].ki.dwExtraInfo = (ULONG_PTR) GetMessageExtraInfo();
|
|
81
|
+
cInput[1].ki.dwFlags = KEYEVENTF_KEYUP;
|
|
82
|
+
cInput[1].ki.time = 0;
|
|
83
|
+
cInput[1].ki.wScan = (WORD) cScanCode;
|
|
84
|
+
cInput[1].ki.wVk = cKeyCode;
|
|
85
|
+
if (SendInput(2, cInput, sizeof(INPUT)) == 0)
|
|
86
|
+
RAISE_WIN32_ERROR;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
default: {
|
|
90
|
+
PCHAR cModeName = ruby___special_input_device_get_mode_name();
|
|
91
|
+
rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return self;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/*
|
|
98
|
+
* @overload release(key_code)
|
|
99
|
+
* Simulate releasing the specified key.
|
|
100
|
+
* @param [Integer] key_code virtual key code. Use a value of constant in {SpecialInputDevice::KeyCode}.
|
|
101
|
+
* @return [Module] self
|
|
102
|
+
* @see SpecialInputDevice::Window#key_release
|
|
103
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
104
|
+
*/
|
|
105
|
+
static VALUE ruby__release(VALUE self, VALUE keyCode) {
|
|
106
|
+
WORD cKeyCode = NUM2USHORT(keyCode);
|
|
107
|
+
UINT cScanCode = MapVirtualKeyA(cKeyCode, MAPVK_VK_TO_VSC);
|
|
108
|
+
switch (ruby___special_input_device_get_mode_identifier()) {
|
|
109
|
+
case MODE_INTERCEPTION: {
|
|
110
|
+
InterceptionContext cContext = ruby___interception_get_context();
|
|
111
|
+
InterceptionDevice cDevice = ruby___interception_find_keyboard();
|
|
112
|
+
InterceptionKeyStroke cStroke;
|
|
113
|
+
cStroke.code = (USHORT) cScanCode;
|
|
114
|
+
cStroke.information = 0;
|
|
115
|
+
cStroke.state = INTERCEPTION_KEY_UP;
|
|
116
|
+
interceptionSend(cContext, cDevice, (InterceptionStroke const *) &cStroke, 2);
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
case MODE_WIN_API: {
|
|
120
|
+
INPUT cInput;
|
|
121
|
+
cInput.type = INPUT_KEYBOARD;
|
|
122
|
+
cInput.ki.dwExtraInfo = (ULONG_PTR) GetMessageExtraInfo();
|
|
123
|
+
cInput.ki.dwFlags = KEYEVENTF_KEYUP;
|
|
124
|
+
cInput.ki.time = 0;
|
|
125
|
+
cInput.ki.wScan = (WORD) cScanCode;
|
|
126
|
+
cInput.ki.wVk = cKeyCode;
|
|
127
|
+
if (SendInput(1, &cInput, sizeof(INPUT)) == 0)
|
|
128
|
+
RAISE_WIN32_ERROR;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
default: {
|
|
132
|
+
PCHAR cModeName = ruby___special_input_device_get_mode_name();
|
|
133
|
+
rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return self;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
VOID Init_keyboard() {
|
|
140
|
+
#ifdef YARD
|
|
141
|
+
specialInputDevice = rb_define_module("SpecialInputDevice");
|
|
142
|
+
#endif
|
|
143
|
+
/*
|
|
144
|
+
* Document-module: SpecialInputDevice::Keyboard
|
|
145
|
+
*
|
|
146
|
+
* The <code>Keyboard</code> module provides an interface to simulate the signal form keyboard.
|
|
147
|
+
*/
|
|
148
|
+
VALUE specialInputDevice_keyboard = rb_define_module_under(specialInputDevice, "Keyboard");
|
|
149
|
+
rb_define_singleton_method(specialInputDevice_keyboard, "hold", ruby__hold, 1);
|
|
150
|
+
rb_define_singleton_method(specialInputDevice_keyboard, "press", ruby__press, 1);
|
|
151
|
+
rb_define_singleton_method(specialInputDevice_keyboard, "release", ruby__release, 1);
|
|
152
|
+
}
|
|
@@ -0,0 +1,1137 @@
|
|
|
1
|
+
#include "special_input_device.h"
|
|
2
|
+
#include "_screen.h"
|
|
3
|
+
#include "interception_connector.h"
|
|
4
|
+
#include "point.h"
|
|
5
|
+
|
|
6
|
+
//<editor-fold desc="cursor">
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* Lock the mouse.
|
|
10
|
+
* @return [Module] self
|
|
11
|
+
*/
|
|
12
|
+
static VALUE ruby__lock(VALUE self) {
|
|
13
|
+
switch (ruby___special_input_device_get_mode_identifier()) {
|
|
14
|
+
case MODE_INTERCEPTION: {
|
|
15
|
+
InterceptionContext cContext = ruby___interception_get_context();
|
|
16
|
+
interceptionSetFilter(cContext, interceptionIsMouse, INTERCEPTION_FILTER_MOUSE_ALL);
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
case MODE_WIN_API: {
|
|
20
|
+
rb_raise(rb_eRuntimeError, "WinAPI mode does not support lock mouse function.");
|
|
21
|
+
}
|
|
22
|
+
default: {
|
|
23
|
+
PCHAR cModeName = ruby___special_input_device_get_mode_name();
|
|
24
|
+
rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return self;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/*
|
|
31
|
+
* Unlock the mouse.
|
|
32
|
+
* @return [Module] self
|
|
33
|
+
*/
|
|
34
|
+
static VALUE ruby__unlock(VALUE self) {
|
|
35
|
+
switch (ruby___special_input_device_get_mode_identifier()) {
|
|
36
|
+
case MODE_INTERCEPTION: {
|
|
37
|
+
InterceptionContext cContext = ruby___interception_get_context();
|
|
38
|
+
interceptionSetFilter(cContext, interceptionIsMouse, INTERCEPTION_FILTER_MOUSE_NONE);
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case MODE_WIN_API: {
|
|
42
|
+
rb_raise(rb_eRuntimeError, "WinAPI mode does not support lock mouse function.");
|
|
43
|
+
}
|
|
44
|
+
default: {
|
|
45
|
+
PCHAR cModeName = ruby___special_input_device_get_mode_name();
|
|
46
|
+
rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return self;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/*
|
|
53
|
+
* @return [SpecialInputDevice::Point] the point of cursor position
|
|
54
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
55
|
+
*/
|
|
56
|
+
static VALUE ruby__cursor_position(VALUE self) {
|
|
57
|
+
POINT cPoint;
|
|
58
|
+
if (!GetCursorPos(&cPoint))
|
|
59
|
+
RAISE_WIN32_ERROR;
|
|
60
|
+
return ruby___point_new_from_point(&cPoint);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/*
|
|
64
|
+
* @overload move_relatively(x, y)
|
|
65
|
+
* Move the cursor position relative to current position.
|
|
66
|
+
* @param [Integer] x the amount of horizontal motion specified as the number of pixels.
|
|
67
|
+
* @param [Integer] y the amount of vertical motion specified as the number of pixels.
|
|
68
|
+
* @return [Module] self
|
|
69
|
+
* @see SpecialInputDevice::Window#mouse_move_relatively
|
|
70
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
71
|
+
*/
|
|
72
|
+
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;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/*
|
|
111
|
+
* @overload move_to_primary(x, y)
|
|
112
|
+
* Move the cursor position relative to the upper-left corner of primary screen.
|
|
113
|
+
* @param [Integer] x the x-coordinate of position specified as the number of pixels.
|
|
114
|
+
* @param [Integer] y the y-coordinate of position specified as the number of pixels.
|
|
115
|
+
* @return [Module] self
|
|
116
|
+
* @see SpecialInputDevice::Mouse.move_to_virtual
|
|
117
|
+
* @see SpecialInputDevice::Screen.primary_screen
|
|
118
|
+
* @see SpecialInputDevice::Window#mouse_move_to
|
|
119
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
120
|
+
*/
|
|
121
|
+
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;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/*
|
|
160
|
+
* @overload move_to_virtual(x, y)
|
|
161
|
+
* Move the cursor position relative to the upper-left corner of virtual screen. If the position of virtual screen is
|
|
162
|
+
* inaccessible, the cursor will move to the closest point to the specified position.
|
|
163
|
+
* @param [Integer] x the x-coordinate of position specified as the number of pixels.
|
|
164
|
+
* @param [Integer] y the y-coordinate of position specified as the number of pixels.
|
|
165
|
+
* @return [Module] self
|
|
166
|
+
* @see SpecialInputDevice::Mouse.move_to_primary
|
|
167
|
+
* @see SpecialInputDevice::Screen.virtual_screen
|
|
168
|
+
* @see SpecialInputDevice::Window#mouse_move_to
|
|
169
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
170
|
+
*/
|
|
171
|
+
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;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
//</editor-fold>
|
|
210
|
+
|
|
211
|
+
//<editor-fold desc="left_button">
|
|
212
|
+
|
|
213
|
+
/*
|
|
214
|
+
* Simulate clicking the left button on the mouse.
|
|
215
|
+
* @return [Module] self
|
|
216
|
+
* @see SpecialInputDevice::Window#mouse_left_click
|
|
217
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
218
|
+
*/
|
|
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;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/*
|
|
269
|
+
* Simulate holding the left button on the mouse down.
|
|
270
|
+
* @return [Module] self
|
|
271
|
+
* @see SpecialInputDevice::Window#mouse_left_down
|
|
272
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
273
|
+
*/
|
|
274
|
+
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;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/*
|
|
311
|
+
* Simulate releasing the left button on the mouse.
|
|
312
|
+
* @return [Module] self
|
|
313
|
+
* @see SpecialInputDevice::Window#mouse_left_up
|
|
314
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
315
|
+
*/
|
|
316
|
+
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;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
//</editor-fold>
|
|
353
|
+
|
|
354
|
+
//<editor-fold desc="right_button">
|
|
355
|
+
|
|
356
|
+
/*
|
|
357
|
+
* Simulate clicking the right button on the mouse.
|
|
358
|
+
* @return [Module] self
|
|
359
|
+
* @see SpecialInputDevice::Window#mouse_right_click
|
|
360
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
361
|
+
*/
|
|
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;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/*
|
|
412
|
+
* Simulate holding the right button on the mouse down.
|
|
413
|
+
* @return [Module] self
|
|
414
|
+
* @see SpecialInputDevice::Window#mouse_right_down
|
|
415
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
416
|
+
*/
|
|
417
|
+
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;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/*
|
|
454
|
+
* Simulate releasing the right button on the mouse.
|
|
455
|
+
* @return [Module] self
|
|
456
|
+
* @see SpecialInputDevice::Window#mouse_right_up
|
|
457
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
458
|
+
*/
|
|
459
|
+
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;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
//</editor-fold>
|
|
496
|
+
|
|
497
|
+
//<editor-fold desc="middle_button">
|
|
498
|
+
|
|
499
|
+
/*
|
|
500
|
+
* Simulate clicking the middle button on the mouse.
|
|
501
|
+
* @return [Module] self
|
|
502
|
+
* @see SpecialInputDevice::Window#mouse_middle_click
|
|
503
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
504
|
+
*/
|
|
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;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/*
|
|
555
|
+
* Simulate holding the middle button on the mouse down.
|
|
556
|
+
* @return [Module] self
|
|
557
|
+
* @see SpecialInputDevice::Window#mouse_middle_down
|
|
558
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
559
|
+
*/
|
|
560
|
+
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;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/*
|
|
597
|
+
* Simulate releasing the middle button on the mouse.
|
|
598
|
+
* @return [Module] self
|
|
599
|
+
* @see SpecialInputDevice::Window#mouse_middle_up
|
|
600
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
601
|
+
*/
|
|
602
|
+
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;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
//</editor-fold>
|
|
639
|
+
|
|
640
|
+
//<editor-fold desc="x_button">
|
|
641
|
+
|
|
642
|
+
/*
|
|
643
|
+
* Simulate clicking the x1 button on the mouse.
|
|
644
|
+
* @return [Module] self
|
|
645
|
+
* @see SpecialInputDevice::Window#mouse_x1_click
|
|
646
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
647
|
+
*/
|
|
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;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/*
|
|
698
|
+
* Simulate holding the x1 button on the mouse down.
|
|
699
|
+
* @return [Module] self
|
|
700
|
+
* @see SpecialInputDevice::Window#mouse_x1_down
|
|
701
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
702
|
+
*/
|
|
703
|
+
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;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/*
|
|
740
|
+
* Simulate releasing the x1 button on the mouse.
|
|
741
|
+
* @return [Module] self
|
|
742
|
+
* @see SpecialInputDevice::Window#mouse_x1_up
|
|
743
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
744
|
+
*/
|
|
745
|
+
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;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
/*
|
|
782
|
+
* Simulate clicking the x2 button on the mouse.
|
|
783
|
+
* @return [Module] self
|
|
784
|
+
* @see SpecialInputDevice::Window#mouse_x2_click
|
|
785
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
786
|
+
*/
|
|
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;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/*
|
|
837
|
+
* Simulate holding the x2 button on the mouse down.
|
|
838
|
+
* @return [Module] self
|
|
839
|
+
* @see SpecialInputDevice::Window#mouse_x2_down
|
|
840
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
841
|
+
*/
|
|
842
|
+
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;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
/*
|
|
879
|
+
* Simulate releasing the x2 button on the mouse.
|
|
880
|
+
* @return [Module] self
|
|
881
|
+
* @see SpecialInputDevice::Window#mouse_x2_up
|
|
882
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
883
|
+
*/
|
|
884
|
+
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;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
//</editor-fold>
|
|
921
|
+
|
|
922
|
+
//<editor-fold desc="wheel">
|
|
923
|
+
|
|
924
|
+
/*
|
|
925
|
+
* Simulate wheeling the scroll backward.
|
|
926
|
+
* @return [Module] self
|
|
927
|
+
* @see SpecialInputDevice::Window#mouse_scroll_wheel_backward
|
|
928
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
929
|
+
*/
|
|
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;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
/*
|
|
967
|
+
* Simulate wheeling the scroll forward.
|
|
968
|
+
* @return [Module] self
|
|
969
|
+
* @see SpecialInputDevice::Window#mouse_scroll_wheel_forward
|
|
970
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
971
|
+
*/
|
|
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;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
/*
|
|
1009
|
+
* Simulate wheeling the scroll to left hand side.
|
|
1010
|
+
* @return [Module] self
|
|
1011
|
+
* @see SpecialInputDevice::Window#mouse_scroll_wheel_to_left
|
|
1012
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
1013
|
+
*/
|
|
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
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
/*
|
|
1055
|
+
* Simulate wheeling the scroll to right hand side.
|
|
1056
|
+
* @return [Module] self
|
|
1057
|
+
* @see SpecialInputDevice::Window#mouse_scroll_wheel_to_right
|
|
1058
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx Windows Dev Center - SendInput function
|
|
1059
|
+
*/
|
|
1060
|
+
static VALUE ruby__scroll_wheel_to_right(VALUE self) {
|
|
1061
|
+
#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;
|
|
1095
|
+
#else
|
|
1096
|
+
rb_raise(rb_eRuntimeError, "Error! Your system not support horizontal wheel.");
|
|
1097
|
+
#endif
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
//</editor-fold>
|
|
1101
|
+
|
|
1102
|
+
VOID Init_mouse() {
|
|
1103
|
+
#ifdef YARD
|
|
1104
|
+
specialInputDevice = rb_define_module("SpecialInputDevice");
|
|
1105
|
+
#endif
|
|
1106
|
+
/*
|
|
1107
|
+
* Document-module: SpecialInputDevice::Mouse
|
|
1108
|
+
*
|
|
1109
|
+
* The <code>Mouse</code> module provides an interface to simulate the signal form mouse.
|
|
1110
|
+
*/
|
|
1111
|
+
VALUE specialInputDevice_mouse = rb_define_module_under(specialInputDevice, "Mouse");
|
|
1112
|
+
rb_define_singleton_method(specialInputDevice_mouse, "lock", ruby__lock, 0);
|
|
1113
|
+
rb_define_singleton_method(specialInputDevice_mouse, "unlock", ruby__unlock, 0);
|
|
1114
|
+
rb_define_singleton_method(specialInputDevice_mouse, "cursor_position", ruby__cursor_position, 0);
|
|
1115
|
+
rb_define_singleton_method(specialInputDevice_mouse, "move_relatively", ruby__move_relatively, 2);
|
|
1116
|
+
rb_define_singleton_method(specialInputDevice_mouse, "move_to_primary", ruby__move_to_primary, 2);
|
|
1117
|
+
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);
|
|
1119
|
+
rb_define_singleton_method(specialInputDevice_mouse, "left_down", ruby__left_down, 0);
|
|
1120
|
+
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);
|
|
1122
|
+
rb_define_singleton_method(specialInputDevice_mouse, "right_down", ruby__right_down, 0);
|
|
1123
|
+
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);
|
|
1125
|
+
rb_define_singleton_method(specialInputDevice_mouse, "middle_down", ruby__middle_down, 0);
|
|
1126
|
+
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);
|
|
1128
|
+
rb_define_singleton_method(specialInputDevice_mouse, "x1_down", ruby__x1_down, 0);
|
|
1129
|
+
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);
|
|
1131
|
+
rb_define_singleton_method(specialInputDevice_mouse, "x2_down", ruby__x2_down, 0);
|
|
1132
|
+
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);
|
|
1137
|
+
}
|