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,40 @@
|
|
|
1
|
+
#include "special_input_device.h"
|
|
2
|
+
|
|
3
|
+
SID_MODE ruby___special_input_device_get_mode_identifier() {
|
|
4
|
+
PCHAR cModeName = ruby___special_input_device_get_mode_name();
|
|
5
|
+
if (!strcmp(cModeName, "interception"))
|
|
6
|
+
return MODE_INTERCEPTION;
|
|
7
|
+
if (!strcmp(cModeName, "win_api"))
|
|
8
|
+
return MODE_WIN_API;
|
|
9
|
+
return (SID_MODE) -1;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
PCHAR ruby___special_input_device_get_mode_name() {
|
|
13
|
+
VALUE mode = rb_sym2str(rb_iv_get(specialInputDevice, "@mode"));
|
|
14
|
+
return rb_string_value_cstr(&mode);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
VOID Init_special_input_device() {
|
|
18
|
+
specialInputDevice = rb_define_module("SpecialInputDevice");
|
|
19
|
+
|
|
20
|
+
Init_win32error();
|
|
21
|
+
|
|
22
|
+
specialInputDevice_attributesEqualChecker = rb_define_module_under(specialInputDevice, "AttributesEqualChecker");
|
|
23
|
+
specialInputDevice_table2d = rb_define_class_under(specialInputDevice, "Table2D", rb_cObject);
|
|
24
|
+
specialInputDevice_color = rb_define_class_under(specialInputDevice, "Color", rb_cObject);
|
|
25
|
+
specialInputDevice_image = rb_define_class_under(specialInputDevice, "Image", specialInputDevice_table2d);
|
|
26
|
+
specialInputDevice_point = rb_define_class_under(specialInputDevice, "Point", rb_cObject);
|
|
27
|
+
specialInputDevice_rectangle = rb_define_class_under(specialInputDevice, "Rectangle", rb_cObject);
|
|
28
|
+
rb_eval_string(""
|
|
29
|
+
"begin\n"
|
|
30
|
+
" require('special_input_device/special_input_device')\n"
|
|
31
|
+
"rescue LoadError\n"
|
|
32
|
+
" raise LoadError.new('Cannot load the library of SpecialInputDevice. Reinstall may solve this problem.')\n"
|
|
33
|
+
"end\n");
|
|
34
|
+
|
|
35
|
+
Init_keyboard();
|
|
36
|
+
Init_mouse();
|
|
37
|
+
Init_screen();
|
|
38
|
+
Init_window();
|
|
39
|
+
Init_interception();
|
|
40
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#ifdef YARD
|
|
2
|
+
# define INTERCEPTION_STATIC
|
|
3
|
+
# define UNICODE
|
|
4
|
+
#endif
|
|
5
|
+
|
|
6
|
+
#include <ruby.h>
|
|
7
|
+
#include <ruby/encoding.h>
|
|
8
|
+
#include <windows.h>
|
|
9
|
+
|
|
10
|
+
typedef enum {
|
|
11
|
+
MODE_INTERCEPTION,
|
|
12
|
+
MODE_WIN_API
|
|
13
|
+
} SID_MODE;
|
|
14
|
+
|
|
15
|
+
VALUE specialInputDevice;
|
|
16
|
+
VALUE specialInputDevice_attributesEqualChecker;
|
|
17
|
+
VALUE specialInputDevice_table2d;
|
|
18
|
+
VALUE specialInputDevice_color;
|
|
19
|
+
VALUE specialInputDevice_image;
|
|
20
|
+
VALUE specialInputDevice_point;
|
|
21
|
+
VALUE specialInputDevice_rectangle;
|
|
22
|
+
VALUE specialInputDevice_win32error;
|
|
23
|
+
|
|
24
|
+
#include "ruby_macro.h"
|
|
25
|
+
|
|
26
|
+
SID_MODE ruby___special_input_device_get_mode_identifier();
|
|
27
|
+
|
|
28
|
+
PCHAR ruby___special_input_device_get_mode_name();
|
|
29
|
+
|
|
30
|
+
VOID Init_special_input_device();
|
|
31
|
+
|
|
32
|
+
VOID Init_interception();
|
|
33
|
+
|
|
34
|
+
VOID Init_keyboard();
|
|
35
|
+
|
|
36
|
+
VOID Init_mouse();
|
|
37
|
+
|
|
38
|
+
VOID Init_screen();
|
|
39
|
+
|
|
40
|
+
VOID Init_window();
|
|
41
|
+
|
|
42
|
+
VOID Init_win32error();
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#include "special_input_device.h"
|
|
2
|
+
|
|
3
|
+
VALUE ruby___win32error_new() {
|
|
4
|
+
VALUE newWin32ErrorArguments[0];
|
|
5
|
+
return rb_class_new_instance(0, newWin32ErrorArguments, specialInputDevice_win32error);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
VALUE ruby___win32error_new_from_code(DWORD cCode) {
|
|
9
|
+
VALUE newWin32ErrorArguments[1];
|
|
10
|
+
newWin32ErrorArguments[0] = UINT2NUM(cCode);
|
|
11
|
+
return rb_class_new_instance(1, newWin32ErrorArguments, specialInputDevice_win32error);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* @!scope class
|
|
16
|
+
* @overload new(code = nil)
|
|
17
|
+
* Returns a new instance of <code>Win32Error</code>.
|
|
18
|
+
* @param [Integer] code the error code
|
|
19
|
+
* @return [SpecialInputDevice::Window] a new instance of <code>Win32Error</code>
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
static VALUE ruby_initialize(VARIABLE_ARGUMENTS_C) {
|
|
23
|
+
VALUE code;
|
|
24
|
+
VALUE description;
|
|
25
|
+
VALUE formatStringArguments[2];
|
|
26
|
+
VALUE superArguments[1];
|
|
27
|
+
DWORD cCode;
|
|
28
|
+
LPTSTR cMessage;
|
|
29
|
+
DWORD cMessageLength;
|
|
30
|
+
SCAN_ARGUMENTS("01", &code);
|
|
31
|
+
cCode = code == Qnil ? GetLastError() : NUM2USHORT(code);
|
|
32
|
+
cMessage = (LPTSTR) VirtualAlloc((LPVOID) NULL, (SIZE_T) 256 * sizeof(TCHAR), MEM_COMMIT,
|
|
33
|
+
PAGE_READWRITE);
|
|
34
|
+
cMessageLength = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, cCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
35
|
+
cMessage, 256, NULL);
|
|
36
|
+
code = UINT2NUM(cCode);
|
|
37
|
+
description = RUBY_LPTSTR_TO_VALUE(cMessage, cMessageLength);
|
|
38
|
+
rb_iv_set(self, "@code", code);
|
|
39
|
+
rb_iv_set(self, "@description", description);
|
|
40
|
+
formatStringArguments[0] = code;
|
|
41
|
+
formatStringArguments[1] = description;
|
|
42
|
+
superArguments[0] = rb_str_format(2, formatStringArguments, rb_str_new_literal("0x%04X %s"));
|
|
43
|
+
rb_call_super(1, superArguments);
|
|
44
|
+
return Qnil;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
VOID Init_win32error() {
|
|
48
|
+
#ifdef YARD
|
|
49
|
+
specialInputDevice = rb_define_module("SpecialInputDevice");
|
|
50
|
+
#endif
|
|
51
|
+
/*
|
|
52
|
+
* Document-class: SpecialInputDevice::Win32Error
|
|
53
|
+
*
|
|
54
|
+
* Raised when calling Win API failed.
|
|
55
|
+
*/
|
|
56
|
+
specialInputDevice_win32error = rb_define_class_under(specialInputDevice, "Win32Error", rb_eException);
|
|
57
|
+
/*
|
|
58
|
+
* @return [Integer] the error code
|
|
59
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms679360.aspx Windows Dev Center - GetLastError function
|
|
60
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms681381.aspx Windows Dev Center - System Error Codes
|
|
61
|
+
*/
|
|
62
|
+
rb_define_attr(specialInputDevice_win32error, "code", TRUE, FALSE);
|
|
63
|
+
/*
|
|
64
|
+
* @return [String] the error description
|
|
65
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351.aspx Windows Dev Center - FormatMessage function
|
|
66
|
+
*/
|
|
67
|
+
rb_define_attr(specialInputDevice_win32error, "description", TRUE, FALSE);
|
|
68
|
+
rb_define_method(specialInputDevice_win32error, "initialize", ruby_initialize, -1);
|
|
69
|
+
}
|
|
@@ -0,0 +1,1108 @@
|
|
|
1
|
+
#include "special_input_device.h"
|
|
2
|
+
#include "_system_time.h"
|
|
3
|
+
#include "color.h"
|
|
4
|
+
#include "rectangle.h"
|
|
5
|
+
|
|
6
|
+
#define MAXIMUM_WINDOW_NAME_LENGTH 256
|
|
7
|
+
|
|
8
|
+
#define FLAT_CONTROL 0x0001
|
|
9
|
+
#define FLAT_CONTROL_LEFT 0x0002
|
|
10
|
+
#define FLAT_CONTROL_RIGHT 0x0004
|
|
11
|
+
#define FLAT_CONTROLS (FLAT_CONTROL | FLAT_CONTROL_LEFT | FLAT_CONTROL_RIGHT)
|
|
12
|
+
#define FLAT_SHIFT 0x0008
|
|
13
|
+
#define FLAT_SHIFT_LEFT 0x0010
|
|
14
|
+
#define FLAT_SHIFT_RIGHT 0x0020
|
|
15
|
+
#define FLAT_SHIFTS (FLAT_SHIFT | FLAT_SHIFT_LEFT | FLAT_SHIFT_RIGHT)
|
|
16
|
+
#define FLAT_ALTERNATE 0x0040
|
|
17
|
+
#define FLAT_ALTERNATE_LEFT 0x0080
|
|
18
|
+
#define FLAT_ALTERNATE_RIGHT 0x0100
|
|
19
|
+
#define FLAT_MOUSE_LEFT 0x0800
|
|
20
|
+
#define FLAT_MOUSE_MIDDLE 0x1000
|
|
21
|
+
#define FLAT_MOUSE_RIGHT 0x2000
|
|
22
|
+
#define FLAT_MOUSE_X1 0x4000
|
|
23
|
+
#define FLAT_MOUSE_X2 0x8000
|
|
24
|
+
|
|
25
|
+
typedef struct {
|
|
26
|
+
WORD flats;
|
|
27
|
+
SHORT x;
|
|
28
|
+
SHORT y;
|
|
29
|
+
ULONGLONG leftClick;
|
|
30
|
+
ULONGLONG middleClick;
|
|
31
|
+
ULONGLONG rightClick;
|
|
32
|
+
ULONGLONG x1Click;
|
|
33
|
+
ULONGLONG x2Click;
|
|
34
|
+
} SID_WINDOW_DATA;
|
|
35
|
+
|
|
36
|
+
static WPARAM createMouseMessageWParam(SID_WINDOW_DATA *cData) {
|
|
37
|
+
WPARAM cWParam = 0;
|
|
38
|
+
if (cData->flats & FLAT_CONTROLS)
|
|
39
|
+
cWParam |= MK_CONTROL;
|
|
40
|
+
if (cData->flats & FLAT_SHIFTS)
|
|
41
|
+
cWParam |= MK_SHIFT;
|
|
42
|
+
if (cData->flats & FLAT_MOUSE_LEFT)
|
|
43
|
+
cWParam |= MK_LBUTTON;
|
|
44
|
+
if (cData->flats & FLAT_MOUSE_MIDDLE)
|
|
45
|
+
cWParam |= MK_MBUTTON;
|
|
46
|
+
if (cData->flats & FLAT_MOUSE_RIGHT)
|
|
47
|
+
cWParam |= MK_RBUTTON;
|
|
48
|
+
if (cData->flats & FLAT_MOUSE_X1)
|
|
49
|
+
cWParam |= MK_XBUTTON1;
|
|
50
|
+
if (cData->flats & FLAT_MOUSE_X2)
|
|
51
|
+
cWParam |= MK_XBUTTON2;
|
|
52
|
+
return cWParam;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
inline static LPARAM createMouseMessageLParam(SID_WINDOW_DATA *cData) {
|
|
56
|
+
return cData->x | cData->y << 16;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static VALUE specialInputDevice_window;
|
|
60
|
+
|
|
61
|
+
static VALUE ruby___window_new(HWND cHandleCode) {
|
|
62
|
+
VALUE arguments = ULL2NUM((ULONGLONG) cHandleCode);
|
|
63
|
+
return rb_class_new_instance(1, &arguments, specialInputDevice_window);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
* Returns the desktop window. The desktop window covers the entire screen. The desktop window is the area on top of
|
|
68
|
+
* which other windows are painted.
|
|
69
|
+
* @return [SpecialInputDevice::Window] the desktop window.
|
|
70
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633504.aspx Windows Dev Center - GetDesktopWindow function
|
|
71
|
+
*/
|
|
72
|
+
static VALUE ruby__desktop(VALUE self) {
|
|
73
|
+
return ruby___window_new(GetDesktopWindow());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
typedef struct {
|
|
77
|
+
VALUE windowName;
|
|
78
|
+
VALUE className;
|
|
79
|
+
HWND cHandleCode;
|
|
80
|
+
} SID_WINDOW_FIND_PARAMETER;
|
|
81
|
+
|
|
82
|
+
static BOOLEAN callback_find_helper(VALUE pattern, LPTSTR cString) {
|
|
83
|
+
VALUE string;
|
|
84
|
+
if (pattern == Qnil)
|
|
85
|
+
return FALSE;
|
|
86
|
+
string = RUBY_LPCTSTR_TO_VALUE(cString);
|
|
87
|
+
if (RTEST(RUBY_OBJECT_IS_A_qs(pattern, rb_cRegexp))) {
|
|
88
|
+
if (RUBY_REGEXP_MATCH(pattern, string) == Qnil)
|
|
89
|
+
return TRUE;
|
|
90
|
+
} else {
|
|
91
|
+
if (!rb_str_equal(pattern, string))
|
|
92
|
+
return TRUE;
|
|
93
|
+
}
|
|
94
|
+
return FALSE;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static BOOL callback_find(HWND cHandleCode, LPARAM cArguments) {
|
|
98
|
+
SID_WINDOW_FIND_PARAMETER *cCallbackArguments = (SID_WINDOW_FIND_PARAMETER *) cArguments;
|
|
99
|
+
TCHAR cClassName[MAXIMUM_WINDOW_NAME_LENGTH * sizeof(TCHAR)];
|
|
100
|
+
INT cWindowNameLength = GetWindowTextLength(cHandleCode) + 1;
|
|
101
|
+
LPTSTR cWindowName = (LPTSTR) VirtualAlloc((LPVOID) NULL,
|
|
102
|
+
(SIZE_T) (cWindowNameLength) * sizeof(TCHAR),
|
|
103
|
+
MEM_COMMIT, PAGE_READWRITE);
|
|
104
|
+
GetClassName(cHandleCode, cClassName, MAXIMUM_WINDOW_NAME_LENGTH);
|
|
105
|
+
if (callback_find_helper(cCallbackArguments->className, cClassName))
|
|
106
|
+
return TRUE;
|
|
107
|
+
GetWindowText(cHandleCode, cWindowName, cWindowNameLength);
|
|
108
|
+
if (callback_find_helper(cCallbackArguments->windowName, cWindowName))
|
|
109
|
+
return TRUE;
|
|
110
|
+
cCallbackArguments->cHandleCode = cHandleCode;
|
|
111
|
+
SetLastError(0);
|
|
112
|
+
return FALSE;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/*
|
|
116
|
+
* @overload find(window_name = nil, class_name = nil)
|
|
117
|
+
* Search the window with specified windows name and class_name. If this parameter is <i>nil</i>, all window pass. If
|
|
118
|
+
* this parameter is a <code>Regexp</code>, window pass if its name match the pattern.If this parameter is a
|
|
119
|
+
* <code>String</code>, this method perform a case-insensitive search and window pass only if its full name totally
|
|
120
|
+
* matches.
|
|
121
|
+
* @param [NilClass, Regex, String] window_name the title of window.
|
|
122
|
+
* @param [NilClass, Regex, String] class_name the name class or class atom in windows.
|
|
123
|
+
* @return [SpecialInputDevice::Window, NilClass]
|
|
124
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633497.aspx Windows Dev Center - EnumWindows function
|
|
125
|
+
*/
|
|
126
|
+
static VALUE ruby__find(VARIABLE_ARGUMENTS_C) {
|
|
127
|
+
VALUE windowName;
|
|
128
|
+
VALUE className;
|
|
129
|
+
HWND cHandleCode;
|
|
130
|
+
SID_WINDOW_FIND_PARAMETER cCallbackArguments;
|
|
131
|
+
SCAN_ARGUMENTS("02", &windowName, &className);
|
|
132
|
+
if (windowName != Qnil && !RTEST(RUBY_OBJECT_IS_A_qs(windowName, rb_cRegexp)) &&
|
|
133
|
+
!RTEST(RUBY_OBJECT_IS_A_qs(windowName, rb_cString)))
|
|
134
|
+
RAISE_TYPE_ERROR(windowName, "nil, Regexp or String");
|
|
135
|
+
if (className != Qnil && !RTEST(RUBY_OBJECT_IS_A_qs(className, rb_cRegexp)) &&
|
|
136
|
+
!RTEST(RUBY_OBJECT_IS_A_qs(className, rb_cString)))
|
|
137
|
+
RAISE_TYPE_ERROR(className, "nil, Regexp or String");
|
|
138
|
+
cCallbackArguments.className = className;
|
|
139
|
+
cCallbackArguments.windowName = windowName;
|
|
140
|
+
cCallbackArguments.cHandleCode = 0;
|
|
141
|
+
EnumWindows(callback_find, (LPARAM) &cCallbackArguments);
|
|
142
|
+
cHandleCode = cCallbackArguments.cHandleCode;
|
|
143
|
+
if (GetLastError())
|
|
144
|
+
RAISE_WIN32_ERROR;
|
|
145
|
+
return cHandleCode ? ruby___window_new(cHandleCode) : Qnil;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/*
|
|
149
|
+
* @return [SpecialInputDevice::Window] a window which the user is currently working.
|
|
150
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633505.aspx Windows Dev Center - GetForegroundWindow function
|
|
151
|
+
*/
|
|
152
|
+
static VALUE ruby__foreground(VALUE self) {
|
|
153
|
+
return ruby___window_new(GetForegroundWindow());
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
inline static HWND ruby___window_get_handle_code(VALUE window) {
|
|
157
|
+
return (HWND) NUM2ULL(rb_iv_get(window, "@handle_code"));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
static VALUE ruby_window_name_EQ(VALUE self, VALUE value) {
|
|
161
|
+
HWND cHandleCode = ruby___window_get_handle_code(self);
|
|
162
|
+
LPCTSTR cWindowName = RUBY_VALUE_TO_LPCTSTR(value);
|
|
163
|
+
SetWindowText(cHandleCode, cWindowName);
|
|
164
|
+
return rb_iv_set(self, "@window_name", value);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
static VALUE ruby__alloc(VALUE self) {
|
|
168
|
+
return NEW_SIMPLE_DATA_OBJECT(self, SID_WINDOW_DATA);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/*
|
|
172
|
+
* @!scope class
|
|
173
|
+
* @overload new(handle_code)
|
|
174
|
+
* Returns a new instance of <code>Window</code>. Normally, use <code>::find</code> to get a window because it is not
|
|
175
|
+
* easy to find out a handle code of the window directly.
|
|
176
|
+
* @param [Integer] handle_code the handle code of the window. Handle code is an Integer for identifying windows.
|
|
177
|
+
* @return [SpecialInputDevice::Window] a new instance of <code>Window</code>
|
|
178
|
+
*/
|
|
179
|
+
static VALUE ruby_initialize(VALUE self, VALUE handleCode) {
|
|
180
|
+
HWND cHandleCode = (HWND) NUM2ULL(handleCode);
|
|
181
|
+
TCHAR cClassName[MAXIMUM_WINDOW_NAME_LENGTH * sizeof(TCHAR)];
|
|
182
|
+
INT cWindowNameLength = GetWindowTextLength(cHandleCode) + 1;
|
|
183
|
+
LPTSTR cWindowName = (LPTSTR) VirtualAlloc((LPVOID) NULL, (SIZE_T) (cWindowNameLength) * sizeof(TCHAR),
|
|
184
|
+
MEM_COMMIT, PAGE_READWRITE);
|
|
185
|
+
VALUE className;
|
|
186
|
+
VALUE windowName;
|
|
187
|
+
if (!GetClassName(cHandleCode, cClassName, MAXIMUM_WINDOW_NAME_LENGTH))
|
|
188
|
+
RAISE_WIN32_ERROR;
|
|
189
|
+
if (!GetWindowText(cHandleCode, cWindowName, cWindowNameLength)) {
|
|
190
|
+
DWORD cError = GetLastError();
|
|
191
|
+
switch (cError) {
|
|
192
|
+
case ERROR_SUCCESS:
|
|
193
|
+
case ERROR_NOT_SUPPORTED:
|
|
194
|
+
break;
|
|
195
|
+
default:
|
|
196
|
+
RAISE_WIN32_ERROR_FROM_CODE(cError);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
rb_iv_set(self, "@handle_code", handleCode);
|
|
200
|
+
className = RUBY_LPCTSTR_TO_VALUE(cClassName);
|
|
201
|
+
rb_iv_set(self, "@class_name", className);
|
|
202
|
+
windowName = RUBY_LPCTSTR_TO_VALUE(cWindowName);
|
|
203
|
+
rb_iv_set(self, "@window_name", windowName);
|
|
204
|
+
return Qnil;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
//<editor-fold desc="relationship">
|
|
208
|
+
|
|
209
|
+
/*
|
|
210
|
+
* @overload find_child(window_name = nil, class_name = nil, after = nil)
|
|
211
|
+
* Search the window with specified windows name and class_name form the children of self. This method perform a
|
|
212
|
+
* case-insensitive search.
|
|
213
|
+
* @param [String] window_name the title of window. If this parameter is <i>nil</i>, all window names match.
|
|
214
|
+
* @param [String] class_name the name of class or class atom in windows. If this parameter is <i>nil</i>, all class names match.
|
|
215
|
+
* @param [SpecialInputDevice::Window] after a child window. The search begins with the next child window in the z-order. The child window must be a direct child window of hwndParent, not just a descendant window.
|
|
216
|
+
* @return [SpecialInputDevice::Window]
|
|
217
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633500.aspx Windows Dev Center - FindWindowEX function
|
|
218
|
+
*/
|
|
219
|
+
static VALUE ruby_find_child(VARIABLE_ARGUMENTS_C) {
|
|
220
|
+
VALUE windowName;
|
|
221
|
+
VALUE className;
|
|
222
|
+
VALUE after;
|
|
223
|
+
LPCTSTR cWindowName;
|
|
224
|
+
LPCTSTR cClassName;
|
|
225
|
+
HWND cAfter;
|
|
226
|
+
HWND cHandleCode;
|
|
227
|
+
SCAN_ARGUMENTS("03", &windowName, &className, &after);
|
|
228
|
+
cWindowName = windowName == Qnil ? NULL : RUBY_VALUE_TO_LPCTSTR(windowName);
|
|
229
|
+
cClassName = className == Qnil ? NULL : RUBY_VALUE_TO_LPCTSTR(className);
|
|
230
|
+
cAfter = after == Qnil ? NULL : ruby___window_get_handle_code(after);
|
|
231
|
+
cHandleCode = FindWindowEx(ruby___window_get_handle_code(self), cAfter, cClassName, cWindowName);
|
|
232
|
+
if (!cHandleCode)
|
|
233
|
+
RAISE_WIN32_ERROR;
|
|
234
|
+
return ruby___window_new(cHandleCode);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/*
|
|
238
|
+
* @overload parent(include_owner = false)
|
|
239
|
+
* @return [SpecialInputDevice::Window] the parent window of self.
|
|
240
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633502.aspx Windows Dev Center - GetAncestor function
|
|
241
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633510.aspx Windows Dev Center - GetParent function
|
|
242
|
+
*/
|
|
243
|
+
static VALUE ruby_parent(VARIABLE_ARGUMENTS_C) {
|
|
244
|
+
VALUE includeOwner;
|
|
245
|
+
HWND cHandleCode;
|
|
246
|
+
SCAN_ARGUMENTS("01", &includeOwner);
|
|
247
|
+
cHandleCode = ruby___window_get_handle_code(self);
|
|
248
|
+
return ruby___window_new(
|
|
249
|
+
includeOwner && includeOwner != Qnil ? GetAncestor(cHandleCode, GA_PARENT) : GetParent(cHandleCode));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/*
|
|
253
|
+
* @overload root(include_owner = false)
|
|
254
|
+
* @return [SpecialInputDevice::Window] the root window of self.
|
|
255
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633502.aspx Windows Dev Center - GetAncestor function
|
|
256
|
+
*/
|
|
257
|
+
static VALUE ruby_root(VARIABLE_ARGUMENTS_C) {
|
|
258
|
+
VALUE includeOwner;
|
|
259
|
+
HWND cHandleCode;
|
|
260
|
+
SCAN_ARGUMENTS("01", &includeOwner);
|
|
261
|
+
cHandleCode = ruby___window_get_handle_code(self);
|
|
262
|
+
return ruby___window_new(GetAncestor(cHandleCode, includeOwner && includeOwner != Qnil ? GA_ROOT : GA_ROOTOWNER));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
//</editor-fold>
|
|
266
|
+
|
|
267
|
+
//<editor-fold desc="size">
|
|
268
|
+
|
|
269
|
+
/*
|
|
270
|
+
* Returns the rectangle of the window's client area. The coordinates of rectangle are relative to the client area
|
|
271
|
+
* itself so the upper-left corner are always (0, 0).
|
|
272
|
+
* @return [SpecialInputDevice::Rectangle] the rectangle of the window's client area.
|
|
273
|
+
* @see #window_rectangle
|
|
274
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633503.aspx Windows Dev Center - GetClientRect function
|
|
275
|
+
*/
|
|
276
|
+
static VALUE ruby_client_rectangle(VALUE self) {
|
|
277
|
+
RECT cClientRectangle;
|
|
278
|
+
HWND cHandleCode = ruby___window_get_handle_code(self);
|
|
279
|
+
if (!GetClientRect(cHandleCode, &cClientRectangle))
|
|
280
|
+
RAISE_WIN32_ERROR;
|
|
281
|
+
if (!ClientToScreen(cHandleCode, (LPPOINT) &cClientRectangle))
|
|
282
|
+
RAISE_WIN32_ERROR;
|
|
283
|
+
cClientRectangle.right += cClientRectangle.left;
|
|
284
|
+
cClientRectangle.bottom += cClientRectangle.top;
|
|
285
|
+
return ruby___rectangle_new_from_rect(&cClientRectangle);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/*
|
|
289
|
+
* Returns the bounding rectangle of the window. The rectangle is given in screen coordinates.
|
|
290
|
+
* @return [SpecialInputDevice::Rectangle] the bounding rectangle of the window.
|
|
291
|
+
* @see #client_rectangle
|
|
292
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633503.aspx Windows Dev Center - GetClientRect function
|
|
293
|
+
*/
|
|
294
|
+
static VALUE ruby_window_rectangle(VALUE self) {
|
|
295
|
+
RECT cWindowRectangle;
|
|
296
|
+
if (!GetWindowRect(ruby___window_get_handle_code(self), &cWindowRectangle))
|
|
297
|
+
RAISE_WIN32_ERROR;
|
|
298
|
+
return ruby___rectangle_new_from_rect(&cWindowRectangle);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
//</editor-fold>
|
|
302
|
+
|
|
303
|
+
//<editor-fold desc="control">
|
|
304
|
+
|
|
305
|
+
/*
|
|
306
|
+
* Brings the window to the foreground.
|
|
307
|
+
* @return [SpecialInputDevice::Window] self
|
|
308
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633539.aspx Windows Dev Center - SetForegroundWindow function
|
|
309
|
+
*/
|
|
310
|
+
static VALUE ruby_bring_to_foreground(VALUE self) {
|
|
311
|
+
if (!SetForegroundWindow(ruby___window_get_handle_code(self)))
|
|
312
|
+
RAISE_WIN32_ERROR;
|
|
313
|
+
return self;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/*
|
|
317
|
+
* Close the window.
|
|
318
|
+
* @return [SpecialInputDevice::Window] self
|
|
319
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
320
|
+
*/
|
|
321
|
+
static VALUE ruby_close(VALUE self) {
|
|
322
|
+
if (!PostMessage(ruby___window_get_handle_code(self), WM_CLOSE, 0, 0))
|
|
323
|
+
RAISE_WIN32_ERROR;
|
|
324
|
+
return self;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/*
|
|
328
|
+
* Hides the window. To show it again, call {#maximize}, {#minimize} or {#restore}.
|
|
329
|
+
* @return [SpecialInputDevice::Window] self
|
|
330
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548.aspx Windows Dev Center - ShowWindow function
|
|
331
|
+
*/
|
|
332
|
+
static VALUE ruby_hide(VALUE self) {
|
|
333
|
+
if (!ShowWindow(ruby___window_get_handle_code(self), SW_HIDE))
|
|
334
|
+
RAISE_WIN32_ERROR;
|
|
335
|
+
return self;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/*
|
|
339
|
+
* Maximizes the window.
|
|
340
|
+
* @return [SpecialInputDevice::Window] self
|
|
341
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548.aspx Windows Dev Center - ShowWindow function
|
|
342
|
+
*/
|
|
343
|
+
static VALUE ruby_maximize(VALUE self) {
|
|
344
|
+
if (!ShowWindow(ruby___window_get_handle_code(self), SW_SHOWMAXIMIZED))
|
|
345
|
+
RAISE_WIN32_ERROR;
|
|
346
|
+
return self;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/*
|
|
350
|
+
* Minimizes the window.
|
|
351
|
+
* @return [SpecialInputDevice::Window] self
|
|
352
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548.aspx Windows Dev Center - ShowWindow function
|
|
353
|
+
*/
|
|
354
|
+
static VALUE ruby_minimize(VALUE self) {
|
|
355
|
+
if (!ShowWindow(ruby___window_get_handle_code(self), SW_SHOWMINIMIZED))
|
|
356
|
+
RAISE_WIN32_ERROR;
|
|
357
|
+
return self;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/*
|
|
361
|
+
* Restore the window and then moves it to specific position.
|
|
362
|
+
* @overload move_to(x, y)
|
|
363
|
+
* @param [Integer] x the x-coordinate of target
|
|
364
|
+
* @param [Integer] y the y-coordinate of target
|
|
365
|
+
* @return [SpecialInputDevice::Window] self
|
|
366
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548.aspx Windows Dev Center - SetWindowPos function
|
|
367
|
+
*/
|
|
368
|
+
static VALUE ruby_move_to(VALUE self, VALUE x, VALUE y) {
|
|
369
|
+
INT cX = NUM2INT(x);
|
|
370
|
+
INT cY = NUM2INT(y);
|
|
371
|
+
if (!SetWindowPos(ruby___window_get_handle_code(self), NULL, cX, cY, 0, 0,
|
|
372
|
+
SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER))
|
|
373
|
+
RAISE_WIN32_ERROR;
|
|
374
|
+
return self;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/*
|
|
378
|
+
* Restore the window and then change it to specific size.
|
|
379
|
+
* @overload resize_to(width, height)
|
|
380
|
+
* @param [Integer] width the width of target size
|
|
381
|
+
* @param [Integer] height the height of target size
|
|
382
|
+
* @return [SpecialInputDevice::Window] self
|
|
383
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633545.aspx Windows Dev Center - SetWindowPos function
|
|
384
|
+
*/
|
|
385
|
+
static VALUE ruby_resize_to(VALUE self, VALUE width, VALUE height) {
|
|
386
|
+
INT cWidth = NUM2INT(width);
|
|
387
|
+
INT cHeight = NUM2INT(height);
|
|
388
|
+
if (!SetWindowPos(ruby___window_get_handle_code(self), NULL, 0, 0, cWidth, cHeight,
|
|
389
|
+
SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER))
|
|
390
|
+
RAISE_WIN32_ERROR;
|
|
391
|
+
return self;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/*
|
|
395
|
+
* Restores the window.
|
|
396
|
+
* @return [SpecialInputDevice::Window] self
|
|
397
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548.aspx Windows Dev Center - ShowWindow function
|
|
398
|
+
*/
|
|
399
|
+
static VALUE ruby_restore(VALUE self) {
|
|
400
|
+
if (!ShowWindow(ruby___window_get_handle_code(self), SW_SHOWNORMAL))
|
|
401
|
+
RAISE_WIN32_ERROR;
|
|
402
|
+
return self;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
//</editor-fold>
|
|
406
|
+
|
|
407
|
+
//<editor-fold desc="display">
|
|
408
|
+
|
|
409
|
+
/*
|
|
410
|
+
* @overload color_at(x, y)
|
|
411
|
+
* @param [Fixnum] x the x coordinate of the point for get color
|
|
412
|
+
* @param [Fixnum] y the y coordinate of the point for get color
|
|
413
|
+
* @return [SpecialInputDevice::Color] the color at the specified point in the client area of window
|
|
414
|
+
* @see SpecialInputDevice::Screen.color_at
|
|
415
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/dd144909.aspx Windows Dev Center - GetPixel function
|
|
416
|
+
*/
|
|
417
|
+
static VALUE ruby_color_at(VALUE self, VALUE x, VALUE y) {
|
|
418
|
+
INT cX = NUM2INT(x);
|
|
419
|
+
INT cY = NUM2INT(y);
|
|
420
|
+
COLORREF cColor = GetPixel(GetDC(ruby___window_get_handle_code(self)), cX, cY);
|
|
421
|
+
return ruby___color_new_from_color_ref(cColor);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
//</editor-fold>
|
|
425
|
+
|
|
426
|
+
//<editor-fold desc="input">
|
|
427
|
+
|
|
428
|
+
//<editor-fold desc="keyboard">
|
|
429
|
+
|
|
430
|
+
/*
|
|
431
|
+
* @overload key_hold(key_code)
|
|
432
|
+
* Simulate holding the specified key down in the window. User would not lose the control of computer.
|
|
433
|
+
* @param [Integer] key_code virtual key code. Use a value of constant in {SpecialInputDevice::KeyCode}.
|
|
434
|
+
* @return [SpecialInputDevice::Window] self
|
|
435
|
+
* @see SpecialInputDevice::Keyboard.hold
|
|
436
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
437
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646280.aspx Windows Dev Center - WM_KEYDOWN message
|
|
438
|
+
*/
|
|
439
|
+
static VALUE ruby_key_hold(VALUE self, VALUE keyCode) {
|
|
440
|
+
SID_WINDOW_DATA *cData;
|
|
441
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
442
|
+
WPARAM cWParam = NUM2USHORT(keyCode);
|
|
443
|
+
LPARAM cLParam = 1 | (WORD) MapVirtualKeyA(cWParam, MAPVK_VK_TO_VSC) << 16;
|
|
444
|
+
PostMessage(cHWnd, WM_KEYDOWN, cWParam, cLParam);
|
|
445
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
446
|
+
switch (cWParam) {
|
|
447
|
+
case VK_CONTROL:
|
|
448
|
+
cData->flats |= FLAT_CONTROL;
|
|
449
|
+
break;
|
|
450
|
+
case VK_LCONTROL:
|
|
451
|
+
cData->flats |= FLAT_CONTROL_LEFT;
|
|
452
|
+
break;
|
|
453
|
+
case VK_RCONTROL:
|
|
454
|
+
cData->flats |= FLAT_CONTROL_RIGHT;
|
|
455
|
+
break;
|
|
456
|
+
case VK_SHIFT:
|
|
457
|
+
cData->flats |= FLAT_SHIFT;
|
|
458
|
+
break;
|
|
459
|
+
case VK_LSHIFT:
|
|
460
|
+
cData->flats |= FLAT_SHIFT_LEFT;
|
|
461
|
+
break;
|
|
462
|
+
case VK_RSHIFT:
|
|
463
|
+
cData->flats |= FLAT_SHIFT_RIGHT;
|
|
464
|
+
break;
|
|
465
|
+
case VK_MENU:
|
|
466
|
+
cData->flats |= FLAT_ALTERNATE;
|
|
467
|
+
break;
|
|
468
|
+
case VK_LMENU:
|
|
469
|
+
cData->flats |= FLAT_ALTERNATE_LEFT;
|
|
470
|
+
break;
|
|
471
|
+
case VK_RMENU:
|
|
472
|
+
cData->flats |= FLAT_ALTERNATE_RIGHT;
|
|
473
|
+
break;
|
|
474
|
+
default:
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
return self;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/*
|
|
481
|
+
* @overload key_release(key_code)
|
|
482
|
+
* Simulate releasing the specified key in the window. User would not lose the control of computer.
|
|
483
|
+
* @param [Integer] key_code virtual key code. Use a value of constant in {SpecialInputDevice::KeyCode}.
|
|
484
|
+
* @return [SpecialInputDevice::Window] self
|
|
485
|
+
* @see SpecialInputDevice::Keyboard.release
|
|
486
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
487
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646281.aspx Windows Dev Center - WM_KEYUP message
|
|
488
|
+
*/
|
|
489
|
+
static VALUE ruby_key_release(VALUE self, VALUE keyCode) {
|
|
490
|
+
SID_WINDOW_DATA *cData;
|
|
491
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
492
|
+
WPARAM cWParam = NUM2USHORT(keyCode);
|
|
493
|
+
LPARAM cLParam = 1;
|
|
494
|
+
cLParam |= (WORD) MapVirtualKeyA(cWParam, MAPVK_VK_TO_VSC) << 16;
|
|
495
|
+
cLParam |= 0xA0000000;
|
|
496
|
+
PostMessage(cHWnd, WM_KEYUP, cWParam, cLParam);
|
|
497
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
498
|
+
switch (cWParam) {
|
|
499
|
+
case VK_CONTROL:
|
|
500
|
+
cData->flats &= ~FLAT_CONTROL;
|
|
501
|
+
break;
|
|
502
|
+
case VK_LCONTROL:
|
|
503
|
+
cData->flats &= ~FLAT_CONTROL_LEFT;
|
|
504
|
+
break;
|
|
505
|
+
case VK_RCONTROL:
|
|
506
|
+
cData->flats &= ~FLAT_CONTROL_RIGHT;
|
|
507
|
+
break;
|
|
508
|
+
case VK_SHIFT:
|
|
509
|
+
cData->flats &= ~FLAT_SHIFT;
|
|
510
|
+
break;
|
|
511
|
+
case VK_LSHIFT:
|
|
512
|
+
cData->flats &= ~FLAT_SHIFT_LEFT;
|
|
513
|
+
break;
|
|
514
|
+
case VK_RSHIFT:
|
|
515
|
+
cData->flats &= ~FLAT_SHIFT_RIGHT;
|
|
516
|
+
break;
|
|
517
|
+
case VK_MENU:
|
|
518
|
+
cData->flats &= ~FLAT_ALTERNATE;
|
|
519
|
+
break;
|
|
520
|
+
case VK_LMENU:
|
|
521
|
+
cData->flats &= ~FLAT_ALTERNATE_LEFT;
|
|
522
|
+
break;
|
|
523
|
+
case VK_RMENU:
|
|
524
|
+
cData->flats &= ~FLAT_ALTERNATE_RIGHT;
|
|
525
|
+
break;
|
|
526
|
+
default:
|
|
527
|
+
break;
|
|
528
|
+
}
|
|
529
|
+
return self;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/*
|
|
533
|
+
* @overload key_press(key_code)
|
|
534
|
+
* Simulate pressing the specified key in the window. User would not lose the control of computer.
|
|
535
|
+
* @param [Integer] key_code virtual key code. Use a value of constant in {SpecialInputDevice::KeyCode}.
|
|
536
|
+
* @return [SpecialInputDevice::Window] self
|
|
537
|
+
* @see SpecialInputDevice::Keyboard.press
|
|
538
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
539
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646280.aspx Windows Dev Center - WM_KEYDOWN message
|
|
540
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646281.aspx Windows Dev Center - WM_KEYUP message
|
|
541
|
+
*/
|
|
542
|
+
static VALUE ruby_key_press(VALUE self, VALUE keyCode) {
|
|
543
|
+
SID_WINDOW_DATA *cData;
|
|
544
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
545
|
+
WPARAM cWParam = NUM2USHORT(keyCode);
|
|
546
|
+
LPARAM cLParam = 1 | (WORD) MapVirtualKeyA(cWParam, MAPVK_VK_TO_VSC) << 16;
|
|
547
|
+
PostMessage(cHWnd, WM_KEYDOWN, cWParam, cLParam);
|
|
548
|
+
cLParam |= 0xA0000000;
|
|
549
|
+
PostMessage(cHWnd, WM_KEYUP, cWParam, cLParam);
|
|
550
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
551
|
+
switch (cWParam) {
|
|
552
|
+
case VK_CONTROL:
|
|
553
|
+
cData->flats &= ~FLAT_CONTROL;
|
|
554
|
+
break;
|
|
555
|
+
case VK_LCONTROL:
|
|
556
|
+
cData->flats &= ~FLAT_CONTROL_LEFT;
|
|
557
|
+
break;
|
|
558
|
+
case VK_RCONTROL:
|
|
559
|
+
cData->flats &= ~FLAT_CONTROL_RIGHT;
|
|
560
|
+
break;
|
|
561
|
+
case VK_SHIFT:
|
|
562
|
+
cData->flats &= ~FLAT_SHIFT;
|
|
563
|
+
break;
|
|
564
|
+
case VK_LSHIFT:
|
|
565
|
+
cData->flats &= ~FLAT_SHIFT_LEFT;
|
|
566
|
+
break;
|
|
567
|
+
case VK_RSHIFT:
|
|
568
|
+
cData->flats &= ~FLAT_SHIFT_RIGHT;
|
|
569
|
+
break;
|
|
570
|
+
case VK_MENU:
|
|
571
|
+
cData->flats &= ~FLAT_ALTERNATE;
|
|
572
|
+
break;
|
|
573
|
+
case VK_LMENU:
|
|
574
|
+
cData->flats &= ~FLAT_ALTERNATE_LEFT;
|
|
575
|
+
break;
|
|
576
|
+
case VK_RMENU:
|
|
577
|
+
cData->flats &= ~FLAT_ALTERNATE_RIGHT;
|
|
578
|
+
break;
|
|
579
|
+
default:
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
582
|
+
return self;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
//</editor-fold>
|
|
586
|
+
|
|
587
|
+
//<editor-fold desc="mouse">
|
|
588
|
+
|
|
589
|
+
//<editor-fold desc="move">
|
|
590
|
+
|
|
591
|
+
/*
|
|
592
|
+
* @overload mouse_move_relatively(x, y)
|
|
593
|
+
* Move the cursor position relative to current position.
|
|
594
|
+
* @param [Integer] x the amount of horizontal motion specified as the number of pixels.
|
|
595
|
+
* @param [Integer] y the amount of vertical motion specified as the number of pixels.
|
|
596
|
+
* @return [SpecialInputDevice::Window] self
|
|
597
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
598
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645616.aspx Windows Dev Center - WM_MOUSEMOVE message
|
|
599
|
+
*/
|
|
600
|
+
static VALUE ruby_mouse_move_relatively(VALUE self, VALUE x, VALUE y) {
|
|
601
|
+
SID_WINDOW_DATA *cData;
|
|
602
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
603
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
604
|
+
cData->x += NUM2SHORT(x);
|
|
605
|
+
cData->y += NUM2SHORT(y);
|
|
606
|
+
PostMessage(cHWnd, WM_MOUSEMOVE, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
607
|
+
return self;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/*
|
|
611
|
+
* @overload mouse_move_to(x, y)
|
|
612
|
+
* Move the cursor position relative to the upper-left corner of client area of the window.
|
|
613
|
+
* @param [Integer] x the x-coordinate of position specified as the number of pixels.
|
|
614
|
+
* @param [Integer] y the y-coordinate of position specified as the number of pixels.
|
|
615
|
+
* @return [SpecialInputDevice::Window] self
|
|
616
|
+
* @see SpecialInputDevice::Mouse.move_to_primary
|
|
617
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
618
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645616.aspx Windows Dev Center - WM_MOUSEMOVE message
|
|
619
|
+
*/
|
|
620
|
+
static VALUE ruby_mouse_move_to(VALUE self, VALUE x, VALUE y) {
|
|
621
|
+
SID_WINDOW_DATA *cData;
|
|
622
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
623
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
624
|
+
cData->x = NUM2SHORT(x);
|
|
625
|
+
cData->y = NUM2SHORT(y);
|
|
626
|
+
PostMessage(cHWnd, WM_MOUSEMOVE, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
627
|
+
return self;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
//</editor-fold>
|
|
631
|
+
|
|
632
|
+
//<editor-fold desc="left_button">
|
|
633
|
+
|
|
634
|
+
/*
|
|
635
|
+
* Simulate clicking the left button on the mouse in the window.
|
|
636
|
+
* @return [SpecialInputDevice::Window] self
|
|
637
|
+
* @see SpecialInputDevice::Mouse.left_click
|
|
638
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
639
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645606.aspx Windows Dev Center - WM_LBUTTONDBLCLK message
|
|
640
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645607.aspx Windows Dev Center - WM_LBUTTONDOWN message
|
|
641
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645608.aspx Windows Dev Center - WM_LBUTTONUP message
|
|
642
|
+
*/
|
|
643
|
+
static VALUE ruby_mouse_left_click(VALUE self) {
|
|
644
|
+
SID_WINDOW_DATA *cData;
|
|
645
|
+
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
646
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
647
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
648
|
+
cData->flats |= FLAT_MOUSE_LEFT;
|
|
649
|
+
PostMessage(cHWnd, WM_LBUTTONDOWN, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
650
|
+
if (cData->leftClick && cData->leftClick + GetDoubleClickTime() <= cCurrentTime)
|
|
651
|
+
PostMessage(cHWnd, WM_LBUTTONDBLCLK, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
652
|
+
cData->flats &= ~FLAT_MOUSE_LEFT;
|
|
653
|
+
PostMessage(cHWnd, WM_LBUTTONUP, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
654
|
+
cData->leftClick = cCurrentTime;
|
|
655
|
+
return self;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/*
|
|
659
|
+
* Simulate holding the left button on the mouse down in the window.
|
|
660
|
+
* @return [SpecialInputDevice::Window] self
|
|
661
|
+
* @see SpecialInputDevice::Mouse.left_down
|
|
662
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
663
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645606.aspx Windows Dev Center - WM_LBUTTONDBLCLK message
|
|
664
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645607.aspx Windows Dev Center - WM_LBUTTONDOWN message
|
|
665
|
+
*/
|
|
666
|
+
static VALUE ruby_mouse_left_down(VALUE self) {
|
|
667
|
+
SID_WINDOW_DATA *cData;
|
|
668
|
+
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
669
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
670
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
671
|
+
cData->flats |= FLAT_MOUSE_LEFT;
|
|
672
|
+
PostMessage(cHWnd, WM_LBUTTONDOWN, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
673
|
+
if (cData->leftClick && cData->leftClick + GetDoubleClickTime() <= cCurrentTime)
|
|
674
|
+
PostMessage(cHWnd, WM_LBUTTONDBLCLK, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
675
|
+
cData->leftClick = cCurrentTime;
|
|
676
|
+
return self;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/*
|
|
680
|
+
* Simulate releasing the left button on the mouse in the window.
|
|
681
|
+
* @return [SpecialInputDevice::Window] self
|
|
682
|
+
* @see SpecialInputDevice::Mouse.left_up
|
|
683
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
684
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645608.aspx Windows Dev Center - WM_LBUTTONUP message
|
|
685
|
+
*/
|
|
686
|
+
static VALUE ruby_mouse_left_up(VALUE self) {
|
|
687
|
+
SID_WINDOW_DATA *cData;
|
|
688
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
689
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
690
|
+
cData->flats &= ~FLAT_MOUSE_LEFT;
|
|
691
|
+
PostMessage(cHWnd, WM_LBUTTONUP, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
692
|
+
return self;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
//</editor-fold>
|
|
696
|
+
|
|
697
|
+
//<editor-fold desc="right_button">
|
|
698
|
+
|
|
699
|
+
/*
|
|
700
|
+
* Simulate clicking the right button on the mouse in the window.
|
|
701
|
+
* @return [SpecialInputDevice::Window] self
|
|
702
|
+
* @see SpecialInputDevice::Mouse.right_click
|
|
703
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
704
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646241.aspx Windows Dev Center - WM_RBUTTONDBLCLK function
|
|
705
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646242.aspx Windows Dev Center - WM_RBUTTONDOWN function
|
|
706
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646243.aspx Windows Dev Center - WM_RBUTTONUP function
|
|
707
|
+
*/
|
|
708
|
+
static VALUE ruby_mouse_right_click(VALUE self) {
|
|
709
|
+
SID_WINDOW_DATA *cData;
|
|
710
|
+
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
711
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
712
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
713
|
+
cData->flats |= FLAT_MOUSE_RIGHT;
|
|
714
|
+
PostMessage(cHWnd, WM_RBUTTONDOWN, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
715
|
+
if (cData->rightClick && cData->rightClick + GetDoubleClickTime() <= cCurrentTime)
|
|
716
|
+
PostMessage(cHWnd, WM_LBUTTONDBLCLK, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
717
|
+
cData->flats &= ~FLAT_MOUSE_RIGHT;
|
|
718
|
+
PostMessage(cHWnd, WM_RBUTTONUP, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
719
|
+
cData->rightClick = cCurrentTime;
|
|
720
|
+
return self;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/*
|
|
724
|
+
* Simulate holding the right button on the mouse down in the window.
|
|
725
|
+
* @return [SpecialInputDevice::Window] self
|
|
726
|
+
* @see SpecialInputDevice::Mouse.right_down
|
|
727
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
728
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646241.aspx Windows Dev Center - WM_RBUTTONDBLCLK function
|
|
729
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646242.aspx Windows Dev Center - WM_RBUTTONDOWN function
|
|
730
|
+
*/
|
|
731
|
+
static VALUE ruby_mouse_right_down(VALUE self) {
|
|
732
|
+
SID_WINDOW_DATA *cData;
|
|
733
|
+
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
734
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
735
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
736
|
+
cData->flats |= FLAT_MOUSE_RIGHT;
|
|
737
|
+
PostMessage(cHWnd, WM_RBUTTONDOWN, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
738
|
+
if (cData->rightClick && cData->rightClick + GetDoubleClickTime() <= cCurrentTime)
|
|
739
|
+
PostMessage(cHWnd, WM_LBUTTONDBLCLK, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
740
|
+
cData->rightClick = cCurrentTime;
|
|
741
|
+
return self;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/*
|
|
745
|
+
* Simulate releasing the right button on the mouse in the window.
|
|
746
|
+
* @return [SpecialInputDevice::Window] self
|
|
747
|
+
* @see SpecialInputDevice::Mouse.right_up
|
|
748
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
749
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646243.aspx Windows Dev Center - WM_RBUTTONUP function
|
|
750
|
+
*/
|
|
751
|
+
static VALUE ruby_mouse_right_up(VALUE self) {
|
|
752
|
+
SID_WINDOW_DATA *cData;
|
|
753
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
754
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
755
|
+
cData->flats &= ~FLAT_MOUSE_RIGHT;
|
|
756
|
+
PostMessage(cHWnd, WM_RBUTTONUP, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
757
|
+
return self;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
//</editor-fold>
|
|
761
|
+
|
|
762
|
+
//<editor-fold desc="middle_button">
|
|
763
|
+
|
|
764
|
+
/*
|
|
765
|
+
* Simulate clicking the middle button on the mouse in the window.
|
|
766
|
+
* @return [SpecialInputDevice::Window] self
|
|
767
|
+
* @see SpecialInputDevice::Mouse.middle_click
|
|
768
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
769
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645609.aspx Windows Dev Center - WM_MBUTTONDBLCLK function
|
|
770
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645610.aspx Windows Dev Center - WM_MBUTTONDOWN function
|
|
771
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645611.aspx Windows Dev Center - WM_MBUTTONUP function
|
|
772
|
+
*/
|
|
773
|
+
static VALUE ruby_mouse_middle_click(VALUE self) {
|
|
774
|
+
SID_WINDOW_DATA *cData;
|
|
775
|
+
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
776
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
777
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
778
|
+
cData->flats |= FLAT_MOUSE_MIDDLE;
|
|
779
|
+
PostMessage(cHWnd, WM_MBUTTONDOWN, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
780
|
+
if (cData->middleClick && cData->middleClick + GetDoubleClickTime() <= cCurrentTime)
|
|
781
|
+
PostMessage(cHWnd, WM_LBUTTONDBLCLK, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
782
|
+
cData->flats &= ~FLAT_MOUSE_MIDDLE;
|
|
783
|
+
PostMessage(cHWnd, WM_MBUTTONUP, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
784
|
+
cData->middleClick = cCurrentTime;
|
|
785
|
+
return self;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
/*
|
|
789
|
+
* Simulate holding the middle button on the mouse down in the window.
|
|
790
|
+
* @return [SpecialInputDevice::Window] self
|
|
791
|
+
* @see SpecialInputDevice::Mouse.middle_down
|
|
792
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
793
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645609.aspx Windows Dev Center - WM_MBUTTONDBLCLK function
|
|
794
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645610.aspx Windows Dev Center - WM_MBUTTONDOWN function
|
|
795
|
+
*/
|
|
796
|
+
static VALUE ruby_mouse_middle_down(VALUE self) {
|
|
797
|
+
SID_WINDOW_DATA *cData;
|
|
798
|
+
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
799
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
800
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
801
|
+
cData->flats |= FLAT_MOUSE_MIDDLE;
|
|
802
|
+
PostMessage(cHWnd, WM_MBUTTONDOWN, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
803
|
+
if (cData->middleClick && cData->middleClick + GetDoubleClickTime() <= cCurrentTime)
|
|
804
|
+
PostMessage(cHWnd, WM_LBUTTONDBLCLK, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
805
|
+
cData->middleClick = cCurrentTime;
|
|
806
|
+
return self;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/*
|
|
810
|
+
* Simulate releasing the middle button on the mouse in the window.
|
|
811
|
+
* @return [SpecialInputDevice::Window] self
|
|
812
|
+
* @see SpecialInputDevice::Mouse.middle_up
|
|
813
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
814
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645611.aspx Windows Dev Center - WM_MBUTTONUP function
|
|
815
|
+
*/
|
|
816
|
+
static VALUE ruby_mouse_middle_up(VALUE self) {
|
|
817
|
+
SID_WINDOW_DATA *cData;
|
|
818
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
819
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
820
|
+
cData->flats &= ~FLAT_MOUSE_MIDDLE;
|
|
821
|
+
PostMessage(cHWnd, WM_MBUTTONUP, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
822
|
+
return self;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
//</editor-fold>
|
|
826
|
+
|
|
827
|
+
//<editor-fold desc="x_button">
|
|
828
|
+
|
|
829
|
+
/*
|
|
830
|
+
* Simulate clicking the x1 button on the mouse in the window.
|
|
831
|
+
* @return [SpecialInputDevice::Window] self
|
|
832
|
+
* @see SpecialInputDevice::Mouse.x1_click
|
|
833
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
834
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646244.aspx Windows Dev Center - WM_XBUTTONDBLCLK function
|
|
835
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646245.aspx Windows Dev Center - WM_XBUTTONDOWN function
|
|
836
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646246.aspx Windows Dev Center - WM_XBUTTONUP function
|
|
837
|
+
*/
|
|
838
|
+
static VALUE ruby_mouse_x1_click(VALUE self) {
|
|
839
|
+
SID_WINDOW_DATA *cData;
|
|
840
|
+
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
841
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
842
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
843
|
+
cData->flats |= FLAT_MOUSE_X1;
|
|
844
|
+
PostMessage(cHWnd, WM_XBUTTONDOWN, createMouseMessageWParam(cData) | XBUTTON1 << 16,
|
|
845
|
+
createMouseMessageLParam(cData));
|
|
846
|
+
if (cData->x1Click && cData->x1Click + GetDoubleClickTime() <= cCurrentTime)
|
|
847
|
+
PostMessage(cHWnd, WM_LBUTTONDBLCLK, createMouseMessageWParam(cData) | XBUTTON1 << 16,
|
|
848
|
+
createMouseMessageLParam(cData));
|
|
849
|
+
cData->flats &= ~FLAT_MOUSE_X1;
|
|
850
|
+
PostMessage(cHWnd, WM_XBUTTONUP, createMouseMessageWParam(cData) | XBUTTON1 << 16, createMouseMessageLParam(cData));
|
|
851
|
+
cData->x1Click = cCurrentTime;
|
|
852
|
+
return self;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
/*
|
|
856
|
+
* Simulate holding the x1 button on the mouse down in the window.
|
|
857
|
+
* @return [SpecialInputDevice::Window] self
|
|
858
|
+
* @see SpecialInputDevice::Mouse.x1_down
|
|
859
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
860
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646244.aspx Windows Dev Center - WM_XBUTTONDBLCLK function
|
|
861
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646245.aspx Windows Dev Center - WM_XBUTTONDOWN function
|
|
862
|
+
*/
|
|
863
|
+
static VALUE ruby_mouse_x1_down(VALUE self) {
|
|
864
|
+
SID_WINDOW_DATA *cData;
|
|
865
|
+
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
866
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
867
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
868
|
+
cData->flats |= FLAT_MOUSE_X1;
|
|
869
|
+
PostMessage(cHWnd, WM_XBUTTONDOWN, createMouseMessageWParam(cData) | XBUTTON1 << 16,
|
|
870
|
+
createMouseMessageLParam(cData));
|
|
871
|
+
if (cData->x1Click && cData->x1Click + GetDoubleClickTime() <= cCurrentTime)
|
|
872
|
+
PostMessage(cHWnd, WM_LBUTTONDBLCLK, createMouseMessageWParam(cData) | XBUTTON1 << 16,
|
|
873
|
+
createMouseMessageLParam(cData));
|
|
874
|
+
cData->x1Click = cCurrentTime;
|
|
875
|
+
return self;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
/*
|
|
879
|
+
* Simulate releasing the x1 button on the mouse in the window.
|
|
880
|
+
* @return [SpecialInputDevice::Window] self
|
|
881
|
+
* @see SpecialInputDevice::Mouse.x1_up
|
|
882
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
883
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646246.aspx Windows Dev Center - WM_XBUTTONUP function
|
|
884
|
+
*/
|
|
885
|
+
static VALUE ruby_mouse_x1_up(VALUE self) {
|
|
886
|
+
SID_WINDOW_DATA *cData;
|
|
887
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
888
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
889
|
+
cData->flats &= ~FLAT_MOUSE_X1;
|
|
890
|
+
PostMessage(cHWnd, WM_XBUTTONUP, createMouseMessageWParam(cData) | XBUTTON1 << 16, createMouseMessageLParam(cData));
|
|
891
|
+
return self;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
/*
|
|
895
|
+
* Simulate clicking the x2 button on the mouse in the window.
|
|
896
|
+
* @return [SpecialInputDevice::Window] self
|
|
897
|
+
* @see SpecialInputDevice::Mouse.x2_click
|
|
898
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
899
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646244.aspx Windows Dev Center - WM_XBUTTONDBLCLK function
|
|
900
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646245.aspx Windows Dev Center - WM_XBUTTONDOWN function
|
|
901
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646246.aspx Windows Dev Center - WM_XBUTTONUP function
|
|
902
|
+
*/
|
|
903
|
+
static VALUE ruby_mouse_x2_click(VALUE self) {
|
|
904
|
+
SID_WINDOW_DATA *cData;
|
|
905
|
+
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
906
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
907
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
908
|
+
cData->flats |= FLAT_MOUSE_X2;
|
|
909
|
+
PostMessage(cHWnd, WM_XBUTTONDOWN, createMouseMessageWParam(cData) | XBUTTON2 << 16,
|
|
910
|
+
createMouseMessageLParam(cData));
|
|
911
|
+
if (cData->x2Click && cData->x2Click + GetDoubleClickTime() <= cCurrentTime)
|
|
912
|
+
PostMessage(cHWnd, WM_LBUTTONDBLCLK, createMouseMessageWParam(cData) | XBUTTON2 << 16,
|
|
913
|
+
createMouseMessageLParam(cData));
|
|
914
|
+
cData->flats &= ~FLAT_MOUSE_X2;
|
|
915
|
+
PostMessage(cHWnd, WM_XBUTTONUP, createMouseMessageWParam(cData) | XBUTTON2 << 16, createMouseMessageLParam(cData));
|
|
916
|
+
cData->x2Click = cCurrentTime;
|
|
917
|
+
return self;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
/*
|
|
921
|
+
* Simulate holding the x2 button on the mouse down in the window.
|
|
922
|
+
* @return [SpecialInputDevice::Window] self
|
|
923
|
+
* @see SpecialInputDevice::Mouse.x2_down
|
|
924
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
925
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646244.aspx Windows Dev Center - WM_XBUTTONDBLCLK function
|
|
926
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646245.aspx Windows Dev Center - WM_XBUTTONDOWN function
|
|
927
|
+
*/
|
|
928
|
+
static VALUE ruby_mouse_x2_down(VALUE self) {
|
|
929
|
+
SID_WINDOW_DATA *cData;
|
|
930
|
+
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
931
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
932
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
933
|
+
cData->flats |= FLAT_MOUSE_X2;
|
|
934
|
+
PostMessage(cHWnd, WM_XBUTTONDOWN, createMouseMessageWParam(cData) | XBUTTON2 << 16,
|
|
935
|
+
createMouseMessageLParam(cData));
|
|
936
|
+
if (cData->x2Click && cData->x2Click + GetDoubleClickTime() <= cCurrentTime)
|
|
937
|
+
PostMessage(cHWnd, WM_LBUTTONDBLCLK, createMouseMessageWParam(cData) | XBUTTON2 << 16,
|
|
938
|
+
createMouseMessageLParam(cData));
|
|
939
|
+
cData->x2Click = cCurrentTime;
|
|
940
|
+
return self;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/*
|
|
944
|
+
* Simulate releasing the x2 button on the mouse in the window.
|
|
945
|
+
* @return [SpecialInputDevice::Window] self
|
|
946
|
+
* @see SpecialInputDevice::Mouse.x2_up
|
|
947
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
948
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646246.aspx Windows Dev Center - WM_XBUTTONUP function
|
|
949
|
+
*/
|
|
950
|
+
static VALUE ruby_mouse_x2_up(VALUE self) {
|
|
951
|
+
SID_WINDOW_DATA *cData;
|
|
952
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
953
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
954
|
+
cData->flats &= ~FLAT_MOUSE_X2;
|
|
955
|
+
PostMessage(cHWnd, WM_XBUTTONUP, createMouseMessageWParam(cData) | XBUTTON2 << 16, createMouseMessageLParam(cData));
|
|
956
|
+
return self;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
//</editor-fold>
|
|
960
|
+
|
|
961
|
+
//<editor-fold desc="wheel">
|
|
962
|
+
|
|
963
|
+
/*
|
|
964
|
+
* Simulate wheeling the scroll backward in the window.
|
|
965
|
+
* @return [SpecialInputDevice::Window] self
|
|
966
|
+
* @see SpecialInputDevice::Mouse.scroll_wheel_backward
|
|
967
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
968
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645617.aspx Windows Dev Center - WM_MOUSEWHEEL function
|
|
969
|
+
*/
|
|
970
|
+
static VALUE ruby_mouse_scroll_wheel_backward(VALUE self) {
|
|
971
|
+
SID_WINDOW_DATA *cData;
|
|
972
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
973
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
974
|
+
PostMessage(cHWnd, WM_MOUSEWHEEL, createMouseMessageWParam(cData) | -WHEEL_DELTA << 16,
|
|
975
|
+
createMouseMessageLParam(cData));
|
|
976
|
+
return self;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
/*
|
|
980
|
+
* Simulate wheeling the scroll forward in the window.
|
|
981
|
+
* @return [SpecialInputDevice::Window] self
|
|
982
|
+
* @see SpecialInputDevice::Mouse.scroll_wheel_forward
|
|
983
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
984
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645617.aspx Windows Dev Center - WM_MOUSEWHEEL function
|
|
985
|
+
*/
|
|
986
|
+
static VALUE ruby_mouse_scroll_wheel_forward(VALUE self) {
|
|
987
|
+
SID_WINDOW_DATA *cData;
|
|
988
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
989
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
990
|
+
PostMessage(cHWnd, WM_MOUSEWHEEL, createMouseMessageWParam(cData) | WHEEL_DELTA << 16,
|
|
991
|
+
createMouseMessageLParam(cData));
|
|
992
|
+
return self;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
/*
|
|
996
|
+
* Simulate wheeling the scroll to left hand side in the window.
|
|
997
|
+
* @return [SpecialInputDevice::Window] self
|
|
998
|
+
* @see SpecialInputDevice::Mouse.scroll_wheel_to_left
|
|
999
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
1000
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645614.aspx Windows Dev Center - WM_MOUSEHWHEEL function
|
|
1001
|
+
*/
|
|
1002
|
+
static VALUE ruby_mouse_scroll_wheel_to_left(VALUE self) {
|
|
1003
|
+
#ifdef MOUSEEVENTF_HWHEEL
|
|
1004
|
+
SID_WINDOW_DATA *cData;
|
|
1005
|
+
HWND cHWnd = getHandleCode(self);
|
|
1006
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
1007
|
+
PostMessage(cHWnd, WM_MOUSEHWHEEL, createMouseMessageWParam(cData) | -WHEEL_DELTA << 16, createMouseMessageLParam(cData));
|
|
1008
|
+
return self;
|
|
1009
|
+
#else
|
|
1010
|
+
rb_raise(rb_eRuntimeError, "Error! Your system does not support horizontal wheel.");
|
|
1011
|
+
#endif
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/*
|
|
1015
|
+
* Simulate wheeling the scroll to right hand side in the window.
|
|
1016
|
+
* @return [SpecialInputDevice::Window] self
|
|
1017
|
+
* @see SpecialInputDevice::Mouse.scroll_wheel_to_right
|
|
1018
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms644944.aspx Windows Dev Center - PostMessage function
|
|
1019
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645614.aspx Windows Dev Center - WM_MOUSEHWHEEL function
|
|
1020
|
+
*/
|
|
1021
|
+
static VALUE ruby_mouse_scroll_wheel_to_right(VALUE self) {
|
|
1022
|
+
#ifdef MOUSEEVENTF_HWHEEL
|
|
1023
|
+
SID_WINDOW_DATA *cData;
|
|
1024
|
+
HWND cHWnd = getHandleCode(self);
|
|
1025
|
+
Data_Get_Struct(self, SID_WINDOW_DATA, cData);
|
|
1026
|
+
PostMessage(cHWnd, WM_MOUSEHWHEEL, createMouseMessageWParam(cData) | WHEEL_DELTA << 16, createMouseMessageLParam(cData));
|
|
1027
|
+
return self;
|
|
1028
|
+
#else
|
|
1029
|
+
rb_raise(rb_eRuntimeError, "Error! Your system does not support horizontal wheel.");
|
|
1030
|
+
#endif
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
//</editor-fold>
|
|
1034
|
+
|
|
1035
|
+
//</editor-fold>
|
|
1036
|
+
|
|
1037
|
+
//</editor-fold>
|
|
1038
|
+
|
|
1039
|
+
VOID Init_window() {
|
|
1040
|
+
#ifdef YARD
|
|
1041
|
+
specialInputDevice = rb_define_module("SpecialInputDevice");
|
|
1042
|
+
#endif
|
|
1043
|
+
/*
|
|
1044
|
+
* Document-class: SpecialInputDevice::Window
|
|
1045
|
+
*
|
|
1046
|
+
* A <code>Window</code> object represent a rectangular area for application displays output and receives inputs.
|
|
1047
|
+
* By using this class, you can control the window without losing the control of computer.
|
|
1048
|
+
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms632595.aspx Windows Dev Center - Windows
|
|
1049
|
+
*/
|
|
1050
|
+
specialInputDevice_window = rb_define_class_under(specialInputDevice, "Window", rb_cData);
|
|
1051
|
+
rb_define_singleton_method(specialInputDevice_window, "desktop", ruby__desktop, 0);
|
|
1052
|
+
rb_define_singleton_method(specialInputDevice_window, "find", ruby__find, -1);
|
|
1053
|
+
rb_define_singleton_method(specialInputDevice_window, "foreground", ruby__foreground, 0);
|
|
1054
|
+
rb_define_alloc_func(specialInputDevice_window, (rb_alloc_func_t) ruby__alloc);
|
|
1055
|
+
/*
|
|
1056
|
+
* @return [String] the name of class or class atom in windows.
|
|
1057
|
+
*/
|
|
1058
|
+
rb_define_attr(specialInputDevice_window, "class_name", TRUE, FALSE);
|
|
1059
|
+
/*
|
|
1060
|
+
* The handle code of the window. Handle code is an Integer for identifying windows.
|
|
1061
|
+
* @return [Integer] the handle code of the window.
|
|
1062
|
+
*/
|
|
1063
|
+
rb_define_attr(specialInputDevice_window, "handle_code", TRUE, FALSE);
|
|
1064
|
+
/*
|
|
1065
|
+
* @return [String] the title of window.
|
|
1066
|
+
*/
|
|
1067
|
+
rb_define_attr(specialInputDevice_window, "window_name", TRUE, TRUE);
|
|
1068
|
+
rb_define_method(specialInputDevice_window, "window_name=", ruby_window_name_EQ, 1);
|
|
1069
|
+
rb_define_method(specialInputDevice_window, "initialize", ruby_initialize, 1);
|
|
1070
|
+
rb_define_method(specialInputDevice_window, "find_child", ruby_find_child, -1);
|
|
1071
|
+
rb_define_method(specialInputDevice_window, "parent", ruby_parent, -1);
|
|
1072
|
+
rb_define_method(specialInputDevice_window, "root", ruby_root, -1);
|
|
1073
|
+
rb_define_method(specialInputDevice_window, "client_rectangle", ruby_client_rectangle, 0);
|
|
1074
|
+
rb_define_method(specialInputDevice_window, "window_rectangle", ruby_window_rectangle, 0);
|
|
1075
|
+
rb_define_method(specialInputDevice_window, "bring_to_foreground", ruby_bring_to_foreground, 0);
|
|
1076
|
+
rb_define_method(specialInputDevice_window, "close", ruby_close, 0);
|
|
1077
|
+
rb_define_method(specialInputDevice_window, "hide", ruby_hide, 0);
|
|
1078
|
+
rb_define_method(specialInputDevice_window, "maximize", ruby_maximize, 0);
|
|
1079
|
+
rb_define_method(specialInputDevice_window, "minimize", ruby_minimize, 0);
|
|
1080
|
+
rb_define_method(specialInputDevice_window, "move_to", ruby_move_to, 2);
|
|
1081
|
+
rb_define_method(specialInputDevice_window, "resize_to", ruby_resize_to, 2);
|
|
1082
|
+
rb_define_method(specialInputDevice_window, "restore", ruby_restore, 0);
|
|
1083
|
+
rb_define_method(specialInputDevice_window, "color_at", ruby_color_at, 2);
|
|
1084
|
+
rb_define_method(specialInputDevice_window, "key_hold", ruby_key_hold, 1);
|
|
1085
|
+
rb_define_method(specialInputDevice_window, "key_release", ruby_key_release, 1);
|
|
1086
|
+
rb_define_method(specialInputDevice_window, "key_press", ruby_key_press, 1);
|
|
1087
|
+
rb_define_method(specialInputDevice_window, "mouse_move_relatively", ruby_mouse_move_relatively, 2);
|
|
1088
|
+
rb_define_method(specialInputDevice_window, "mouse_move_to", ruby_mouse_move_to, 2);
|
|
1089
|
+
rb_define_method(specialInputDevice_window, "mouse_left_click", ruby_mouse_left_click, 0);
|
|
1090
|
+
rb_define_method(specialInputDevice_window, "mouse_left_down", ruby_mouse_left_down, 0);
|
|
1091
|
+
rb_define_method(specialInputDevice_window, "mouse_left_up", ruby_mouse_left_up, 0);
|
|
1092
|
+
rb_define_method(specialInputDevice_window, "mouse_right_click", ruby_mouse_right_click, 0);
|
|
1093
|
+
rb_define_method(specialInputDevice_window, "mouse_right_down", ruby_mouse_right_down, 0);
|
|
1094
|
+
rb_define_method(specialInputDevice_window, "mouse_right_up", ruby_mouse_right_up, 0);
|
|
1095
|
+
rb_define_method(specialInputDevice_window, "mouse_middle_click", ruby_mouse_middle_click, 0);
|
|
1096
|
+
rb_define_method(specialInputDevice_window, "mouse_middle_down", ruby_mouse_middle_down, 0);
|
|
1097
|
+
rb_define_method(specialInputDevice_window, "mouse_middle_up", ruby_mouse_middle_up, 0);
|
|
1098
|
+
rb_define_method(specialInputDevice_window, "mouse_x1_click", ruby_mouse_x1_click, 0);
|
|
1099
|
+
rb_define_method(specialInputDevice_window, "mouse_x1_down", ruby_mouse_x1_down, 0);
|
|
1100
|
+
rb_define_method(specialInputDevice_window, "mouse_x1_up", ruby_mouse_x1_up, 0);
|
|
1101
|
+
rb_define_method(specialInputDevice_window, "mouse_x2_click", ruby_mouse_x2_click, 0);
|
|
1102
|
+
rb_define_method(specialInputDevice_window, "mouse_x2_down", ruby_mouse_x2_down, 0);
|
|
1103
|
+
rb_define_method(specialInputDevice_window, "mouse_x2_up", ruby_mouse_x2_up, 0);
|
|
1104
|
+
rb_define_method(specialInputDevice_window, "mouse_scroll_wheel_backward", ruby_mouse_scroll_wheel_backward, 0);
|
|
1105
|
+
rb_define_method(specialInputDevice_window, "mouse_scroll_wheel_forward", ruby_mouse_scroll_wheel_forward, 0);
|
|
1106
|
+
rb_define_method(specialInputDevice_window, "mouse_scroll_wheel_to_left", ruby_mouse_scroll_wheel_to_left, 0);
|
|
1107
|
+
rb_define_method(specialInputDevice_window, "mouse_scroll_wheel_to_right", ruby_mouse_scroll_wheel_to_right, 0);
|
|
1108
|
+
}
|