special_input_device 0.0.0 → 0.0.1
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 +4 -4
- data/ext/special_input_device/color.c +25 -6
- data/ext/special_input_device/color.h +5 -1
- data/ext/special_input_device/extconf.rb +2 -2
- data/ext/special_input_device/image.c +728 -0
- data/ext/special_input_device/image.h +8 -0
- data/ext/special_input_device/{interception_connector.c → interception.c} +7 -3
- data/ext/special_input_device/{interception_connector.h → interception.h} +0 -0
- data/ext/special_input_device/keyboard.c +4 -4
- data/ext/special_input_device/mouse.c +26 -28
- data/ext/special_input_device/ruby_macro.h +11 -3
- data/ext/special_input_device/screen.c +54 -164
- data/ext/special_input_device/special_input_device.c +2 -2
- data/ext/special_input_device/special_input_device.h +2 -1
- data/ext/special_input_device/win32error.c +0 -2
- data/ext/special_input_device/window.c +82 -105
- data/lib/special_input_device/color.rb +2 -3
- data/lib/special_input_device/image.rb +2 -61
- data/lib/special_input_device/point.rb +0 -1
- data/lib/special_input_device/special_input_device.rb +0 -1
- metadata +7 -15
- data/lib/special_input_device/image/bmp.rb +0 -89
- data/lib/special_input_device/image/error/damaged_image_error.rb +0 -4
- data/lib/special_input_device/image/error/image_error.rb +0 -3
- data/lib/special_input_device/image/error/unsupported_image_format_error.rb +0 -4
- data/lib/special_input_device/table_2d.rb +0 -157
- data/stab/keyboard.rb +0 -35
- data/stab/mouse.rb +0 -189
- data/stab/screen.rb +0 -56
- data/stab/win32_error.rb +0 -20
- data/stab/window.rb +0 -398
|
@@ -26,7 +26,9 @@ InterceptionDevice ruby___interception_find_keyboard() {
|
|
|
26
26
|
MAXIMUM_HARDWARE_IDENTIFIER_LENGTH))
|
|
27
27
|
return cData->keyboard;
|
|
28
28
|
}
|
|
29
|
-
rb_raise(rb_eRuntimeError, "Can not find any keyboard connected."
|
|
29
|
+
rb_raise(rb_eRuntimeError, "Can not find any keyboard connected. Make sure you have at least one keyboard connected"
|
|
30
|
+
" and interception driver has been installed. Otherwise, you may try to use other mode instead of"
|
|
31
|
+
" interception mode.");
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
InterceptionDevice ruby___interception_find_mouse() {
|
|
@@ -40,12 +42,14 @@ InterceptionDevice ruby___interception_find_mouse() {
|
|
|
40
42
|
MAXIMUM_HARDWARE_IDENTIFIER_LENGTH))
|
|
41
43
|
return cData->mouse;
|
|
42
44
|
}
|
|
43
|
-
rb_raise(rb_eRuntimeError, "Can not find any mouse connected."
|
|
45
|
+
rb_raise(rb_eRuntimeError, "Can not find any mouse connected. Make sure you have at least one keyboard connected"
|
|
46
|
+
" and interception driver has been installed. Otherwise, you may try to use other mode instead of"
|
|
47
|
+
" interception mode.");
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
static VOID callback_interception_free(SID_INTERCEPTION_DATA *cData) {
|
|
47
51
|
interceptionDestroyContext(cData->context);
|
|
48
|
-
|
|
52
|
+
xfree(cData);
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
static VALUE ruby__alloc(VALUE self) {
|
|
File without changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#include "special_input_device.h"
|
|
2
|
-
#include "
|
|
2
|
+
#include "interception.h"
|
|
3
3
|
|
|
4
4
|
/*
|
|
5
5
|
* @overload hold(key_code)
|
|
@@ -32,7 +32,7 @@ static VALUE ruby__hold(VALUE self, VALUE keyCode) {
|
|
|
32
32
|
cInput.ki.wScan = (WORD) cScanCode;
|
|
33
33
|
cInput.ki.wVk = cKeyCode;
|
|
34
34
|
if (SendInput(1, &cInput, sizeof(INPUT)) == 0)
|
|
35
|
-
RAISE_WIN32_ERROR;
|
|
35
|
+
RAISE_WIN32_ERROR();
|
|
36
36
|
break;
|
|
37
37
|
}
|
|
38
38
|
default: {
|
|
@@ -83,7 +83,7 @@ static VALUE ruby__press(VALUE self, VALUE keyCode) {
|
|
|
83
83
|
cInput[1].ki.wScan = (WORD) cScanCode;
|
|
84
84
|
cInput[1].ki.wVk = cKeyCode;
|
|
85
85
|
if (SendInput(2, cInput, sizeof(INPUT)) == 0)
|
|
86
|
-
RAISE_WIN32_ERROR;
|
|
86
|
+
RAISE_WIN32_ERROR();
|
|
87
87
|
break;
|
|
88
88
|
}
|
|
89
89
|
default: {
|
|
@@ -125,7 +125,7 @@ static VALUE ruby__release(VALUE self, VALUE keyCode) {
|
|
|
125
125
|
cInput.ki.wScan = (WORD) cScanCode;
|
|
126
126
|
cInput.ki.wVk = cKeyCode;
|
|
127
127
|
if (SendInput(1, &cInput, sizeof(INPUT)) == 0)
|
|
128
|
-
RAISE_WIN32_ERROR;
|
|
128
|
+
RAISE_WIN32_ERROR();
|
|
129
129
|
break;
|
|
130
130
|
}
|
|
131
131
|
default: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#include "special_input_device.h"
|
|
2
2
|
#include "_screen.h"
|
|
3
|
-
#include "
|
|
3
|
+
#include "interception.h"
|
|
4
4
|
#include "point.h"
|
|
5
5
|
|
|
6
6
|
//<editor-fold desc="cursor">
|
|
@@ -16,9 +16,8 @@ static VALUE ruby__lock(VALUE self) {
|
|
|
16
16
|
interceptionSetFilter(cContext, interceptionIsMouse, INTERCEPTION_FILTER_MOUSE_ALL);
|
|
17
17
|
break;
|
|
18
18
|
}
|
|
19
|
-
case MODE_WIN_API:
|
|
19
|
+
case MODE_WIN_API:
|
|
20
20
|
rb_raise(rb_eRuntimeError, "WinAPI mode does not support lock mouse function.");
|
|
21
|
-
}
|
|
22
21
|
default: {
|
|
23
22
|
PCHAR cModeName = ruby___special_input_device_get_mode_name();
|
|
24
23
|
rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
|
|
@@ -38,9 +37,8 @@ static VALUE ruby__unlock(VALUE self) {
|
|
|
38
37
|
interceptionSetFilter(cContext, interceptionIsMouse, INTERCEPTION_FILTER_MOUSE_NONE);
|
|
39
38
|
break;
|
|
40
39
|
}
|
|
41
|
-
case MODE_WIN_API:
|
|
40
|
+
case MODE_WIN_API:
|
|
42
41
|
rb_raise(rb_eRuntimeError, "WinAPI mode does not support lock mouse function.");
|
|
43
|
-
}
|
|
44
42
|
default: {
|
|
45
43
|
PCHAR cModeName = ruby___special_input_device_get_mode_name();
|
|
46
44
|
rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
|
|
@@ -56,7 +54,7 @@ static VALUE ruby__unlock(VALUE self) {
|
|
|
56
54
|
static VALUE ruby__cursor_position(VALUE self) {
|
|
57
55
|
POINT cPoint;
|
|
58
56
|
if (!GetCursorPos(&cPoint))
|
|
59
|
-
RAISE_WIN32_ERROR;
|
|
57
|
+
RAISE_WIN32_ERROR();
|
|
60
58
|
return ruby___point_new_from_point(&cPoint);
|
|
61
59
|
}
|
|
62
60
|
|
|
@@ -96,7 +94,7 @@ static VALUE ruby__move_relatively(VALUE self, VALUE x, VALUE y) {
|
|
|
96
94
|
input.mi.mouseData = 0;
|
|
97
95
|
input.mi.time = 0;
|
|
98
96
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
99
|
-
RAISE_WIN32_ERROR;
|
|
97
|
+
RAISE_WIN32_ERROR();
|
|
100
98
|
break;
|
|
101
99
|
}
|
|
102
100
|
default: {
|
|
@@ -145,7 +143,7 @@ static VALUE ruby__move_to_primary(VALUE self, VALUE x, VALUE y) {
|
|
|
145
143
|
input.mi.mouseData = 0;
|
|
146
144
|
input.mi.time = 0;
|
|
147
145
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
148
|
-
RAISE_WIN32_ERROR;
|
|
146
|
+
RAISE_WIN32_ERROR();
|
|
149
147
|
break;
|
|
150
148
|
}
|
|
151
149
|
default: {
|
|
@@ -195,7 +193,7 @@ static VALUE ruby__move_to_virtual(VALUE self, VALUE x, VALUE y) {
|
|
|
195
193
|
input.mi.mouseData = 0;
|
|
196
194
|
input.mi.time = 0;
|
|
197
195
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
198
|
-
RAISE_WIN32_ERROR;
|
|
196
|
+
RAISE_WIN32_ERROR();
|
|
199
197
|
break;
|
|
200
198
|
}
|
|
201
199
|
default: {
|
|
@@ -254,7 +252,7 @@ static VALUE ruby__left_click(VALUE self) {
|
|
|
254
252
|
input[1].mi.mouseData = 0;
|
|
255
253
|
input[1].mi.time = 0;
|
|
256
254
|
if (SendInput(2, input, sizeof(INPUT)) == 0)
|
|
257
|
-
RAISE_WIN32_ERROR;
|
|
255
|
+
RAISE_WIN32_ERROR();
|
|
258
256
|
break;
|
|
259
257
|
}
|
|
260
258
|
default: {
|
|
@@ -296,7 +294,7 @@ static VALUE ruby__left_down(VALUE self) {
|
|
|
296
294
|
input.mi.mouseData = 0;
|
|
297
295
|
input.mi.time = 0;
|
|
298
296
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
299
|
-
RAISE_WIN32_ERROR;
|
|
297
|
+
RAISE_WIN32_ERROR();
|
|
300
298
|
break;
|
|
301
299
|
}
|
|
302
300
|
default: {
|
|
@@ -338,7 +336,7 @@ static VALUE ruby__left_up(VALUE self) {
|
|
|
338
336
|
input.mi.mouseData = 0;
|
|
339
337
|
input.mi.time = 0;
|
|
340
338
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
341
|
-
RAISE_WIN32_ERROR;
|
|
339
|
+
RAISE_WIN32_ERROR();
|
|
342
340
|
break;
|
|
343
341
|
}
|
|
344
342
|
default: {
|
|
@@ -397,7 +395,7 @@ static VALUE ruby__right_click(VALUE self) {
|
|
|
397
395
|
input[1].mi.mouseData = 0;
|
|
398
396
|
input[1].mi.time = 0;
|
|
399
397
|
if (SendInput(2, input, sizeof(INPUT)) == 0)
|
|
400
|
-
RAISE_WIN32_ERROR;
|
|
398
|
+
RAISE_WIN32_ERROR();
|
|
401
399
|
break;
|
|
402
400
|
}
|
|
403
401
|
default: {
|
|
@@ -439,7 +437,7 @@ static VALUE ruby__right_down(VALUE self) {
|
|
|
439
437
|
input.mi.mouseData = 0;
|
|
440
438
|
input.mi.time = 0;
|
|
441
439
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
442
|
-
RAISE_WIN32_ERROR;
|
|
440
|
+
RAISE_WIN32_ERROR();
|
|
443
441
|
break;
|
|
444
442
|
}
|
|
445
443
|
default: {
|
|
@@ -481,7 +479,7 @@ static VALUE ruby__right_up(VALUE self) {
|
|
|
481
479
|
input.mi.mouseData = 0;
|
|
482
480
|
input.mi.time = 0;
|
|
483
481
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
484
|
-
RAISE_WIN32_ERROR;
|
|
482
|
+
RAISE_WIN32_ERROR();
|
|
485
483
|
break;
|
|
486
484
|
}
|
|
487
485
|
default: {
|
|
@@ -540,7 +538,7 @@ static VALUE ruby__middle_click(VALUE self) {
|
|
|
540
538
|
input[1].mi.mouseData = 0;
|
|
541
539
|
input[1].mi.time = 0;
|
|
542
540
|
if (SendInput(2, input, sizeof(INPUT)) == 0)
|
|
543
|
-
RAISE_WIN32_ERROR;
|
|
541
|
+
RAISE_WIN32_ERROR();
|
|
544
542
|
break;
|
|
545
543
|
}
|
|
546
544
|
default: {
|
|
@@ -582,7 +580,7 @@ static VALUE ruby__middle_down(VALUE self) {
|
|
|
582
580
|
input.mi.mouseData = 0;
|
|
583
581
|
input.mi.time = 0;
|
|
584
582
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
585
|
-
RAISE_WIN32_ERROR;
|
|
583
|
+
RAISE_WIN32_ERROR();
|
|
586
584
|
break;
|
|
587
585
|
}
|
|
588
586
|
default: {
|
|
@@ -624,7 +622,7 @@ static VALUE ruby__middle_up(VALUE self) {
|
|
|
624
622
|
input.mi.mouseData = 0;
|
|
625
623
|
input.mi.time = 0;
|
|
626
624
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
627
|
-
RAISE_WIN32_ERROR;
|
|
625
|
+
RAISE_WIN32_ERROR();
|
|
628
626
|
break;
|
|
629
627
|
}
|
|
630
628
|
default: {
|
|
@@ -683,7 +681,7 @@ static VALUE ruby__x1_click(VALUE self) {
|
|
|
683
681
|
input[1].mi.mouseData = XBUTTON1;
|
|
684
682
|
input[1].mi.time = 0;
|
|
685
683
|
if (SendInput(2, input, sizeof(INPUT)) == 0)
|
|
686
|
-
RAISE_WIN32_ERROR;
|
|
684
|
+
RAISE_WIN32_ERROR();
|
|
687
685
|
break;
|
|
688
686
|
}
|
|
689
687
|
default: {
|
|
@@ -725,7 +723,7 @@ static VALUE ruby__x1_down(VALUE self) {
|
|
|
725
723
|
input.mi.mouseData = XBUTTON1;
|
|
726
724
|
input.mi.time = 0;
|
|
727
725
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
728
|
-
RAISE_WIN32_ERROR;
|
|
726
|
+
RAISE_WIN32_ERROR();
|
|
729
727
|
break;
|
|
730
728
|
}
|
|
731
729
|
default: {
|
|
@@ -767,7 +765,7 @@ static VALUE ruby__x1_up(VALUE self) {
|
|
|
767
765
|
input.mi.mouseData = XBUTTON1;
|
|
768
766
|
input.mi.time = 0;
|
|
769
767
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
770
|
-
RAISE_WIN32_ERROR;
|
|
768
|
+
RAISE_WIN32_ERROR();
|
|
771
769
|
break;
|
|
772
770
|
}
|
|
773
771
|
default: {
|
|
@@ -822,7 +820,7 @@ static VALUE ruby__x2_click(VALUE self) {
|
|
|
822
820
|
input[1].mi.mouseData = XBUTTON2;
|
|
823
821
|
input[1].mi.time = 0;
|
|
824
822
|
if (SendInput(2, input, sizeof(INPUT)) == 0)
|
|
825
|
-
RAISE_WIN32_ERROR;
|
|
823
|
+
RAISE_WIN32_ERROR();
|
|
826
824
|
break;
|
|
827
825
|
}
|
|
828
826
|
default: {
|
|
@@ -864,7 +862,7 @@ static VALUE ruby__x2_down(VALUE self) {
|
|
|
864
862
|
input.mi.mouseData = XBUTTON2;
|
|
865
863
|
input.mi.time = 0;
|
|
866
864
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
867
|
-
RAISE_WIN32_ERROR;
|
|
865
|
+
RAISE_WIN32_ERROR();
|
|
868
866
|
break;
|
|
869
867
|
}
|
|
870
868
|
default: {
|
|
@@ -906,7 +904,7 @@ static VALUE ruby__x2_up(VALUE self) {
|
|
|
906
904
|
input.mi.mouseData = XBUTTON2;
|
|
907
905
|
input.mi.time = 0;
|
|
908
906
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
909
|
-
RAISE_WIN32_ERROR;
|
|
907
|
+
RAISE_WIN32_ERROR();
|
|
910
908
|
break;
|
|
911
909
|
}
|
|
912
910
|
default: {
|
|
@@ -952,7 +950,7 @@ static VALUE ruby__scroll_wheel_backward(VALUE self) {
|
|
|
952
950
|
input.mi.mouseData = (DWORD) -WHEEL_DELTA;
|
|
953
951
|
input.mi.time = 0;
|
|
954
952
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
955
|
-
RAISE_WIN32_ERROR;
|
|
953
|
+
RAISE_WIN32_ERROR();
|
|
956
954
|
break;
|
|
957
955
|
}
|
|
958
956
|
default: {
|
|
@@ -994,7 +992,7 @@ static VALUE ruby__scroll_wheel_forward(VALUE self) {
|
|
|
994
992
|
input.mi.mouseData = WHEEL_DELTA;
|
|
995
993
|
input.mi.time = 0;
|
|
996
994
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
997
|
-
RAISE_WIN32_ERROR;
|
|
995
|
+
RAISE_WIN32_ERROR();
|
|
998
996
|
break;
|
|
999
997
|
}
|
|
1000
998
|
default: {
|
|
@@ -1037,7 +1035,7 @@ static VALUE ruby__scroll_wheel_to_left(VALUE self) {
|
|
|
1037
1035
|
input.mi.mouseData = (DWORD) -WHEEL_DELTA;
|
|
1038
1036
|
input.mi.time = 0;
|
|
1039
1037
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
1040
|
-
RAISE_WIN32_ERROR;
|
|
1038
|
+
RAISE_WIN32_ERROR();
|
|
1041
1039
|
break;
|
|
1042
1040
|
}
|
|
1043
1041
|
default: {
|
|
@@ -1083,7 +1081,7 @@ static VALUE ruby__scroll_wheel_to_right(VALUE self) {
|
|
|
1083
1081
|
input.mi.mouseData = WHEEL_DELTA;
|
|
1084
1082
|
input.mi.time = 0;
|
|
1085
1083
|
if (SendInput(1, &input, sizeof(INPUT)) == 0)
|
|
1086
|
-
RAISE_WIN32_ERROR;
|
|
1084
|
+
RAISE_WIN32_ERROR();
|
|
1087
1085
|
break;
|
|
1088
1086
|
}
|
|
1089
1087
|
default: {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// Hide error messages in CLion
|
|
7
7
|
#ifdef CLION
|
|
8
8
|
|
|
9
|
-
NORETURN(
|
|
9
|
+
NORETURN(VOID _RUBY_KERNEL_RAISE();)
|
|
10
10
|
|
|
11
11
|
# define RUBY_KERNEL_RAISE(exception) \
|
|
12
12
|
(rb_funcall(rb_mKernel, rb_intern_const("raise"), 1, exception), _RUBY_KERNEL_RAISE())
|
|
@@ -56,14 +56,22 @@ VALUE __ruby_string_converter_temp_variable;
|
|
|
56
56
|
StringValueCStr(string)
|
|
57
57
|
#endif
|
|
58
58
|
|
|
59
|
+
// C Data
|
|
59
60
|
#define NEW_DATA_OBJECT(_class, data_type, mark, free) \
|
|
60
61
|
rb_data_object_zalloc((_class), sizeof(data_type), (RUBY_DATA_FUNC)(mark), (RUBY_DATA_FUNC)(free))
|
|
61
62
|
#define NEW_SIMPLE_DATA_OBJECT(_class, data_type) NEW_DATA_OBJECT(_class, data_type, NULL, RUBY_DEFAULT_FREE)
|
|
63
|
+
#define GET_DATA_OBJECT(instance) rb_data_object_get(instance)
|
|
64
|
+
#define GET_SELF_DATA_OBJECT() rb_data_object_get(self)
|
|
62
65
|
|
|
66
|
+
// Console output
|
|
63
67
|
#define RUBY_KERNEL_P(object) rb_funcall(rb_mKernel, rb_intern_const("p"), 1, object)
|
|
64
68
|
#define RUBY_KERNEL_PUTS(object) rb_funcall(rb_mKernel, rb_intern_const("puts"), 1, object)
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
// Symbol
|
|
71
|
+
#define NEW_SYMBOL(symbol) rb_id2sym(rb_intern_const(symbol))
|
|
72
|
+
|
|
73
|
+
// Exception
|
|
74
|
+
#define RAISE_WIN32_ERROR() RUBY_KERNEL_RAISE(ruby___win32error_new())
|
|
67
75
|
#define RAISE_WIN32_ERROR_FROM_CODE(code) RUBY_KERNEL_RAISE(ruby___win32error_new_from_code(code))
|
|
68
76
|
#define RAISE_ARGUMENT_ERROR(expected) \
|
|
69
77
|
rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected %s)", cCount, expected)
|
|
@@ -75,10 +83,10 @@ VALUE __ruby_string_converter_temp_variable;
|
|
|
75
83
|
RAISE_TYPE_ERROR(object, rb_class2name(expected));\
|
|
76
84
|
})
|
|
77
85
|
|
|
86
|
+
// Arguments
|
|
78
87
|
#define VARIABLE_ARGUMENTS_C INT cCount, VALUE* cArguments, VALUE self
|
|
79
88
|
#define VARIABLE_ARGUMENTS_RUBY VALUE self, VALUE arguments
|
|
80
89
|
#define SCAN_ARGUMENTS(format, arguments...) rb_scan_args(cCount, cArguments, format, arguments)
|
|
81
|
-
|
|
82
90
|
#define ARGUMENT_AT(index, defaultValue) cCount > index ? cArguments[index] : defaultValue
|
|
83
91
|
|
|
84
92
|
#endif //SPECIAL_INPUT_DEVICE_RUBY_MACRO_H
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#include "special_input_device.h"
|
|
2
2
|
#include "_screen.h"
|
|
3
3
|
#include "color.h"
|
|
4
|
+
#include "image.h"
|
|
4
5
|
#include "rectangle.h"
|
|
5
6
|
|
|
6
7
|
/*
|
|
@@ -41,146 +42,38 @@ static VALUE ruby__virtual_screen(VALUE self) {
|
|
|
41
42
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/dd144909.aspx Windows Dev Center - GetPixel function
|
|
42
43
|
*/
|
|
43
44
|
static VALUE ruby__color_at(VALUE self, VALUE x, VALUE y) {
|
|
44
|
-
INT cX
|
|
45
|
-
INT cY
|
|
46
|
-
HDC
|
|
47
|
-
COLORREF cColor
|
|
48
|
-
ReleaseDC(NULL,
|
|
45
|
+
INT cX = NUM2INT(x);
|
|
46
|
+
INT cY = NUM2INT(y);
|
|
47
|
+
HDC cScreenDC = GetDC(NULL);
|
|
48
|
+
COLORREF cColor = GetPixel(cScreenDC, cX, cY);
|
|
49
|
+
ReleaseDC(NULL, cScreenDC);
|
|
49
50
|
return ruby___color_new_from_color_ref(cColor);
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
typedef struct {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
static VALUE ruby__capture_helper_protect(VALUE arguments) {
|
|
77
|
-
VALUE bmpClass;
|
|
78
|
-
VALUE pipesEncoding = rb_str_new_cstr("ASCII-8BIT");
|
|
79
|
-
VALUE pipes;
|
|
80
|
-
VALUE pipeIn;
|
|
81
|
-
VALUE pipeOut;
|
|
82
|
-
|
|
83
|
-
SID_SCREEN_CAPTURE_PARAMETER_PROTECT *cParameterProtect;
|
|
84
|
-
SID_SCREEN_CAPTURE_PARAMETER_THREAD cParameterThread;
|
|
85
|
-
|
|
86
|
-
WORD cBitPerPixel;
|
|
87
|
-
DWORD cPaletteSize;
|
|
88
|
-
DWORD cDataSize;
|
|
89
|
-
DWORD cFileSize;
|
|
90
|
-
BITMAP cBitmap;
|
|
91
|
-
HBITMAP cHBitmap;
|
|
92
|
-
BITMAPFILEHEADER cFileHeader;
|
|
93
|
-
BITMAPINFOHEADER cInfoHeader;
|
|
94
|
-
LPBITMAPFILEHEADER cPFileHeader;
|
|
95
|
-
LPBITMAPINFOHEADER cPInfoHeader;
|
|
96
|
-
LPSTR cPPalette;
|
|
97
|
-
LPSTR cPData;
|
|
98
|
-
HPALETTE cPalette = GetStockObject(DEFAULT_PALETTE);
|
|
99
|
-
HPALETTE cOldPalette = NULL;
|
|
100
|
-
|
|
101
|
-
Data_Get_Struct(arguments, SID_SCREEN_CAPTURE_PARAMETER_PROTECT, cParameterProtect);
|
|
102
|
-
|
|
103
|
-
cParameterProtect->cCompatibleDC = CreateCompatibleDC(NULL);
|
|
104
|
-
cParameterProtect->cHDC = GetDC(NULL);
|
|
105
|
-
cHBitmap = CreateCompatibleBitmap(cParameterProtect->cHDC, cParameterProtect->cWidth, cParameterProtect->cHeight);
|
|
106
|
-
|
|
107
|
-
SelectObject(cParameterProtect->cCompatibleDC, cHBitmap);
|
|
108
|
-
BitBlt(cParameterProtect->cCompatibleDC, 0, 0, cParameterProtect->cWidth, cParameterProtect->cHeight,
|
|
109
|
-
cParameterProtect->cHDC, cParameterProtect->cX, cParameterProtect->cY, SRCCOPY);
|
|
110
|
-
GetObject(cHBitmap, sizeof(BITMAP), (LPSTR) &cBitmap);
|
|
111
|
-
|
|
112
|
-
cBitPerPixel = (WORD) (GetDeviceCaps(cParameterProtect->cHDC, BITSPIXEL) *
|
|
113
|
-
GetDeviceCaps(cParameterProtect->cHDC, PLANES));
|
|
114
|
-
if (cBitPerPixel <= 1)
|
|
115
|
-
cBitPerPixel = 1;
|
|
116
|
-
else if (cBitPerPixel <= 4)
|
|
117
|
-
cBitPerPixel = 4;
|
|
118
|
-
else if (cBitPerPixel <= 8)
|
|
119
|
-
cBitPerPixel = 8;
|
|
120
|
-
else if (cBitPerPixel <= 24)
|
|
121
|
-
cBitPerPixel = 24;
|
|
122
|
-
else
|
|
123
|
-
cBitPerPixel = 32;
|
|
124
|
-
|
|
125
|
-
cPaletteSize = cBitPerPixel <= 8 ? (1 << cBitPerPixel) * sizeof(RGBQUAD) : 0;
|
|
126
|
-
cDataSize = (DWORD) (((cBitmap.bmWidth * cBitPerPixel + 31) / 32) * 4 * cBitmap.bmHeight);
|
|
127
|
-
cFileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + cPaletteSize + cDataSize;
|
|
128
|
-
|
|
129
|
-
cFileHeader.bfType = 0x4D42;
|
|
130
|
-
cFileHeader.bfSize = cFileSize;
|
|
131
|
-
cFileHeader.bfReserved1 = 0;
|
|
132
|
-
cFileHeader.bfReserved2 = 0;
|
|
133
|
-
cFileHeader.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + (DWORD) sizeof(BITMAPINFOHEADER) + cPaletteSize;
|
|
134
|
-
|
|
135
|
-
cInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
136
|
-
cInfoHeader.biWidth = cBitmap.bmWidth;
|
|
137
|
-
cInfoHeader.biHeight = cBitmap.bmHeight;
|
|
138
|
-
cInfoHeader.biPlanes = 1;
|
|
139
|
-
cInfoHeader.biBitCount = cBitPerPixel;
|
|
140
|
-
cInfoHeader.biCompression = BI_RGB;
|
|
141
|
-
cInfoHeader.biSizeImage = 0;
|
|
142
|
-
cInfoHeader.biXPelsPerMeter = 0;
|
|
143
|
-
cInfoHeader.biYPelsPerMeter = 0;
|
|
144
|
-
cInfoHeader.biClrUsed = 0;
|
|
145
|
-
cInfoHeader.biClrImportant = 0;
|
|
146
|
-
|
|
147
|
-
cParameterProtect->cHBitmapFile = GlobalAlloc(GHND, cFileSize);
|
|
148
|
-
if (!cParameterProtect->cHBitmapFile)
|
|
149
|
-
RAISE_WIN32_ERROR;
|
|
150
|
-
cParameterProtect->cBitmapFile = (LPSTR) GlobalLock(cParameterProtect->cHBitmapFile);
|
|
151
|
-
if (!cParameterProtect->cBitmapFile)
|
|
152
|
-
RAISE_WIN32_ERROR;
|
|
153
|
-
|
|
154
|
-
cPFileHeader = (LPBITMAPFILEHEADER) cParameterProtect->cBitmapFile;
|
|
155
|
-
cPInfoHeader = (LPBITMAPINFOHEADER) (cPFileHeader + 1);
|
|
156
|
-
cPPalette = (LPSTR) (cPInfoHeader + 1);
|
|
157
|
-
cPData = cPPalette + cPaletteSize;
|
|
158
|
-
|
|
159
|
-
*cPFileHeader = cFileHeader;
|
|
160
|
-
*cPInfoHeader = cInfoHeader;
|
|
161
|
-
if (cPalette) {
|
|
162
|
-
cOldPalette = SelectPalette(cParameterProtect->cHDC, cPalette, FALSE);
|
|
163
|
-
RealizePalette(cParameterProtect->cHDC);
|
|
164
|
-
}
|
|
165
|
-
GetDIBits(cParameterProtect->cHDC, cHBitmap, 0, (UINT) cBitmap.bmHeight, cPData, (LPBITMAPINFO) cPInfoHeader,
|
|
166
|
-
DIB_RGB_COLORS);
|
|
167
|
-
if (cOldPalette) {
|
|
168
|
-
SelectPalette(cParameterProtect->cHDC, cOldPalette, TRUE);
|
|
169
|
-
RealizePalette(cParameterProtect->cHDC);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
pipes = rb_funcall(rb_cIO, rb_intern_const("pipe"), 2, pipesEncoding, pipesEncoding);
|
|
173
|
-
pipeIn = rb_ary_entry(pipes, 1);
|
|
174
|
-
pipeOut = rb_ary_entry(pipes, 0);
|
|
175
|
-
|
|
176
|
-
cParameterThread.pipe = pipeIn;
|
|
177
|
-
cParameterThread.cFileSize = cFileSize;
|
|
178
|
-
cParameterThread.cBitmapFile = cParameterProtect->cBitmapFile;
|
|
179
|
-
cParameterThread.cHBitmapFile = cParameterProtect->cHBitmapFile;
|
|
180
|
-
rb_thread_create(ruby__capture_helper_thread, &cParameterThread);
|
|
181
|
-
|
|
182
|
-
bmpClass = RUBY_MODULE_CONST_GET(specialInputDevice_image, rb_intern_const("BMP"));
|
|
183
|
-
return rb_funcall(bmpClass, rb_intern_const("load"), 1, pipeOut);
|
|
54
|
+
INT x;
|
|
55
|
+
INT y;
|
|
56
|
+
INT width;
|
|
57
|
+
INT height;
|
|
58
|
+
HDC memoryDC;
|
|
59
|
+
HDC screenDC;
|
|
60
|
+
LPSTR bitmapFile;
|
|
61
|
+
HANDLE hBitmapFile;
|
|
62
|
+
} SID_SCREEN_CAPTURE_PARAMETER;
|
|
63
|
+
|
|
64
|
+
static VALUE ruby__capture_helper(VALUE arguments) {
|
|
65
|
+
SID_SCREEN_CAPTURE_PARAMETER *cParameter = GET_DATA_OBJECT(arguments);
|
|
66
|
+
HBITMAP cHBitmap;
|
|
67
|
+
|
|
68
|
+
cParameter->screenDC = GetDC(NULL);
|
|
69
|
+
cParameter->memoryDC = CreateCompatibleDC(cParameter->screenDC);
|
|
70
|
+
cHBitmap = CreateCompatibleBitmap(cParameter->screenDC, cParameter->width, cParameter->height);
|
|
71
|
+
|
|
72
|
+
SelectObject(cParameter->memoryDC, cHBitmap);
|
|
73
|
+
BitBlt(cParameter->memoryDC, 0, 0, cParameter->width, cParameter->height,
|
|
74
|
+
cParameter->screenDC, cParameter->x, cParameter->y, SRCCOPY);
|
|
75
|
+
|
|
76
|
+
return ruby___image_new_from_bitmap(cHBitmap);
|
|
184
77
|
}
|
|
185
78
|
|
|
186
79
|
/*
|
|
@@ -195,40 +88,37 @@ static VALUE ruby__capture_helper_protect(VALUE arguments) {
|
|
|
195
88
|
* @return [SpecialInputDevice::Image]
|
|
196
89
|
*/
|
|
197
90
|
static VALUE ruby__capture(VARIABLE_ARGUMENTS_C) {
|
|
198
|
-
VALUE
|
|
199
|
-
VALUE
|
|
200
|
-
VALUE
|
|
201
|
-
VALUE
|
|
202
|
-
VALUE
|
|
203
|
-
|
|
204
|
-
INT
|
|
205
|
-
VALUE
|
|
206
|
-
parameter = Data_Make_Struct(rb_cData,
|
|
207
|
-
cParameter);
|
|
91
|
+
VALUE x;
|
|
92
|
+
VALUE y;
|
|
93
|
+
VALUE width;
|
|
94
|
+
VALUE height;
|
|
95
|
+
VALUE parameter;
|
|
96
|
+
SID_SCREEN_CAPTURE_PARAMETER *cParameter;
|
|
97
|
+
INT cError;
|
|
98
|
+
VALUE result;
|
|
99
|
+
parameter = Data_Make_Struct(rb_cData, SID_SCREEN_CAPTURE_PARAMETER, NULL, RUBY_DEFAULT_FREE, cParameter);
|
|
208
100
|
switch (cCount) {
|
|
209
|
-
case 0:
|
|
210
|
-
cParameter->
|
|
211
|
-
cParameter->
|
|
212
|
-
cParameter->
|
|
213
|
-
cParameter->
|
|
101
|
+
case 0:
|
|
102
|
+
cParameter->x = getVirtualScreenX();
|
|
103
|
+
cParameter->y = getVirtualScreenY();
|
|
104
|
+
cParameter->width = getVirtualScreenWidth();
|
|
105
|
+
cParameter->height = getVirtualScreenHeight();
|
|
214
106
|
break;
|
|
215
|
-
|
|
216
|
-
case 4: {
|
|
107
|
+
case 4:
|
|
217
108
|
SCAN_ARGUMENTS("4", &x, &y, &width, &height);
|
|
218
|
-
cParameter->
|
|
219
|
-
cParameter->
|
|
220
|
-
cParameter->
|
|
221
|
-
cParameter->
|
|
109
|
+
cParameter->x = NUM2INT(x);
|
|
110
|
+
cParameter->y = NUM2INT(y);
|
|
111
|
+
cParameter->width = NUM2INT(width);
|
|
112
|
+
cParameter->height = NUM2INT(height);
|
|
222
113
|
break;
|
|
223
|
-
}
|
|
224
114
|
default:
|
|
225
115
|
RAISE_ARGUMENT_ERROR("0, 4");
|
|
226
116
|
}
|
|
227
|
-
result = rb_protect(
|
|
228
|
-
GlobalUnlock(cParameter->
|
|
229
|
-
GlobalFree(cParameter->
|
|
230
|
-
ReleaseDC(NULL, cParameter->
|
|
231
|
-
ReleaseDC(NULL, cParameter->
|
|
117
|
+
result = rb_protect(ruby__capture_helper, parameter, &cError);
|
|
118
|
+
GlobalUnlock(cParameter->hBitmapFile);
|
|
119
|
+
GlobalFree(cParameter->hBitmapFile);
|
|
120
|
+
ReleaseDC(NULL, cParameter->memoryDC);
|
|
121
|
+
ReleaseDC(NULL, cParameter->screenDC);
|
|
232
122
|
if (cError)
|
|
233
123
|
rb_jump_tag(cError);
|
|
234
124
|
return result;
|
|
@@ -277,7 +167,7 @@ static VALUE ruby__find_image(VARIABLE_ARGUMENTS_C) {
|
|
|
277
167
|
}
|
|
278
168
|
// return capture;
|
|
279
169
|
rb_funcall(capture, rb_intern_const("save"), 1, rb_str_new_cstr("D:/2.bmp"));
|
|
280
|
-
result
|
|
170
|
+
result = rb_funcall(capture, rb_intern_const("find"), 2, image, options);
|
|
281
171
|
if (result != Qnil && *area != Qundef)
|
|
282
172
|
result = rb_funcall(result, rb_intern_const("move"), 2, x, y);
|
|
283
173
|
return result;
|
|
@@ -20,9 +20,8 @@ VOID Init_special_input_device() {
|
|
|
20
20
|
Init_win32error();
|
|
21
21
|
|
|
22
22
|
specialInputDevice_attributesEqualChecker = rb_define_module_under(specialInputDevice, "AttributesEqualChecker");
|
|
23
|
-
specialInputDevice_table2d = rb_define_class_under(specialInputDevice, "Table2D", rb_cObject);
|
|
24
23
|
specialInputDevice_color = rb_define_class_under(specialInputDevice, "Color", rb_cObject);
|
|
25
|
-
specialInputDevice_image = rb_define_class_under(specialInputDevice, "Image",
|
|
24
|
+
specialInputDevice_image = rb_define_class_under(specialInputDevice, "Image", rb_cData);
|
|
26
25
|
specialInputDevice_point = rb_define_class_under(specialInputDevice, "Point", rb_cObject);
|
|
27
26
|
specialInputDevice_rectangle = rb_define_class_under(specialInputDevice, "Rectangle", rb_cObject);
|
|
28
27
|
rb_eval_string(""
|
|
@@ -32,6 +31,7 @@ VOID Init_special_input_device() {
|
|
|
32
31
|
" raise LoadError.new('Cannot load the library of SpecialInputDevice. Reinstall may solve this problem.')\n"
|
|
33
32
|
"end\n");
|
|
34
33
|
|
|
34
|
+
Init_image();
|
|
35
35
|
Init_keyboard();
|
|
36
36
|
Init_mouse();
|
|
37
37
|
Init_screen();
|
|
@@ -14,7 +14,6 @@ typedef enum {
|
|
|
14
14
|
|
|
15
15
|
VALUE specialInputDevice;
|
|
16
16
|
VALUE specialInputDevice_attributesEqualChecker;
|
|
17
|
-
VALUE specialInputDevice_table2d;
|
|
18
17
|
VALUE specialInputDevice_color;
|
|
19
18
|
VALUE specialInputDevice_image;
|
|
20
19
|
VALUE specialInputDevice_point;
|
|
@@ -29,6 +28,8 @@ PCHAR ruby___special_input_device_get_mode_name();
|
|
|
29
28
|
|
|
30
29
|
VOID Init_special_input_device();
|
|
31
30
|
|
|
31
|
+
VOID Init_image();
|
|
32
|
+
|
|
32
33
|
VOID Init_interception();
|
|
33
34
|
|
|
34
35
|
VOID Init_keyboard();
|
|
@@ -14,9 +14,7 @@ VALUE ruby___win32error_new_from_code(DWORD cCode) {
|
|
|
14
14
|
/*
|
|
15
15
|
* @!scope class
|
|
16
16
|
* @overload new(code = nil)
|
|
17
|
-
* Returns a new instance of <code>Win32Error</code>.
|
|
18
17
|
* @param [Integer] code the error code
|
|
19
|
-
* @return [SpecialInputDevice::Window] a new instance of <code>Win32Error</code>
|
|
20
18
|
*/
|
|
21
19
|
|
|
22
20
|
static VALUE ruby_initialize(VARIABLE_ARGUMENTS_C) {
|