special_input_device 0.0.1 → 0.1.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 +4 -4
- data/ext/special_input_device/image.c +13 -13
- data/ext/special_input_device/interception.c +151 -7
- data/ext/special_input_device/interception.h +2 -0
- data/ext/special_input_device/keyboard.c +44 -0
- data/ext/special_input_device/keyboard.h +6 -0
- data/ext/special_input_device/mouse.c +22 -20
- data/ext/special_input_device/mouse.h +6 -0
- data/ext/special_input_device/ruby_macro.h +10 -6
- data/ext/special_input_device/screen.c +3 -4
- data/ext/special_input_device/special_input_device.c +36 -1
- data/ext/special_input_device/special_input_device.h +7 -0
- data/ext/special_input_device/window.c +207 -60
- data/lib/special_input_device/color.rb +4 -4
- data/lib/special_input_device/image.rb +2 -1
- data/lib/special_input_device/point.rb +2 -2
- data/lib/special_input_device/rectangle.rb +40 -37
- data/lib/special_input_device/special_input_device.rb +6 -4
- metadata +5 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#include "special_input_device.h"
|
|
2
2
|
#include "_system_time.h"
|
|
3
3
|
#include "color.h"
|
|
4
|
+
#include "image.h"
|
|
4
5
|
#include "rectangle.h"
|
|
5
6
|
|
|
6
7
|
#define MAXIMUM_WINDOW_NAME_LENGTH 256
|
|
@@ -136,13 +137,13 @@ static VALUE ruby__find(VARIABLE_ARGUMENTS_C) {
|
|
|
136
137
|
SCAN_ARGUMENTS("02", &windowName, &className);
|
|
137
138
|
if (windowName != Qnil && !RTEST(RUBY_OBJECT_IS_A_qs(windowName, rb_cRegexp)) &&
|
|
138
139
|
!RTEST(RUBY_OBJECT_IS_A_qs(windowName, rb_cString)))
|
|
139
|
-
|
|
140
|
+
RAISE_SIMPLE_TYPE_ERROR(windowName, "nil, Regexp or String");
|
|
140
141
|
if (className != Qnil && !RTEST(RUBY_OBJECT_IS_A_qs(className, rb_cRegexp)) &&
|
|
141
142
|
!RTEST(RUBY_OBJECT_IS_A_qs(className, rb_cString)))
|
|
142
|
-
|
|
143
|
-
cCallbackArguments.className
|
|
144
|
-
cCallbackArguments.windowName
|
|
145
|
-
cCallbackArguments.hWND
|
|
143
|
+
RAISE_SIMPLE_TYPE_ERROR(className, "nil, Regexp or String");
|
|
144
|
+
cCallbackArguments.className = className;
|
|
145
|
+
cCallbackArguments.windowName = windowName;
|
|
146
|
+
cCallbackArguments.hWND = 0;
|
|
146
147
|
EnumWindows(callback_find, (LPARAM) &cCallbackArguments);
|
|
147
148
|
cHWND = cCallbackArguments.hWND;
|
|
148
149
|
if (GetLastError())
|
|
@@ -163,7 +164,7 @@ static VALUE ruby__alloc(VALUE self) {
|
|
|
163
164
|
}
|
|
164
165
|
|
|
165
166
|
static VALUE ruby_window_name_EQ(VALUE self, VALUE value) {
|
|
166
|
-
HWND cHWND
|
|
167
|
+
HWND cHWND = ruby___window_get_handle_code(self);
|
|
167
168
|
LPCTSTR cWindowName = RUBY_VALUE_TO_LPCTSTR(value);
|
|
168
169
|
SetWindowText(cHWND, cWindowName);
|
|
169
170
|
return rb_iv_set(self, "@window_name", value);
|
|
@@ -177,7 +178,7 @@ static VALUE ruby_window_name_EQ(VALUE self, VALUE value) {
|
|
|
177
178
|
* @param [Integer] handle_code the handle code of the window. Handle code is an Integer for identifying windows.
|
|
178
179
|
*/
|
|
179
180
|
static VALUE ruby_initialize(VALUE self, VALUE handleCode) {
|
|
180
|
-
HWND cHWND
|
|
181
|
+
HWND cHWND = (HWND) NUM2ULL(handleCode);
|
|
181
182
|
TCHAR cClassName[MAXIMUM_WINDOW_NAME_LENGTH * sizeof(TCHAR)];
|
|
182
183
|
INT cWindowNameLength = GetWindowTextLength(cHWND) + 1;
|
|
183
184
|
LPTSTR cWindowName = (LPTSTR) VirtualAlloc((LPVOID) NULL, (SIZE_T) (cWindowNameLength) * sizeof(TCHAR),
|
|
@@ -204,7 +205,7 @@ static VALUE ruby_initialize(VALUE self, VALUE handleCode) {
|
|
|
204
205
|
return Qnil;
|
|
205
206
|
}
|
|
206
207
|
|
|
207
|
-
|
|
208
|
+
//region relationship
|
|
208
209
|
|
|
209
210
|
/*
|
|
210
211
|
* @overload find_child(window_name = nil, class_name = nil, after = nil)
|
|
@@ -228,7 +229,7 @@ static VALUE ruby_find_child(VARIABLE_ARGUMENTS_C) {
|
|
|
228
229
|
cWindowName = windowName == Qnil ? NULL : RUBY_VALUE_TO_LPCTSTR(windowName);
|
|
229
230
|
cClassName = className == Qnil ? NULL : RUBY_VALUE_TO_LPCTSTR(className);
|
|
230
231
|
cAfter = after == Qnil ? NULL : ruby___window_get_handle_code(after);
|
|
231
|
-
cHWND
|
|
232
|
+
cHWND = FindWindowEx(ruby___window_get_handle_code(self), cAfter, cClassName, cWindowName);
|
|
232
233
|
if (!cHWND)
|
|
233
234
|
RAISE_WIN32_ERROR();
|
|
234
235
|
return ruby___window_new(cHWND);
|
|
@@ -262,9 +263,9 @@ static VALUE ruby_root(VARIABLE_ARGUMENTS_C) {
|
|
|
262
263
|
return ruby___window_new(GetAncestor(cHWND, includeOwner && includeOwner != Qnil ? GA_ROOT : GA_ROOTOWNER));
|
|
263
264
|
}
|
|
264
265
|
|
|
265
|
-
|
|
266
|
+
//endregion relationship
|
|
266
267
|
|
|
267
|
-
|
|
268
|
+
//region size
|
|
268
269
|
|
|
269
270
|
/*
|
|
270
271
|
* Returns the rectangle of the window's client area. The coordinates of rectangle are relative to the client area
|
|
@@ -298,9 +299,9 @@ static VALUE ruby_window_rectangle(VALUE self) {
|
|
|
298
299
|
return ruby___rectangle_new_from_rect(&cWindowRectangle);
|
|
299
300
|
}
|
|
300
301
|
|
|
301
|
-
|
|
302
|
+
//endregion size
|
|
302
303
|
|
|
303
|
-
|
|
304
|
+
//region control
|
|
304
305
|
|
|
305
306
|
/*
|
|
306
307
|
* Brings the window to the foreground.
|
|
@@ -402,9 +403,9 @@ static VALUE ruby_restore(VALUE self) {
|
|
|
402
403
|
return self;
|
|
403
404
|
}
|
|
404
405
|
|
|
405
|
-
|
|
406
|
+
//endregion control
|
|
406
407
|
|
|
407
|
-
|
|
408
|
+
//region display
|
|
408
409
|
|
|
409
410
|
/*
|
|
410
411
|
* @overload color_at(x, y)
|
|
@@ -415,18 +416,162 @@ static VALUE ruby_restore(VALUE self) {
|
|
|
415
416
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/dd144909.aspx Windows Dev Center - GetPixel function
|
|
416
417
|
*/
|
|
417
418
|
static VALUE ruby_color_at(VALUE self, VALUE x, VALUE y) {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
HDC
|
|
421
|
-
|
|
419
|
+
HWND cWindow = ruby___window_get_handle_code(self);
|
|
420
|
+
COLORREF cColor;
|
|
421
|
+
HDC cWindowDC;
|
|
422
|
+
POINT cPoint;
|
|
423
|
+
RECT cWindowRectangle;
|
|
424
|
+
cPoint.x = NUM2LONG(x);
|
|
425
|
+
cPoint.y = NUM2LONG(y);
|
|
426
|
+
if (!ClientToScreen(cWindow, &cPoint))
|
|
427
|
+
RAISE_WIN32_ERROR();
|
|
428
|
+
if (!GetWindowRect(cWindow, &cWindowRectangle))
|
|
429
|
+
RAISE_WIN32_ERROR();
|
|
430
|
+
cWindowDC = GetWindowDC(cWindow);
|
|
431
|
+
cColor = GetPixel(cWindowDC, cPoint.x - cWindowRectangle.left, cPoint.y - cWindowRectangle.top);
|
|
432
|
+
ReleaseDC(cWindow, cWindowDC);
|
|
422
433
|
return ruby___color_new_from_color_ref(cColor);
|
|
423
434
|
}
|
|
424
435
|
|
|
425
|
-
|
|
436
|
+
typedef struct {
|
|
437
|
+
INT x;
|
|
438
|
+
INT y;
|
|
439
|
+
INT width;
|
|
440
|
+
INT height;
|
|
441
|
+
HWND window;
|
|
442
|
+
HDC memoryDC;
|
|
443
|
+
HDC windowDC;
|
|
444
|
+
LPSTR bitmapFile;
|
|
445
|
+
HANDLE hBitmapFile;
|
|
446
|
+
} SID_WINDOW_CAPTURE_PARAMETER;
|
|
447
|
+
|
|
448
|
+
static VALUE ruby_capture_helper(VALUE arguments) {
|
|
449
|
+
SID_WINDOW_CAPTURE_PARAMETER *cParameter = GET_DATA_OBJECT(arguments);
|
|
450
|
+
HBITMAP cHBitmap;
|
|
451
|
+
|
|
452
|
+
cParameter->windowDC = GetWindowDC(cParameter->window);
|
|
453
|
+
cParameter->memoryDC = CreateCompatibleDC(cParameter->windowDC);
|
|
454
|
+
cHBitmap = CreateCompatibleBitmap(cParameter->windowDC, cParameter->width, cParameter->height);
|
|
455
|
+
|
|
456
|
+
SelectObject(cParameter->memoryDC, cHBitmap);
|
|
457
|
+
BitBlt(cParameter->memoryDC, 0, 0, cParameter->width, cParameter->height,
|
|
458
|
+
cParameter->windowDC, cParameter->x, cParameter->y, SRCCOPY);
|
|
459
|
+
|
|
460
|
+
return ruby___image_new_from_bitmap(cHBitmap);
|
|
461
|
+
}
|
|
426
462
|
|
|
427
|
-
|
|
463
|
+
/*
|
|
464
|
+
* @overload capture()
|
|
465
|
+
* Capture the whole screen.
|
|
466
|
+
* @overload capture(x, y, width, height)
|
|
467
|
+
* Capture a rectangle part of screen.
|
|
468
|
+
* @param [Integer] x the x-coordinate of the left edge
|
|
469
|
+
* @param [Integer] y the y-coordinate of the top edge
|
|
470
|
+
* @param [Integer] width the width of rectangle
|
|
471
|
+
* @param [Integer] height the height of rectangle
|
|
472
|
+
* @return [SpecialInputDevice::Image]
|
|
473
|
+
*/
|
|
474
|
+
static VALUE ruby_capture(VARIABLE_ARGUMENTS_C) {
|
|
475
|
+
VALUE x;
|
|
476
|
+
VALUE y;
|
|
477
|
+
VALUE width;
|
|
478
|
+
VALUE height;
|
|
479
|
+
VALUE parameter;
|
|
480
|
+
SID_WINDOW_CAPTURE_PARAMETER *cParameter;
|
|
481
|
+
INT cError;
|
|
482
|
+
VALUE result;
|
|
483
|
+
parameter = Data_Make_Struct(rb_cData, SID_WINDOW_CAPTURE_PARAMETER, NULL, RUBY_DEFAULT_FREE, cParameter);
|
|
484
|
+
switch (cCount) {
|
|
485
|
+
case 0: {
|
|
486
|
+
HWND cWindow = ruby___window_get_handle_code(self);
|
|
487
|
+
RECT cClientRectangle;
|
|
488
|
+
RECT cWindowRectangle;
|
|
489
|
+
if (!GetClientRect(cWindow, &cClientRectangle))
|
|
490
|
+
RAISE_WIN32_ERROR();
|
|
491
|
+
if (!ClientToScreen(cWindow, (LPPOINT) &cClientRectangle))
|
|
492
|
+
RAISE_WIN32_ERROR();
|
|
493
|
+
if (!GetWindowRect(cWindow, &cWindowRectangle))
|
|
494
|
+
RAISE_WIN32_ERROR();
|
|
495
|
+
cParameter->x = cClientRectangle.left - cWindowRectangle.left;
|
|
496
|
+
cParameter->y = cClientRectangle.top - cWindowRectangle.top;
|
|
497
|
+
cParameter->width = cClientRectangle.right;
|
|
498
|
+
cParameter->height = cClientRectangle.bottom;
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
case 4:
|
|
502
|
+
SCAN_ARGUMENTS("4", &x, &y, &width, &height);
|
|
503
|
+
cParameter->x = NUM2INT(x);
|
|
504
|
+
cParameter->y = NUM2INT(y);
|
|
505
|
+
cParameter->width = NUM2INT(width);
|
|
506
|
+
cParameter->height = NUM2INT(height);
|
|
507
|
+
break;
|
|
508
|
+
default:
|
|
509
|
+
RAISE_ARGUMENT_ERROR("0, 4");
|
|
510
|
+
}
|
|
511
|
+
cParameter->window = ruby___window_get_handle_code(self);
|
|
512
|
+
result = rb_protect(ruby_capture_helper, parameter, &cError);
|
|
513
|
+
GlobalUnlock(cParameter->hBitmapFile);
|
|
514
|
+
GlobalFree(cParameter->hBitmapFile);
|
|
515
|
+
ReleaseDC(NULL, cParameter->memoryDC);
|
|
516
|
+
ReleaseDC(NULL, cParameter->windowDC);
|
|
517
|
+
if (cError)
|
|
518
|
+
rb_jump_tag(cError);
|
|
519
|
+
return result;
|
|
520
|
+
}
|
|
428
521
|
|
|
429
|
-
|
|
522
|
+
/*
|
|
523
|
+
* @overload find_image(image, area: SpecialInputDevice::Screen.primary_screen, similarity: 1.0, _return: RETURN_METHOD::FIRST)
|
|
524
|
+
* @param [SpecialInputDevice::Image, String] image a picture to be search
|
|
525
|
+
* @param [SpecialInputDevice::Rectangle] area the searching area
|
|
526
|
+
* @param [Float] similarity minimum limit of similarity
|
|
527
|
+
* @param [Symbol] _return indicate the behavior of this method, see SpecialInputDevice::Image::RETURN_METHOD
|
|
528
|
+
* @return [NilClass, SpecialInputDevice::Rectangle] a rectangle contain the position and the size of the result
|
|
529
|
+
* @see SpecialInputDevice::Image#find
|
|
530
|
+
* @see SpecialInputDevice::Image::RETURN_METHOD
|
|
531
|
+
*/
|
|
532
|
+
static VALUE ruby_find_image(VARIABLE_ARGUMENTS_C) {
|
|
533
|
+
VALUE image;
|
|
534
|
+
VALUE options;
|
|
535
|
+
ID keywords[1] = {
|
|
536
|
+
rb_intern_const("area")
|
|
537
|
+
};
|
|
538
|
+
VALUE option_values[sizeof(keywords)];
|
|
539
|
+
VALUE *area = option_values + 0;
|
|
540
|
+
VALUE x = Qnil;
|
|
541
|
+
VALUE y = Qnil;
|
|
542
|
+
VALUE capture;
|
|
543
|
+
VALUE captureArguments[4];
|
|
544
|
+
VALUE result;
|
|
545
|
+
SCAN_ARGUMENTS("1:", &image, &options);
|
|
546
|
+
rb_get_kwargs(options, keywords, 0, -2, option_values);
|
|
547
|
+
if (RTEST(RUBY_OBJECT_IS_A_qs(image, rb_cString)) || RTEST(RUBY_OBJECT_IS_A_qs(image, rb_cFile)))
|
|
548
|
+
image = rb_funcall(specialInputDevice_image, rb_intern_const("load"), 1, image);
|
|
549
|
+
else if (!RTEST(RUBY_OBJECT_IS_A_qs(image, specialInputDevice_image)))
|
|
550
|
+
RAISE_SIMPLE_TYPE_ERROR(image, "String, File or SpecialInputDevice::Image");
|
|
551
|
+
if (*area == Qundef) {
|
|
552
|
+
capture = ruby_capture(0, captureArguments, self);
|
|
553
|
+
} else {
|
|
554
|
+
CHECK_TYPE_ERROR(*area, ":area", specialInputDevice_rectangle);
|
|
555
|
+
x = rb_funcall(*area, rb_intern_const("x"), 0);
|
|
556
|
+
y = rb_funcall(*area, rb_intern_const("y"), 0);
|
|
557
|
+
captureArguments[0] = x;
|
|
558
|
+
captureArguments[1] = y;
|
|
559
|
+
captureArguments[2] = rb_funcall(*area, rb_intern_const("width"), 0);
|
|
560
|
+
captureArguments[3] = rb_funcall(*area, rb_intern_const("height"), 0);
|
|
561
|
+
capture = ruby_capture(4, captureArguments, self);
|
|
562
|
+
}
|
|
563
|
+
rb_funcall(capture, rb_intern_const("save"), 1, rb_str_new_cstr("D:/2.bmp"));
|
|
564
|
+
result = rb_funcall(capture, rb_intern_const("find"), options == Qnil ? 1 : 2, image, options);
|
|
565
|
+
if (result != Qnil && *area != Qundef)
|
|
566
|
+
result = rb_funcall(result, rb_intern_const("move"), 2, x, y);
|
|
567
|
+
return result;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
//endregion display
|
|
571
|
+
|
|
572
|
+
//region input
|
|
573
|
+
|
|
574
|
+
//region keyboard
|
|
430
575
|
|
|
431
576
|
/*
|
|
432
577
|
* @overload key_hold(key_code)
|
|
@@ -438,7 +583,7 @@ static VALUE ruby_color_at(VALUE self, VALUE x, VALUE y) {
|
|
|
438
583
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646280.aspx Windows Dev Center - WM_KEYDOWN message
|
|
439
584
|
*/
|
|
440
585
|
static VALUE ruby_key_hold(VALUE self, VALUE keyCode) {
|
|
441
|
-
SID_WINDOW_DATA *cData
|
|
586
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
442
587
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
443
588
|
WPARAM cWParam = NUM2USHORT(keyCode);
|
|
444
589
|
LPARAM cLParam = 1 | (WORD) MapVirtualKeyA(cWParam, MAPVK_VK_TO_VSC) << 16;
|
|
@@ -487,7 +632,7 @@ static VALUE ruby_key_hold(VALUE self, VALUE keyCode) {
|
|
|
487
632
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646281.aspx Windows Dev Center - WM_KEYUP message
|
|
488
633
|
*/
|
|
489
634
|
static VALUE ruby_key_release(VALUE self, VALUE keyCode) {
|
|
490
|
-
SID_WINDOW_DATA *cData
|
|
635
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
491
636
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
492
637
|
WPARAM cWParam = NUM2USHORT(keyCode);
|
|
493
638
|
LPARAM cLParam = 1;
|
|
@@ -539,7 +684,7 @@ static VALUE ruby_key_release(VALUE self, VALUE keyCode) {
|
|
|
539
684
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646281.aspx Windows Dev Center - WM_KEYUP message
|
|
540
685
|
*/
|
|
541
686
|
static VALUE ruby_key_press(VALUE self, VALUE keyCode) {
|
|
542
|
-
SID_WINDOW_DATA *cData
|
|
687
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
543
688
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
544
689
|
WPARAM cWParam = NUM2USHORT(keyCode);
|
|
545
690
|
LPARAM cLParam = 1 | (WORD) MapVirtualKeyA(cWParam, MAPVK_VK_TO_VSC) << 16;
|
|
@@ -580,11 +725,11 @@ static VALUE ruby_key_press(VALUE self, VALUE keyCode) {
|
|
|
580
725
|
return self;
|
|
581
726
|
}
|
|
582
727
|
|
|
583
|
-
|
|
728
|
+
//endregion keyboard
|
|
584
729
|
|
|
585
|
-
|
|
730
|
+
//region mouse
|
|
586
731
|
|
|
587
|
-
|
|
732
|
+
//region move
|
|
588
733
|
|
|
589
734
|
/*
|
|
590
735
|
* @overload mouse_move_relatively(x, y)
|
|
@@ -597,7 +742,7 @@ static VALUE ruby_key_press(VALUE self, VALUE keyCode) {
|
|
|
597
742
|
*/
|
|
598
743
|
static VALUE ruby_mouse_move_relatively(VALUE self, VALUE x, VALUE y) {
|
|
599
744
|
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
600
|
-
HWND cHWnd
|
|
745
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
601
746
|
cData->x += NUM2SHORT(x);
|
|
602
747
|
cData->y += NUM2SHORT(y);
|
|
603
748
|
PostMessage(cHWnd, WM_MOUSEMOVE, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
@@ -616,16 +761,16 @@ static VALUE ruby_mouse_move_relatively(VALUE self, VALUE x, VALUE y) {
|
|
|
616
761
|
*/
|
|
617
762
|
static VALUE ruby_mouse_move_to(VALUE self, VALUE x, VALUE y) {
|
|
618
763
|
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
619
|
-
HWND cHWnd
|
|
764
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
620
765
|
cData->x = NUM2SHORT(x);
|
|
621
766
|
cData->y = NUM2SHORT(y);
|
|
622
767
|
PostMessage(cHWnd, WM_MOUSEMOVE, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
623
768
|
return self;
|
|
624
769
|
}
|
|
625
770
|
|
|
626
|
-
|
|
771
|
+
//endregion move
|
|
627
772
|
|
|
628
|
-
|
|
773
|
+
//region left_button
|
|
629
774
|
|
|
630
775
|
/*
|
|
631
776
|
* Simulate clicking the left button on the mouse in the window.
|
|
@@ -637,7 +782,7 @@ static VALUE ruby_mouse_move_to(VALUE self, VALUE x, VALUE y) {
|
|
|
637
782
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645608.aspx Windows Dev Center - WM_LBUTTONUP message
|
|
638
783
|
*/
|
|
639
784
|
static VALUE ruby_mouse_left_click(VALUE self) {
|
|
640
|
-
SID_WINDOW_DATA *cData
|
|
785
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
641
786
|
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
642
787
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
643
788
|
cData->flats |= FLAT_MOUSE_LEFT;
|
|
@@ -659,7 +804,7 @@ static VALUE ruby_mouse_left_click(VALUE self) {
|
|
|
659
804
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645607.aspx Windows Dev Center - WM_LBUTTONDOWN message
|
|
660
805
|
*/
|
|
661
806
|
static VALUE ruby_mouse_left_down(VALUE self) {
|
|
662
|
-
SID_WINDOW_DATA *cData
|
|
807
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
663
808
|
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
664
809
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
665
810
|
cData->flats |= FLAT_MOUSE_LEFT;
|
|
@@ -679,15 +824,15 @@ static VALUE ruby_mouse_left_down(VALUE self) {
|
|
|
679
824
|
*/
|
|
680
825
|
static VALUE ruby_mouse_left_up(VALUE self) {
|
|
681
826
|
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
682
|
-
HWND cHWnd
|
|
827
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
683
828
|
cData->flats &= ~FLAT_MOUSE_LEFT;
|
|
684
829
|
PostMessage(cHWnd, WM_LBUTTONUP, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
685
830
|
return self;
|
|
686
831
|
}
|
|
687
832
|
|
|
688
|
-
|
|
833
|
+
//endregion left_button
|
|
689
834
|
|
|
690
|
-
|
|
835
|
+
//region right_button
|
|
691
836
|
|
|
692
837
|
/*
|
|
693
838
|
* Simulate clicking the right button on the mouse in the window.
|
|
@@ -699,7 +844,7 @@ static VALUE ruby_mouse_left_up(VALUE self) {
|
|
|
699
844
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646243.aspx Windows Dev Center - WM_RBUTTONUP function
|
|
700
845
|
*/
|
|
701
846
|
static VALUE ruby_mouse_right_click(VALUE self) {
|
|
702
|
-
SID_WINDOW_DATA *cData
|
|
847
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
703
848
|
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
704
849
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
705
850
|
cData->flats |= FLAT_MOUSE_RIGHT;
|
|
@@ -721,7 +866,7 @@ static VALUE ruby_mouse_right_click(VALUE self) {
|
|
|
721
866
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646242.aspx Windows Dev Center - WM_RBUTTONDOWN function
|
|
722
867
|
*/
|
|
723
868
|
static VALUE ruby_mouse_right_down(VALUE self) {
|
|
724
|
-
SID_WINDOW_DATA *cData
|
|
869
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
725
870
|
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
726
871
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
727
872
|
cData->flats |= FLAT_MOUSE_RIGHT;
|
|
@@ -741,15 +886,15 @@ static VALUE ruby_mouse_right_down(VALUE self) {
|
|
|
741
886
|
*/
|
|
742
887
|
static VALUE ruby_mouse_right_up(VALUE self) {
|
|
743
888
|
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
744
|
-
HWND cHWnd
|
|
889
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
745
890
|
cData->flats &= ~FLAT_MOUSE_RIGHT;
|
|
746
891
|
PostMessage(cHWnd, WM_RBUTTONUP, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
747
892
|
return self;
|
|
748
893
|
}
|
|
749
894
|
|
|
750
|
-
|
|
895
|
+
//endregion right_button
|
|
751
896
|
|
|
752
|
-
|
|
897
|
+
//region middle_button
|
|
753
898
|
|
|
754
899
|
/*
|
|
755
900
|
* Simulate clicking the middle button on the mouse in the window.
|
|
@@ -761,7 +906,7 @@ static VALUE ruby_mouse_right_up(VALUE self) {
|
|
|
761
906
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645611.aspx Windows Dev Center - WM_MBUTTONUP function
|
|
762
907
|
*/
|
|
763
908
|
static VALUE ruby_mouse_middle_click(VALUE self) {
|
|
764
|
-
SID_WINDOW_DATA *cData
|
|
909
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
765
910
|
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
766
911
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
767
912
|
cData->flats |= FLAT_MOUSE_MIDDLE;
|
|
@@ -783,7 +928,7 @@ static VALUE ruby_mouse_middle_click(VALUE self) {
|
|
|
783
928
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms645610.aspx Windows Dev Center - WM_MBUTTONDOWN function
|
|
784
929
|
*/
|
|
785
930
|
static VALUE ruby_mouse_middle_down(VALUE self) {
|
|
786
|
-
SID_WINDOW_DATA *cData
|
|
931
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
787
932
|
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
788
933
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
789
934
|
cData->flats |= FLAT_MOUSE_MIDDLE;
|
|
@@ -803,15 +948,15 @@ static VALUE ruby_mouse_middle_down(VALUE self) {
|
|
|
803
948
|
*/
|
|
804
949
|
static VALUE ruby_mouse_middle_up(VALUE self) {
|
|
805
950
|
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
806
|
-
HWND cHWnd
|
|
951
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
807
952
|
cData->flats &= ~FLAT_MOUSE_MIDDLE;
|
|
808
953
|
PostMessage(cHWnd, WM_MBUTTONUP, createMouseMessageWParam(cData), createMouseMessageLParam(cData));
|
|
809
954
|
return self;
|
|
810
955
|
}
|
|
811
956
|
|
|
812
|
-
|
|
957
|
+
//endregion middle_button
|
|
813
958
|
|
|
814
|
-
|
|
959
|
+
//region x_button
|
|
815
960
|
|
|
816
961
|
/*
|
|
817
962
|
* Simulate clicking the x1 button on the mouse in the window.
|
|
@@ -823,7 +968,7 @@ static VALUE ruby_mouse_middle_up(VALUE self) {
|
|
|
823
968
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646246.aspx Windows Dev Center - WM_XBUTTONUP function
|
|
824
969
|
*/
|
|
825
970
|
static VALUE ruby_mouse_x1_click(VALUE self) {
|
|
826
|
-
SID_WINDOW_DATA *cData
|
|
971
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
827
972
|
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
828
973
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
829
974
|
cData->flats |= FLAT_MOUSE_X1;
|
|
@@ -847,7 +992,7 @@ static VALUE ruby_mouse_x1_click(VALUE self) {
|
|
|
847
992
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646245.aspx Windows Dev Center - WM_XBUTTONDOWN function
|
|
848
993
|
*/
|
|
849
994
|
static VALUE ruby_mouse_x1_down(VALUE self) {
|
|
850
|
-
SID_WINDOW_DATA *cData
|
|
995
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
851
996
|
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
852
997
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
853
998
|
cData->flats |= FLAT_MOUSE_X1;
|
|
@@ -869,7 +1014,7 @@ static VALUE ruby_mouse_x1_down(VALUE self) {
|
|
|
869
1014
|
*/
|
|
870
1015
|
static VALUE ruby_mouse_x1_up(VALUE self) {
|
|
871
1016
|
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
872
|
-
HWND cHWnd
|
|
1017
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
873
1018
|
cData->flats &= ~FLAT_MOUSE_X1;
|
|
874
1019
|
PostMessage(cHWnd, WM_XBUTTONUP, createMouseMessageWParam(cData) | XBUTTON1 << 16, createMouseMessageLParam(cData));
|
|
875
1020
|
return self;
|
|
@@ -885,7 +1030,7 @@ static VALUE ruby_mouse_x1_up(VALUE self) {
|
|
|
885
1030
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646246.aspx Windows Dev Center - WM_XBUTTONUP function
|
|
886
1031
|
*/
|
|
887
1032
|
static VALUE ruby_mouse_x2_click(VALUE self) {
|
|
888
|
-
SID_WINDOW_DATA *cData
|
|
1033
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
889
1034
|
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
890
1035
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
891
1036
|
cData->flats |= FLAT_MOUSE_X2;
|
|
@@ -909,7 +1054,7 @@ static VALUE ruby_mouse_x2_click(VALUE self) {
|
|
|
909
1054
|
* @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms646245.aspx Windows Dev Center - WM_XBUTTONDOWN function
|
|
910
1055
|
*/
|
|
911
1056
|
static VALUE ruby_mouse_x2_down(VALUE self) {
|
|
912
|
-
SID_WINDOW_DATA *cData
|
|
1057
|
+
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
913
1058
|
ULONGLONG cCurrentTime = getSystemTimeIdentifier();
|
|
914
1059
|
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
915
1060
|
cData->flats |= FLAT_MOUSE_X2;
|
|
@@ -931,15 +1076,15 @@ static VALUE ruby_mouse_x2_down(VALUE self) {
|
|
|
931
1076
|
*/
|
|
932
1077
|
static VALUE ruby_mouse_x2_up(VALUE self) {
|
|
933
1078
|
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
934
|
-
HWND cHWnd
|
|
1079
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
935
1080
|
cData->flats &= ~FLAT_MOUSE_X2;
|
|
936
1081
|
PostMessage(cHWnd, WM_XBUTTONUP, createMouseMessageWParam(cData) | XBUTTON2 << 16, createMouseMessageLParam(cData));
|
|
937
1082
|
return self;
|
|
938
1083
|
}
|
|
939
1084
|
|
|
940
|
-
|
|
1085
|
+
//endregion x_button
|
|
941
1086
|
|
|
942
|
-
|
|
1087
|
+
//region wheel
|
|
943
1088
|
|
|
944
1089
|
/*
|
|
945
1090
|
* Simulate wheeling the scroll backward in the window.
|
|
@@ -950,7 +1095,7 @@ static VALUE ruby_mouse_x2_up(VALUE self) {
|
|
|
950
1095
|
*/
|
|
951
1096
|
static VALUE ruby_mouse_scroll_wheel_backward(VALUE self) {
|
|
952
1097
|
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
953
|
-
HWND cHWnd
|
|
1098
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
954
1099
|
PostMessage(cHWnd, WM_MOUSEWHEEL, createMouseMessageWParam(cData) | -WHEEL_DELTA << 16,
|
|
955
1100
|
createMouseMessageLParam(cData));
|
|
956
1101
|
return self;
|
|
@@ -965,7 +1110,7 @@ static VALUE ruby_mouse_scroll_wheel_backward(VALUE self) {
|
|
|
965
1110
|
*/
|
|
966
1111
|
static VALUE ruby_mouse_scroll_wheel_forward(VALUE self) {
|
|
967
1112
|
SID_WINDOW_DATA *cData = GET_SELF_DATA_OBJECT();
|
|
968
|
-
HWND cHWnd
|
|
1113
|
+
HWND cHWnd = ruby___window_get_handle_code(self);
|
|
969
1114
|
PostMessage(cHWnd, WM_MOUSEWHEEL, createMouseMessageWParam(cData) | WHEEL_DELTA << 16,
|
|
970
1115
|
createMouseMessageLParam(cData));
|
|
971
1116
|
return self;
|
|
@@ -1007,11 +1152,11 @@ static VALUE ruby_mouse_scroll_wheel_to_right(VALUE self) {
|
|
|
1007
1152
|
#endif
|
|
1008
1153
|
}
|
|
1009
1154
|
|
|
1010
|
-
|
|
1155
|
+
//endregion wheel
|
|
1011
1156
|
|
|
1012
|
-
|
|
1157
|
+
//endregion mouse
|
|
1013
1158
|
|
|
1014
|
-
|
|
1159
|
+
//endregion input
|
|
1015
1160
|
|
|
1016
1161
|
VOID Init_window() {
|
|
1017
1162
|
#ifdef YARD
|
|
@@ -1058,6 +1203,8 @@ VOID Init_window() {
|
|
|
1058
1203
|
rb_define_method(specialInputDevice_window, "resize_to", ruby_resize_to, 2);
|
|
1059
1204
|
rb_define_method(specialInputDevice_window, "restore", ruby_restore, 0);
|
|
1060
1205
|
rb_define_method(specialInputDevice_window, "color_at", ruby_color_at, 2);
|
|
1206
|
+
rb_define_method(specialInputDevice_window, "capture", ruby_capture, -1);
|
|
1207
|
+
rb_define_method(specialInputDevice_window, "find_image", ruby_find_image, -1);
|
|
1061
1208
|
rb_define_method(specialInputDevice_window, "key_hold", ruby_key_hold, 1);
|
|
1062
1209
|
rb_define_method(specialInputDevice_window, "key_release", ruby_key_release, 1);
|
|
1063
1210
|
rb_define_method(specialInputDevice_window, "key_press", ruby_key_press, 1);
|
|
@@ -6,28 +6,28 @@ class SpecialInputDevice::Color
|
|
|
6
6
|
include(SpecialInputDevice::AttributesEqualChecker)
|
|
7
7
|
|
|
8
8
|
# @return [Fixnum] the level of alpha
|
|
9
|
-
attr_reader
|
|
9
|
+
attr_reader(:alpha)
|
|
10
10
|
# @param [Fixnum] value the level of alpha
|
|
11
11
|
def alpha=(value)
|
|
12
12
|
@alpha = [value.to_i, 0, 255].sort[1];
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
# @return [Fixnum] the level of blue
|
|
16
|
-
attr_reader
|
|
16
|
+
attr_reader(:blue)
|
|
17
17
|
# @param [Fixnum] value the level of blue
|
|
18
18
|
def blue=(value)
|
|
19
19
|
@blue = [value.to_i, 0, 255].sort[1];
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
# @return [Fixnum] the level of green
|
|
23
|
-
attr_reader
|
|
23
|
+
attr_reader(:green)
|
|
24
24
|
# @param [Fixnum] value the level of green
|
|
25
25
|
def green=(value)
|
|
26
26
|
@green = [value.to_i, 0, 255].sort[1];
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
# @return [Fixnum] the level of red
|
|
30
|
-
attr_reader
|
|
30
|
+
attr_reader(:red)
|
|
31
31
|
# @param [Fixnum] value the level of red
|
|
32
32
|
def red=(value)
|
|
33
33
|
@red = [value.to_i, 0, 255].sort[1];
|
|
@@ -35,7 +35,7 @@ class SpecialInputDevice::Image < Data
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
# Find the position of another smaller image in this image.
|
|
38
|
-
# @param [SpecialInputDevice::Image] image another image, should be smaller
|
|
38
|
+
# @param [SpecialInputDevice::Image, String] image another image, should be smaller
|
|
39
39
|
# @param [Float] similarity minimum limit of similarity
|
|
40
40
|
# @param [Symbol] _return indicate the behavior of this method, see SpecialInputDevice::Image::RETURN_METHOD
|
|
41
41
|
# @return [SpecialInputDevice::Rectangle, NilClass] the position
|
|
@@ -43,6 +43,7 @@ class SpecialInputDevice::Image < Data
|
|
|
43
43
|
def find(image, similarity: 1.0, _return: RETURN_METHOD::FIRST)
|
|
44
44
|
methods = RETURN_METHOD.constants(false).map { |x| RETURN_METHOD.const_get(x) }
|
|
45
45
|
raise("Undefined return method '#{_return.to_s}' passed, Defined methods are [#{methods.join(', ')}].") unless methods.include?(_return)
|
|
46
|
+
image = Image.load(image) if image.is_a?(String)
|
|
46
47
|
closest_similarity = 0.0
|
|
47
48
|
closest_similarity_x = nil
|
|
48
49
|
closest_similarity_y = nil
|
|
@@ -6,14 +6,14 @@ class SpecialInputDevice::Point
|
|
|
6
6
|
include(SpecialInputDevice::AttributesEqualChecker)
|
|
7
7
|
|
|
8
8
|
# @return [Integer] the x-coordinate of the point
|
|
9
|
-
attr_reader
|
|
9
|
+
attr_reader(:x)
|
|
10
10
|
# @param [Integer] value the x-coordinate of the point
|
|
11
11
|
def x=(value)
|
|
12
12
|
@x = value.to_i
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
# @return [Integer] the y-coordinate of the point
|
|
16
|
-
attr_reader
|
|
16
|
+
attr_reader(:y)
|
|
17
17
|
# @param [Integer] value the y-coordinate of the point
|
|
18
18
|
def y=(value)
|
|
19
19
|
@y = value.to_i
|