From 4b6b1e105ef2324da73cea565ef4dc0f0bc5318b Mon Sep 17 00:00:00 2001 From: brian Date: Sat, 23 Sep 2023 06:34:20 -0400 Subject: [PATCH 1/7] Don't push this commit --- .idea/.gitignore | 8 + .idea/auto_click.iml | 21 + .idea/deployment.xml | 21 + .idea/inspectionProfiles/Project_Default.xml | 67 ++ .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + Gemfile.lock | 9 +- auto_click.gemspec | 36 +- lib/auto_click.rb | 707 +++++++++---------- lib/auto_click/input_structure.rb | 69 +- lib/auto_click/user32.rb | 14 +- lib/auto_click/version.rb | 2 +- lib/auto_click/virtual_key.rb | 562 +-------------- 14 files changed, 586 insertions(+), 948 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/auto_click.iml create mode 100644 .idea/deployment.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/auto_click.iml b/.idea/auto_click.iml new file mode 100644 index 0000000..dadadde --- /dev/null +++ b/.idea/auto_click.iml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/deployment.xml b/.idea/deployment.xml new file mode 100644 index 0000000..18a6e04 --- /dev/null +++ b/.idea/deployment.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..b19fd24 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,67 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..081d4e1 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..051c6d7 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 5c3c698..0616a6d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,14 +1,17 @@ PATH remote: . specs: - auto_click (0.1.0) + win_auto_click (1.0.0) GEM remote: http://rubygems.org/ specs: PLATFORMS - x86-mingw32 + x64-mingw-ucrt DEPENDENCIES - auto_click! + win_auto_click! + +BUNDLED WITH + 2.4.19 diff --git a/auto_click.gemspec b/auto_click.gemspec index a4f1100..8b6ed50 100644 --- a/auto_click.gemspec +++ b/auto_click.gemspec @@ -3,24 +3,24 @@ $:.push File.expand_path("../lib", __FILE__) require "auto_click/version" Gem::Specification.new do |s| - s.name = "auto_click" - s.version = AutoClick::VERSION - s.platform = Gem::Platform::RUBY - s.authors = ["erinata"] - s.email = ["erinata@gmail.com"] - s.homepage = "https://github.com/erinata/auto_click" - s.summary = %q{Smulating mouse click, cursor movement and keystrokes} - s.description = %q{Provide several Ruby methods for simulating mouse click, cursor movement and keystrokes in Windows. + s.name = "win_auto_click" + s.version = AutoClick::VERSION + s.platform = Gem::Platform::RUBY + s.authors = ["BrianPurgert"] + s.email = ["brianpurgert2@gmail.com"] + s.homepage = "https://github.com/BrianPurgert/auto_click" + s.summary = %q{Smulating mouse click, cursor movement and keystrokes} + s.description = %q{this is a Fork of https://github.com/erinata/auto_click + Provide several Ruby methods for simulating mouse click, cursor movement and keystrokes in Windows. This gem use DL library and SendInput method so there is no dependency on FFI, AutoIt or Win32-api. Methods include mouse_move(x,y), left_click, right_click, type(string), mouse_scroll(steps), key_up, key_down...etc. - See https://github.com/erinata/auto_click for more details about instalation and usage. - (More control over mouse movement such as speed or locus will be implemented in future releases)} - - s.required_ruby_version = '>= 2.3.0' - - s.files = `git ls-files`.split("\n") - s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") - s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } - s.require_paths = ["lib"] - s.licenses = "MIT" + )} + + s.required_ruby_version = '>= 2.3.0' + + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } + s.require_paths = ["lib"] + s.licenses = "MIT" end diff --git a/lib/auto_click.rb b/lib/auto_click.rb index 57a4ffa..894d725 100644 --- a/lib/auto_click.rb +++ b/lib/auto_click.rb @@ -4,368 +4,361 @@ require 'auto_click/user32' module AutoClickMethods - @@rightdown = InputStructure.mouse_input(0,0,0,0x0008) - @@rightup = InputStructure.mouse_input(0,0,0,0x0010) - @@leftdown = InputStructure.mouse_input(0,0,0,0x0002) - @@leftup = InputStructure.mouse_input(0,0,0,0x0004) - @@middledown = InputStructure.mouse_input(0,0,0,0x0020) - @@middleup = InputStructure.mouse_input(0,0,0,0x0040) - - - def send_input(inputs) - n = inputs.size - ptr = inputs.collect {|i| i.to_s}.join - User32.SendInput(n, ptr, inputs[0].size) - end - - def get_screen_resolution - [User32.GetSystemMetrics(0), User32.GetSystemMetrics(1)] - end - - def mouse_move(x,y) - User32.SetCursorPos(x,y) - end - - def mouse_move_percentage(x,y) - screen_resolution = get_screen_resolution() - User32.SetCursorPos(screen_resolution[0]*x, screen_resolution[1]*y) - end - - - def right_click - send_input( [@@rightdown, @@rightup] ) - end - - def left_click - send_input( [@@leftdown, @@leftup] ) - end - - def middle_click - send_input( [@@middledown, @@middleup] ) - end - - def mouse_down(button_name) - case button_name - when :right - send_input( [@@rightdown] ) - when :middle - send_input( [@@middledown] ) - else - send_input( [@@leftdown] ) - end - end - - def mouse_up(button_name) - case button_name - when :right - send_input( [@@rightup] ) - when :middle - send_input( [@@middleup] ) - else - send_input( [@@leftup] ) - end - end - - def double_click - left_click - left_click - end - - ################# TEMP ##################### - - - @@rightdown32 = InputStructure.mouse_input_32(0,0,0,0x0008) - @@rightup32 = InputStructure.mouse_input_32(0,0,0,0x0010) - @@leftdown32 = InputStructure.mouse_input_32(0,0,0,0x0002) - @@leftup32 = InputStructure.mouse_input_32(0,0,0,0x0004) - @@middledown32 = InputStructure.mouse_input_32(0,0,0,0x0020) - @@middleup32 = InputStructure.mouse_input_32(0,0,0,0x0040) - - - def right_click_32 - send_input( [@@rightdown32, @@rightup32] ) - end - - def left_click_32 - send_input( [@@leftdown32, @@leftup32] ) - end - - def middle_click_32 - send_input( [@@middledown32, @@middleup32] ) - end - - def mouse_down_32(button_name) - case button_name - when :right - send_input( [@@rightdown32] ) - when :middle - send_input( [@@middledown32] ) - else - send_input( [@@leftdown32] ) - end - end - - def mouse_up_32(button_name) - case button_name - when :right - send_input( [@@rightup32] ) - when :middle - send_input( [@@middleup32] ) - else - send_input( [@@leftup32] ) - end - end - - def double_click_32 - left_click_32 - left_click_32 - end - - - def left_drag_32(sx,sy,ex,ey) - mouse_move sx,sy - sleep 0.1 - send_input( [@@leftdown32] ) - sleep 0.1 - mouse_move ex,ey - sleep 0.1 - send_input( [@@leftup32] ) - sleep 0.1 - end - - def right_drag_32(sx,sy,ex,ey) - mouse_move sx,sy - sleep 0.1 - send_input( [@@rightdown32] ) - sleep 0.1 - mouse_move ex,ey - sleep 0.1 - send_input( [@@rightup32] ) - sleep 0.1 - end - - def key_stroke_32(key_name) - code=VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input_32(code,0x0000), - InputStructure.keyboard_input_32(code,0x0002)]) - end - - def key_down_32(key_name) - code=VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input_32(code,0x0000)]) - end - - def key_up_32(key_name) - code=VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input_32(code,0x0002)]) - end - -################# END TEMP ##################### - - def cursor_position - point = " " * 8 - User32.GetCursorPos(point) - point.unpack('LL') - end - - def mouse_scroll(d) - scroll = InputStructure.mouse_input(0,0,d*120,0x0800) - send_input( [scroll]) - end - - - def left_drag(sx,sy,ex,ey) - mouse_move sx,sy - sleep 0.1 - send_input( [@@leftdown] ) - sleep 0.1 - mouse_move ex,ey - sleep 0.1 - send_input( [@@leftup] ) - sleep 0.1 - end - - def right_drag(sx,sy,ex,ey) - mouse_move sx,sy - sleep 0.1 - send_input( [@@rightdown] ) - sleep 0.1 - mouse_move ex,ey - sleep 0.1 - send_input( [@@rightup] ) - sleep 0.1 - end - - def key_stroke(key_name) - code=VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input(code,0x0000), - InputStructure.keyboard_input(code,0x0002)]) - end - - def key_down(key_name) - code=VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input(code,0x0000)]) - end - - def key_up(key_name) - code=VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input(code,0x0002)]) - end - - def type(string) - key_stroke(:capslock) if get_key_state(:capslock)==1 - string=string.to_s - string.each_char do |c| - if ('a'..'z').include? c - key_stroke(c.to_sym) - elsif ('A'..'Z').include? c - key_down(:leftshift) - key_stroke(c.to_sym) - key_up(:leftshift) - elsif ('0'..'9').include? c - key_stroke(('num'+c).to_sym) - else - case c - when ' ' - key_stroke(:space) - when ';' - key_stroke(:semicolon) - when ':' - key_down(:leftshift) - key_stroke(:semicolon) - key_up(:leftshift) - when '=' - key_stroke(:equal) - when '+' - key_down(:leftshift) - key_stroke(:plus) - key_up(:leftshift) - when ',' - key_stroke(:comma) - when '<' - key_down(:leftshift) - key_stroke(:smallerthan) - key_up(:leftshift) - when '-' - key_stroke(:hyphen) - when '_' - key_down(:leftshift) - key_stroke(:underscore) - key_up(:leftshift) - when '.' - key_stroke(:period) - when '>' - key_down(:leftshift) - key_stroke(:greaterthan) - key_up(:leftshift) - when '/' - key_stroke(:slash) - when '?' - key_down(:leftshift) - key_stroke(:question) - key_up(:leftshift) - when '`' - key_stroke(:grave) - when '~' - key_down(:leftshift) - key_stroke(:tilde) - key_up(:leftshift) - when '/' - key_stroke(:slash) - when '?' - key_down(:leftshift) - key_stroke(:question) - key_up(:leftshift) - when '[' - key_stroke(:branket) - when '{' - key_down(:leftshift) - key_stroke(:branket) - key_up(:leftshift) - when ']' - key_stroke(:closebranket) - when '}' - key_down(:leftshift) - key_stroke(:closebranket) - key_up(:leftshift) - when '\\' # You need to esapce \ in the parameter string - key_stroke(:backslash) - when '|' - key_down(:leftshift) - key_stroke(:pipe) - key_up(:leftshift) - when '\'' # escape ' only for single quote string - key_stroke(:quote) - when '"' # escape " only for double quote string - key_down(:leftshift) - key_stroke(:doublequote) - key_up(:leftshift) - when '!' - key_down(:leftshift) - key_stroke(:num1) - key_up(:leftshift) - when '@' - key_down(:leftshift) - key_stroke(:num2) - key_up(:leftshift) - when '#' # The sharp sign need to be escape in single quote string - key_down(:leftshift) - key_stroke(:num3) - key_up(:leftshift) - when '$' - key_down(:leftshift) - key_stroke(:num4) - key_up(:leftshift) - when '%' - key_down(:leftshift) - key_stroke(:num5) - key_up(:leftshift) - when '^' - key_down(:leftshift) - key_stroke(:num6) - key_up(:leftshift) - when '&' - key_down(:leftshift) - key_stroke(:num7) - key_up(:leftshift) - when '*' - key_down(:leftshift) - key_stroke(:num8) - key_up(:leftshift) - when '(' - key_down(:leftshift) - key_stroke(:num9) - key_up(:leftshift) - when ')' - key_down(:leftshift) - key_stroke(:num0) - key_up(:leftshift) - end - - end - end - end - - def get_key_state(key_name) - code=VirtualKey.code_from_name(key_name) - User32.GetKeyState(code) - # For normal keys (such as a) - # When the key is down the value is -128 - # When the key is up the value is 0 - - # For toggle keys (such as capslock) - # When the cap key is down and the caplock is on the value is -127 - # When the cap key is down and the caplock is off the value is -128 - # When the cap key is Up and the caplock is on the value is 1 - # When the cap key is Up and the caplock is off the value is 0 - end -end + @@rightdown = InputStructure.mouse_input(0, 0, 0, 0x0008) + @@rightup = InputStructure.mouse_input(0, 0, 0, 0x0010) + @@leftdown = InputStructure.mouse_input(0, 0, 0, 0x0002) + @@leftup = InputStructure.mouse_input(0, 0, 0, 0x0004) + @@middledown = InputStructure.mouse_input(0, 0, 0, 0x0020) + @@middleup = InputStructure.mouse_input(0, 0, 0, 0x0040) + + def send_input(inputs) + n = inputs.size + ptr = inputs.collect { |i| i.to_s }.join + User32.SendInput(n, ptr, inputs[0].size) + end + + def get_screen_resolution + [User32.GetSystemMetrics(0), User32.GetSystemMetrics(1)] + end + + def mouse_move(x, y) + User32.SetCursorPos(x, y) + end + + def mouse_move_percentage(x, y) + screen_resolution = get_screen_resolution() + User32.SetCursorPos(screen_resolution[0] * x, screen_resolution[1] * y) + end + + def right_click + send_input([@@rightdown, @@rightup]) + end + + def left_click + send_input([@@leftdown, @@leftup]) + end + + def middle_click + send_input([@@middledown, @@middleup]) + end + + def mouse_down(button_name) + case button_name + when :right + send_input([@@rightdown]) + when :middle + send_input([@@middledown]) + else + send_input([@@leftdown]) + end + end + + def mouse_up(button_name) + case button_name + when :right + send_input([@@rightup]) + when :middle + send_input([@@middleup]) + else + send_input([@@leftup]) + end + end + + def double_click + left_click + left_click + end + + ################# TEMP ##################### + + @@rightdown32 = InputStructure.mouse_input_32(0, 0, 0, 0x0008) + @@rightup32 = InputStructure.mouse_input_32(0, 0, 0, 0x0010) + @@leftdown32 = InputStructure.mouse_input_32(0, 0, 0, 0x0002) + @@leftup32 = InputStructure.mouse_input_32(0, 0, 0, 0x0004) + @@middledown32 = InputStructure.mouse_input_32(0, 0, 0, 0x0020) + @@middleup32 = InputStructure.mouse_input_32(0, 0, 0, 0x0040) + + def right_click_32 + send_input([@@rightdown32, @@rightup32]) + end + + def left_click_32 + send_input([@@leftdown32, @@leftup32]) + end + + def middle_click_32 + send_input([@@middledown32, @@middleup32]) + end + + def mouse_down_32(button_name) + case button_name + when :right + send_input([@@rightdown32]) + when :middle + send_input([@@middledown32]) + else + send_input([@@leftdown32]) + end + end + + def mouse_up_32(button_name) + case button_name + when :right + send_input([@@rightup32]) + when :middle + send_input([@@middleup32]) + else + send_input([@@leftup32]) + end + end + def double_click_32 + left_click_32 + left_click_32 + end + + def left_drag_32(sx, sy, ex, ey) + mouse_move sx, sy + sleep 0.1 + send_input([@@leftdown32]) + sleep 0.1 + mouse_move ex, ey + sleep 0.1 + send_input([@@leftup32]) + sleep 0.1 + end + + def right_drag_32(sx, sy, ex, ey) + mouse_move sx, sy + sleep 0.1 + send_input([@@rightdown32]) + sleep 0.1 + mouse_move ex, ey + sleep 0.1 + send_input([@@rightup32]) + sleep 0.1 + end + + def key_stroke_32(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input_32(code, 0x0000), + InputStructure.keyboard_input_32(code, 0x0002)]) + end + + def key_down_32(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input_32(code, 0x0000)]) + end + + def key_up_32(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input_32(code, 0x0002)]) + end + + ################# END TEMP ##################### + + def cursor_position + point = " " * 8 + User32.GetCursorPos(point) + point.unpack('LL') + end + + def mouse_scroll(d) + scroll = InputStructure.mouse_input(0, 0, d * 120, 0x0800) + send_input([scroll]) + end + + def left_drag(sx, sy, ex, ey) + mouse_move sx, sy + sleep 0.1 + send_input([@@leftdown]) + sleep 0.1 + mouse_move ex, ey + sleep 0.1 + send_input([@@leftup]) + sleep 0.1 + end + + def right_drag(sx, sy, ex, ey) + mouse_move sx, sy + sleep 0.1 + send_input([@@rightdown]) + sleep 0.1 + mouse_move ex, ey + sleep 0.1 + send_input([@@rightup]) + sleep 0.1 + end + + def key_stroke(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input(code, 0x0000), + InputStructure.keyboard_input(code, 0x0002)]) + end + + def key_down(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input(code, 0x0000)]) + end + + def key_up(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input(code, 0x0002)]) + end + + def type(string) + key_stroke(:capslock) if get_key_state(:capslock) == 1 + string = string.to_s + string.each_char do |c| + if ('a'..'z').include? c + key_stroke(c.to_sym) + elsif ('A'..'Z').include? c + key_down(:leftshift) + key_stroke(c.to_sym) + key_up(:leftshift) + elsif ('0'..'9').include? c + key_stroke(('num' + c).to_sym) + else + case c + when ' ' + key_stroke(:space) + when ';' + key_stroke(:semicolon) + when ':' + key_down(:leftshift) + key_stroke(:semicolon) + key_up(:leftshift) + when '=' + key_stroke(:equal) + when '+' + key_down(:leftshift) + key_stroke(:plus) + key_up(:leftshift) + when ',' + key_stroke(:comma) + when '<' + key_down(:leftshift) + key_stroke(:smallerthan) + key_up(:leftshift) + when '-' + key_stroke(:hyphen) + when '_' + key_down(:leftshift) + key_stroke(:underscore) + key_up(:leftshift) + when '.' + key_stroke(:period) + when '>' + key_down(:leftshift) + key_stroke(:greaterthan) + key_up(:leftshift) + when '/' + key_stroke(:slash) + when '?' + key_down(:leftshift) + key_stroke(:question) + key_up(:leftshift) + when '`' + key_stroke(:grave) + when '~' + key_down(:leftshift) + key_stroke(:tilde) + key_up(:leftshift) + when '/' + key_stroke(:slash) + when '?' + key_down(:leftshift) + key_stroke(:question) + key_up(:leftshift) + when '[' + key_stroke(:branket) + when '{' + key_down(:leftshift) + key_stroke(:branket) + key_up(:leftshift) + when ']' + key_stroke(:closebranket) + when '}' + key_down(:leftshift) + key_stroke(:closebranket) + key_up(:leftshift) + when '\\' # You need to esapce \ in the parameter string + key_stroke(:backslash) + when '|' + key_down(:leftshift) + key_stroke(:pipe) + key_up(:leftshift) + when '\'' # escape ' only for single quote string + key_stroke(:quote) + when '"' # escape " only for double quote string + key_down(:leftshift) + key_stroke(:doublequote) + key_up(:leftshift) + when '!' + key_down(:leftshift) + key_stroke(:num1) + key_up(:leftshift) + when '@' + key_down(:leftshift) + key_stroke(:num2) + key_up(:leftshift) + when '#' # The sharp sign need to be escape in single quote string + key_down(:leftshift) + key_stroke(:num3) + key_up(:leftshift) + when '$' + key_down(:leftshift) + key_stroke(:num4) + key_up(:leftshift) + when '%' + key_down(:leftshift) + key_stroke(:num5) + key_up(:leftshift) + when '^' + key_down(:leftshift) + key_stroke(:num6) + key_up(:leftshift) + when '&' + key_down(:leftshift) + key_stroke(:num7) + key_up(:leftshift) + when '*' + key_down(:leftshift) + key_stroke(:num8) + key_up(:leftshift) + when '(' + key_down(:leftshift) + key_stroke(:num9) + key_up(:leftshift) + when ')' + key_down(:leftshift) + key_stroke(:num0) + key_up(:leftshift) + end + + end + end + end + + def get_key_state(key_name) + code = VirtualKey.code_from_name(key_name) + User32.GetKeyState(code) + # For normal keys (such as a) + # When the key is down the value is -128 + # When the key is up the value is 0 + + # For toggle keys (such as capslock) + # When the cap key is down and the caplock is on the value is -127 + # When the cap key is down and the caplock is off the value is -128 + # When the cap key is Up and the caplock is on the value is 1 + # When the cap key is Up and the caplock is off the value is 0 + end +end # include AutoClick # This line allow auto include when the user require the gem class AutoClick - include AutoClickMethods + include AutoClickMethods end diff --git a/lib/auto_click/input_structure.rb b/lib/auto_click/input_structure.rb index 567b9f6..b4a1a0f 100644 --- a/lib/auto_click/input_structure.rb +++ b/lib/auto_click/input_structure.rb @@ -1,40 +1,39 @@ module InputStructure - def self.mouse_input(dx,dy,mouse_data,dw_flags) - mi = Array.new(7, 0) - mi[0] = 0 - mi[1] = dx - mi[2] = dy - mi[3] = mouse_data - mi[4] = dw_flags - mi.pack('QLLLLQQ') - end - - def self.keyboard_input(wVk,dw_flags) - ki = Array.new(7, 0) - ki[0] = 1 - ki[1] = wVk - ki[2] = dw_flags - ki.pack('QLLLLQQ') - end + def self.mouse_input(dx, dy, mouse_data, dw_flags) + mi = Array.new(7, 0) + mi[0] = 0 + mi[1] = dx + mi[2] = dy + mi[3] = mouse_data + mi[4] = dw_flags + mi.pack('QLLLLQQ') + end - def self.mouse_input_32(dx,dy,mouse_data,dw_flags) - mi = Array.new(7, 0) - mi[0] = 0 - mi[1] = dx - mi[2] = dy - mi[3] = mouse_data - mi[4] = dw_flags - mi.pack('LLLLLLL') - end - - def self.keyboard_input_32(wVk,dw_flags) - ki = Array.new(7, 0) - ki[0] = 1 - ki[1] = wVk - ki[2] = dw_flags - ki.pack('LLLLLLL') - end + def self.keyboard_input(wVk, dw_flags) + ki = Array.new(7, 0) + ki[0] = 1 + ki[1] = wVk + ki[2] = dw_flags + ki.pack('QLLLLQQ') + end + + def self.mouse_input_32(dx, dy, mouse_data, dw_flags) + mi = Array.new(7, 0) + mi[0] = 0 + mi[1] = dx + mi[2] = dy + mi[3] = mouse_data + mi[4] = dw_flags + mi.pack('LLLLLLL') + end + + def self.keyboard_input_32(wVk, dw_flags) + ki = Array.new(7, 0) + ki[0] = 1 + ki[1] = wVk + ki[2] = dw_flags + ki.pack('LLLLLLL') + end - end \ No newline at end of file diff --git a/lib/auto_click/user32.rb b/lib/auto_click/user32.rb index 124e1cc..3bbd949 100644 --- a/lib/auto_click/user32.rb +++ b/lib/auto_click/user32.rb @@ -1,9 +1,9 @@ module User32 - extend Fiddle::Importer - dlload 'user32' - extern "int GetCursorPos(char*)" - extern "int SetCursorPos(int,int)" - extern "int SendInput(int,char*,int)" - extern "int GetKeyState(int)" - extern "int GetSystemMetrics(int)" + extend Fiddle::Importer + dlload 'user32' + extern "int GetCursorPos(char*)" + extern "int SetCursorPos(int,int)" + extern "int SendInput(int,char*,int)" + extern "int GetKeyState(int)" + extern "int GetSystemMetrics(int)" end diff --git a/lib/auto_click/version.rb b/lib/auto_click/version.rb index e6f36dd..e5be056 100644 --- a/lib/auto_click/version.rb +++ b/lib/auto_click/version.rb @@ -1,3 +1,3 @@ module AutoClick - VERSION = "0.5.9" + VERSION = "1.0.0" end diff --git a/lib/auto_click/virtual_key.rb b/lib/auto_click/virtual_key.rb index 83c5551..0962b4a 100644 --- a/lib/auto_click/virtual_key.rb +++ b/lib/auto_click/virtual_key.rb @@ -1,530 +1,38 @@ module VirtualKey - def self.code_from_name(name) + KEYNAMES_TO_CODES = { + back: 0x08, backspace: 0x08, tab: 0x09, clear: 0x0C, + return: 0x0D, enter: 0x0D, shift: 0x10, ctrl: 0x11, + control: 0x11, alt: 0x12, alternate: 0x12, pause: 0x13, + cap: 0x14, capslock: 0x14, caplock: 0x14, esc: 0x1B, + escape: 0x1B, space: 0x20, spacebar: 0x20, pageup: 0x21, + pagedown: 0x22, end: 0x23, home: 0x24, left: 0x25, + leftarrow: 0x25, leftkey: 0x25, up: 0x26, uparrow: 0x26, + upkey: 0x26, right: 0x27, rightarrow: 0x27, rightkey: 0x27, + down: 0x28, downarrow: 0x28, downkey: 0x28, select: 0x29, + print: 0x2A, exe: 0x2B, execute: 0x2B, printscr: 0x2C, + printscreen: 0x2C, ins: 0x2D, insert: 0x2D, del: 0x2E, + delete: 0x2E, help: 0x2F, num0: 0x30, number0: 0x30, + num1: 0x31, number1: 0x31, num2: 0x32, number2: 0x32, + num3: 0x33, number3: 0x33, num4: 0x34, number4: 0x34, num5: 0x35, number5: 0x35, + num6: 0x36, number6: 0x36, num7: 0x37, number7: 0x37, num8: 0x38, number8: 0x38, + num9: 0x39, number9: 0x39, a: 0x41, b: 0x42, c: 0x43, d: 0x44, + e: 0x45, f: 0x46, g: 0x47, h: 0x48, i: 0x49, j: 0x4A, + k: 0x4B, l: 0x4C, m: 0x4D, n: 0x4E, o: 0x4F, p: 0x50, + q: 0x51, r: 0x52, s: 0x53, t: 0x54, u: 0x55, v: 0x56, + w: 0x57, x: 0x58, y: 0x59, z: 0x5A, win: 0x5B, windows: 0x5B, + leftwin: 0x5B, rightwin: 0x5C, app: 0x5D, application: 0x5D, + # and so on... + + }.freeze + + def self.code_from_name(name) + return name if name.is_a? Integer + + if name.is_a? String + name = name.downcase.delete('_- ').to_sym + end + + KEYNAMES_TO_CODES.fetch(name, 0) + end - if name.kind_of? Fixnum - return name - elsif name.kind_of? String - name=name.delete('_').delete('-').delete(' ') - end - name = name.to_sym.downcase - case name - #when - # 0x00S - #when - # 0x01 - #when - # 0x02 - #when - # 0x03 - #when - # 0x04 - #when - # 0x05 - #when - # 0x06 - #when - # 0x07 - when :back,:backspace - 0x08 - when :tab - 0x09 - #when - # 0x0A - #when - # 0x0B - when :clear - 0x0C - when :return,:enter - 0x0D - #when - # 0x0E - #when - # 0x0F - when :shift - 0x10 - when :ctrl,:control - 0x11 - when :alt,:alternate - 0x12 - when :pause - 0x13 - when :cap,:capslock,:caplock - 0x14 - #when - # 0x15 - #when - # 0x16 - #when - # 0x17 - #when - # 0x18 - #when - # 0x19 - #when - # 0x1A - when :esc,:escape - 0x1B - #when - # 0x1C - #when - # 0x1D - #when - # 0x1E - #when - # 0x1F - when :space,:spacebar - 0x20 - when :pageup - 0x21 - when :pagedown - 0x22 - when :end - 0x23 - when :home - 0x24 - when :left,:leftarrow,:leftkey - 0x25 - when :up,:uparrow,:upkey - 0x26 - when :right,:rightarrow,:rightkey - 0x27 - when :down,:downarrow,:downkey - 0x28 - when :select - 0x29 - when :print - 0x2A - when :exe,:execute - 0x2B - when :printscr,:printscreen - 0x2C - when :ins,:insert - 0x2D - when :del,:delete - 0x2E - when :help - 0x2F - when :num0,:number0 - 0x30 - when :num1,:number1 - 0x31 - when :num2,:number2 - 0x32 - when :num3,:number3 - 0x33 - when :num4,:number4 - 0x34 - when :num5,:number5 - 0x35 - when :num6,:number6 - 0x36 - when :num7,:number7 - 0x37 - when :num8,:number8 - 0x38 - when :num9,:number9 - 0x39 - #when - # 0x3A - #when - # 0x3B - #when - # 0x3C - #when - # 0x3D - #when - # 0x3E - #when - # 0x3F - #when - # 0x40 - when :a - 0x41 - when :b - 0x42 - when :c - 0x43 - when :d - 0x44 - when :e - 0x45 - when :f - 0x46 - when :g - 0x47 - when :h - 0x48 - when :i - 0x49 - when :j - 0x4A - when :k - 0x4B - when :l - 0x4C - when :m - 0x4D - when :n - 0x4E - when :o - 0x4F - when :p - 0x50 - when :q - 0x51 - when :r - 0x52 - when :s - 0x53 - when :t - 0x54 - when :u - 0x55 - when :v - 0x56 - when :w - 0x57 - when :x - 0x58 - when :y - 0x59 - when :z - 0x5A - when :win, :windows,:leftwin - 0x5B - when :rightwin - 0x5C - when :app,:application - 0x5D - #when - # 0x5E - when :sleep - 0x5F - when :numpad0,:numberpad0 - 0x60 - when :numpad1,:numberpad1 - 0x61 - when :numpad2,:numberpad2 - 0x62 - when :numpad3,:numberpad3 - 0x63 - when :numpad4,:numberpad4 - 0x64 - when :numpad5,:numberpad5 - 0x65 - when :numpad6,:numberpad6 - 0x66 - when :numpad7,:numberpad7 - 0x67 - when :numpad8,:numberpad8 - 0x68 - when :numpad9,:numberpad9 - 0x69 - when :multiply,:multiplication - 0x6A - when :add,:addition - 0x6B - when :separator - 0x6C - when :substract,:subtraction - 0x6D - when :decimal - 0x6E - when :divide,:division - 0x6F - when :f1 - 0x70 - when :f2 - 0x71 - when :f3 - 0x72 - when :f4 - 0x73 - when :f5 - 0x74 - when :f6 - 0x75 - when :f7 - 0x76 - when :f8 - 0x77 - when :f9 - 0x78 - when :f10 - 0x79 - when :f11 - 0x7A - when :f12 - 0x7B - when :f13 - 0x7C - when :f14 - 0x7D - when :f15 - 0x7E - when :f16 - 0x7F - when :f17 - 0x80 - when :f18 - 0x81 - when :f19 - 0x82 - when :f20 - 0x83 - when :f21 - 0x84 - when :f22 - 0x85 - when :f23 - 0x86 - when :f24 - 0x87 - #when - # 0x88 - #when - # 0x89 - #when - # 0x8A - #when - # 0x8B - #when - # 0x8C - #when - # 0x8D - #when - # 0x8E - #when - # 0x8F - when :numlock,:numberlock - 0x90 - when :scroll,:scrolllock - 0x91 - #when - # 0x92 - #when - # 0x93 - #when - # 0x94 - #when - # 0x95 - #when - # 0x96 - #when - # 0x97 - #when - # 0x98 - #when - # 0x99 - #when - # 0x9A - #when - # 0x9B - #when - # 0x9C - #when - # 0x9D - #when - # 0x9E - #when - # 0x9F - when :leftshift - 0xA0 - when :rightshift - 0xA1 - when :leftcontrol,:leftctrl - 0xA2 - when :rightcontrol,:rightctrl - 0xA3 - when :menu,:leftmenu - 0xA4 - when :rightmenu - 0xA5 - when :browserback - 0xA6 - when :browserforward - 0xA7 - when :browserrefresh - 0xA8 - when :browserstop - 0xA9 - when :browsersearch - 0xAA - when :browserfav,:browserfavourites - 0xAB - when :browserstart,:browserhome - 0xAC - when :mute,:volmute,:volumemute - 0xAD - when :voldown,:volumedown - 0xAE - when :volup,:volumeup - 0xAF - when :nexttrack - 0xB0 - when :previoustrack - 0xB1 - when :mediastop - 0xB2 - when :mediaplay,:mediapause - 0xB3 - when :mail - 0xB4 - when :mediaselect - 0xB5 - when :app1,:application1 - 0xB6 - when :app2,:application2 - 0xB7 - #when - # 0xB8 - #when - # 0xB9 - when :semicolon,:colon - 0xBA - when :equal, :plus - 0xBB - when :comma, :smallerthan - 0xBC - when :hyphen,:underscore,:understrike - 0xBD - when :period, :dot, :greaterthan - 0xBE - when :slash,:question,:questionmark,:forwardslash - 0xBF - when :grave, :graveaccent, :tilde,:leftquote - 0xC0 - #when - # 0xC1 - #when - # 0xC2 - #when - # 0xC3 - #when - # 0xC4 - #when - # 0xC5 - #when - # 0xC6 - #when - # 0xC7 - #when - # 0xC8 - #when - # 0xC9 - #when - # 0xCA - #when - # 0xCB - #when - # 0xCC - #when - # 0xCD - #when - # 0xCE - #when - # 0xCF - #when - # 0xD0 - #when - # 0xD1 - #when - # 0xD2 - #when - # 0xD3 - #when - # 0xD4 - #when - # 0xD5 - #when - # 0xD6 - #when - # 0xD7 - #when - # 0xD8 - #when - # 0xD9 - #when - # 0xDA - when :branket, :openbranket, :leftbranket, :opensquarebranket, :leftsquarebranket, :squarebranket, :curlybranket, :opencurlybranket, :leftcurlybranket - 0xDB - when :pipe, :pipes, :bar, :brokenbar, :backslash - 0xDC - when :closebranket, :closesquarebranket, :rightbranket, :rightsquarebranket, :closecurlybranket, :rightcurlybranket - 0xDD - when :quote,:singlequote,:doublequote, :rightquote, :acute, :acuteaccent - 0xDE - #when - # 0xDF - #when - # 0xE0 - #when - # 0xE1 - #when - # 0xE2 - #when - # 0xE3 - #when - # 0xE4 - #when - # 0xE5 - #when - # 0xE6 - #when - # 0xE7 - #when - # 0xE8 - #when - # 0xE9 - #when - # 0xEA - #when - # 0xEB - #when - # 0xEC - #when - # 0xED - #when - # 0xEE - #when - # 0xEF - #when - # 0xF0 - #when - # 0xF1 - #when - # 0xF2 - #when - # 0xF3 - #when - # 0xF4 - #when - # 0xF5 - #when - # 0xF6 - #when - # 0xF7 - #when - # 0xF8 - #when - # 0xF9 - when :play - 0xFA - when :zoom - 0xFB - #when - # 0xFC - #when - # 0xFD - #when - # 0xFE - #when - # 0xFF - else - 0 - end - end - - - end From 1f46695e78f8c87e60cd4da5fd757efd429f167c Mon Sep 17 00:00:00 2001 From: brian Date: Sun, 1 Oct 2023 03:59:43 -0400 Subject: [PATCH 2/7] Does anyone read this? I'll be at the coffee shop accross the street. --- README.rdoc | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.rdoc b/README.rdoc index 4e66b5a..e5efbe3 100644 --- a/README.rdoc +++ b/README.rdoc @@ -23,9 +23,6 @@ To move the mouse cursor to 50,50 ( the top left corner is 0,0) and perform a do mouse_move(50,50) double_click - -To move the mouse cursor to 50,50 and perform a right click: - mouse_move(50,50) right_click From bc922d2dcbb6bce5211a188e8386eb0b67572939 Mon Sep 17 00:00:00 2001 From: BrianPurgert Date: Fri, 24 Nov 2023 02:02:59 -0500 Subject: [PATCH 3/7] 1 --- .idea/auto_click.iml | 2 +- Gemfile.lock | 6 +- README.rdoc | 48 --- auto_click.gemspec | 28 +- lib/auto_click.rb | 706 +++++++++++++++++----------------- lib/auto_click/version.rb | 2 +- lib/auto_click/virtual_key.rb | 166 ++++++-- 7 files changed, 507 insertions(+), 451 deletions(-) diff --git a/.idea/auto_click.iml b/.idea/auto_click.iml index dadadde..c905b43 100644 --- a/.idea/auto_click.iml +++ b/.idea/auto_click.iml @@ -11,7 +11,7 @@ - + + + + + + \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 0616a6d..dff70e3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - win_auto_click (1.0.0) + auto_click (1.0.1) GEM remote: http://rubygems.org/ @@ -11,7 +11,7 @@ PLATFORMS x64-mingw-ucrt DEPENDENCIES - win_auto_click! + auto_click! BUNDLED WITH - 2.4.19 + 2.4.20 diff --git a/README.rdoc b/README.rdoc index e5efbe3..2671d86 100644 --- a/README.rdoc +++ b/README.rdoc @@ -203,51 +203,3 @@ you can construct a new instance of AutoClick and invoke the methods from the in - key_down(key_name) - key_up(key_name) - -== To Do List - -- Backward compatibility with 32-bit Ruby - -- Add options of movement speed of mouse so the cursor is actually "moving" instead of just show up at the destination instantly - -- GetWindow and GetWindowFocus Method - -- Refactor the ugly type(string) method - -- Use code block to implement modifier keys - -- More effective way to move mouse relative to current position - -== Change log -(for full change log please refer to the CHANGELOG file in the repository) - -- 0.5.0 Users have to explicitly use "include AutoClickMethods" to include the methods, add mouse_move_percentage and get_screen_resolution - -- 0.4.0 Fix the 64bit bug and Fixnum! bug - -- 0.3.0 Update to use DL Library - - -== License - -MIT license - -Copyright (C) 2010-2019 by Chungsang Tom Lam - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/auto_click.gemspec b/auto_click.gemspec index 8b6ed50..71c281c 100644 --- a/auto_click.gemspec +++ b/auto_click.gemspec @@ -1,26 +1,25 @@ # -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) require "auto_click/version" - Gem::Specification.new do |s| - s.name = "win_auto_click" - s.version = AutoClick::VERSION - s.platform = Gem::Platform::RUBY - s.authors = ["BrianPurgert"] - s.email = ["brianpurgert2@gmail.com"] - s.homepage = "https://github.com/BrianPurgert/auto_click" - s.summary = %q{Smulating mouse click, cursor movement and keystrokes} - s.description = %q{this is a Fork of https://github.com/erinata/auto_click + s.name = "auto_click" + s.version = AutoClick::VERSION + s.platform = Gem::Platform::RUBY + s.authors = ["erinata", "BrianPurgert"] + s.email = ["erinata@gmail.com", "brianpurgert2@gmail.com"] + s.homepage = "https://github.com/BrianPurgert/auto_click" + s.summary = %q{Smulating mouse click, cursor movement and keystrokes} + s.description = %q{this is a Fork of https://github.com/erinata/auto_click Provide several Ruby methods for simulating mouse click, cursor movement and keystrokes in Windows. This gem use DL library and SendInput method so there is no dependency on FFI, AutoIt or Win32-api. Methods include mouse_move(x,y), left_click, right_click, type(string), mouse_scroll(steps), key_up, key_down...etc. )} + s.required_ruby_version = '>= 2.3.0' + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } + s.require_paths = ["lib"] + s.licenses = "MIT" +end - s.required_ruby_version = '>= 2.3.0' - s.files = `git ls-files`.split("\n") - s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") - s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } - s.require_paths = ["lib"] - s.licenses = "MIT" -end diff --git a/lib/auto_click.rb b/lib/auto_click.rb index 894d725..32fc1de 100644 --- a/lib/auto_click.rb +++ b/lib/auto_click.rb @@ -2,363 +2,362 @@ require 'auto_click/input_structure' require 'auto_click/virtual_key' require 'auto_click/user32' - module AutoClickMethods - @@rightdown = InputStructure.mouse_input(0, 0, 0, 0x0008) - @@rightup = InputStructure.mouse_input(0, 0, 0, 0x0010) - @@leftdown = InputStructure.mouse_input(0, 0, 0, 0x0002) - @@leftup = InputStructure.mouse_input(0, 0, 0, 0x0004) - @@middledown = InputStructure.mouse_input(0, 0, 0, 0x0020) - @@middleup = InputStructure.mouse_input(0, 0, 0, 0x0040) - - def send_input(inputs) - n = inputs.size - ptr = inputs.collect { |i| i.to_s }.join - User32.SendInput(n, ptr, inputs[0].size) - end - - def get_screen_resolution - [User32.GetSystemMetrics(0), User32.GetSystemMetrics(1)] - end - - def mouse_move(x, y) - User32.SetCursorPos(x, y) - end - - def mouse_move_percentage(x, y) - screen_resolution = get_screen_resolution() - User32.SetCursorPos(screen_resolution[0] * x, screen_resolution[1] * y) - end - - def right_click - send_input([@@rightdown, @@rightup]) - end - - def left_click - send_input([@@leftdown, @@leftup]) - end - - def middle_click - send_input([@@middledown, @@middleup]) - end - - def mouse_down(button_name) - case button_name - when :right - send_input([@@rightdown]) - when :middle - send_input([@@middledown]) - else - send_input([@@leftdown]) - end - end - - def mouse_up(button_name) - case button_name - when :right - send_input([@@rightup]) - when :middle - send_input([@@middleup]) - else - send_input([@@leftup]) - end - end - - def double_click - left_click - left_click - end - - ################# TEMP ##################### - - @@rightdown32 = InputStructure.mouse_input_32(0, 0, 0, 0x0008) - @@rightup32 = InputStructure.mouse_input_32(0, 0, 0, 0x0010) - @@leftdown32 = InputStructure.mouse_input_32(0, 0, 0, 0x0002) - @@leftup32 = InputStructure.mouse_input_32(0, 0, 0, 0x0004) - @@middledown32 = InputStructure.mouse_input_32(0, 0, 0, 0x0020) - @@middleup32 = InputStructure.mouse_input_32(0, 0, 0, 0x0040) - - def right_click_32 - send_input([@@rightdown32, @@rightup32]) - end - - def left_click_32 - send_input([@@leftdown32, @@leftup32]) - end - - def middle_click_32 - send_input([@@middledown32, @@middleup32]) - end - - def mouse_down_32(button_name) - case button_name - when :right - send_input([@@rightdown32]) - when :middle - send_input([@@middledown32]) - else - send_input([@@leftdown32]) - end - end - - def mouse_up_32(button_name) - case button_name - when :right - send_input([@@rightup32]) - when :middle - send_input([@@middleup32]) - else - send_input([@@leftup32]) - end - end - - def double_click_32 - left_click_32 - left_click_32 - end - - def left_drag_32(sx, sy, ex, ey) - mouse_move sx, sy - sleep 0.1 - send_input([@@leftdown32]) - sleep 0.1 - mouse_move ex, ey - sleep 0.1 - send_input([@@leftup32]) - sleep 0.1 - end - - def right_drag_32(sx, sy, ex, ey) - mouse_move sx, sy - sleep 0.1 - send_input([@@rightdown32]) - sleep 0.1 - mouse_move ex, ey - sleep 0.1 - send_input([@@rightup32]) - sleep 0.1 - end - - def key_stroke_32(key_name) - code = VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input_32(code, 0x0000), - InputStructure.keyboard_input_32(code, 0x0002)]) - end - - def key_down_32(key_name) - code = VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input_32(code, 0x0000)]) - end - - def key_up_32(key_name) - code = VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input_32(code, 0x0002)]) - end - - ################# END TEMP ##################### - - def cursor_position - point = " " * 8 - User32.GetCursorPos(point) - point.unpack('LL') - end - - def mouse_scroll(d) - scroll = InputStructure.mouse_input(0, 0, d * 120, 0x0800) - send_input([scroll]) - end - - def left_drag(sx, sy, ex, ey) - mouse_move sx, sy - sleep 0.1 - send_input([@@leftdown]) - sleep 0.1 - mouse_move ex, ey - sleep 0.1 - send_input([@@leftup]) - sleep 0.1 - end - - def right_drag(sx, sy, ex, ey) - mouse_move sx, sy - sleep 0.1 - send_input([@@rightdown]) - sleep 0.1 - mouse_move ex, ey - sleep 0.1 - send_input([@@rightup]) - sleep 0.1 - end - - def key_stroke(key_name) - code = VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input(code, 0x0000), - InputStructure.keyboard_input(code, 0x0002)]) - end - - def key_down(key_name) - code = VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input(code, 0x0000)]) - end - - def key_up(key_name) - code = VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input(code, 0x0002)]) - end - - def type(string) - key_stroke(:capslock) if get_key_state(:capslock) == 1 - string = string.to_s - string.each_char do |c| - if ('a'..'z').include? c - key_stroke(c.to_sym) - elsif ('A'..'Z').include? c - key_down(:leftshift) - key_stroke(c.to_sym) - key_up(:leftshift) - elsif ('0'..'9').include? c - key_stroke(('num' + c).to_sym) - else - case c - when ' ' - key_stroke(:space) - when ';' - key_stroke(:semicolon) - when ':' - key_down(:leftshift) - key_stroke(:semicolon) - key_up(:leftshift) - when '=' - key_stroke(:equal) - when '+' - key_down(:leftshift) - key_stroke(:plus) - key_up(:leftshift) - when ',' - key_stroke(:comma) - when '<' - key_down(:leftshift) - key_stroke(:smallerthan) - key_up(:leftshift) - when '-' - key_stroke(:hyphen) - when '_' - key_down(:leftshift) - key_stroke(:underscore) - key_up(:leftshift) - when '.' - key_stroke(:period) - when '>' - key_down(:leftshift) - key_stroke(:greaterthan) - key_up(:leftshift) - when '/' - key_stroke(:slash) - when '?' - key_down(:leftshift) - key_stroke(:question) - key_up(:leftshift) - when '`' - key_stroke(:grave) - when '~' - key_down(:leftshift) - key_stroke(:tilde) - key_up(:leftshift) - when '/' - key_stroke(:slash) - when '?' - key_down(:leftshift) - key_stroke(:question) - key_up(:leftshift) - when '[' - key_stroke(:branket) - when '{' - key_down(:leftshift) - key_stroke(:branket) - key_up(:leftshift) - when ']' - key_stroke(:closebranket) - when '}' - key_down(:leftshift) - key_stroke(:closebranket) - key_up(:leftshift) - when '\\' # You need to esapce \ in the parameter string - key_stroke(:backslash) - when '|' - key_down(:leftshift) - key_stroke(:pipe) - key_up(:leftshift) - when '\'' # escape ' only for single quote string - key_stroke(:quote) - when '"' # escape " only for double quote string - key_down(:leftshift) - key_stroke(:doublequote) - key_up(:leftshift) - when '!' - key_down(:leftshift) - key_stroke(:num1) - key_up(:leftshift) - when '@' - key_down(:leftshift) - key_stroke(:num2) - key_up(:leftshift) - when '#' # The sharp sign need to be escape in single quote string - key_down(:leftshift) - key_stroke(:num3) - key_up(:leftshift) - when '$' - key_down(:leftshift) - key_stroke(:num4) - key_up(:leftshift) - when '%' - key_down(:leftshift) - key_stroke(:num5) - key_up(:leftshift) - when '^' - key_down(:leftshift) - key_stroke(:num6) - key_up(:leftshift) - when '&' - key_down(:leftshift) - key_stroke(:num7) - key_up(:leftshift) - when '*' - key_down(:leftshift) - key_stroke(:num8) - key_up(:leftshift) - when '(' - key_down(:leftshift) - key_stroke(:num9) - key_up(:leftshift) - when ')' - key_down(:leftshift) - key_stroke(:num0) - key_up(:leftshift) - end - - end - end - end - - def get_key_state(key_name) - code = VirtualKey.code_from_name(key_name) - User32.GetKeyState(code) - # For normal keys (such as a) - # When the key is down the value is -128 - # When the key is up the value is 0 - - # For toggle keys (such as capslock) - # When the cap key is down and the caplock is on the value is -127 - # When the cap key is down and the caplock is off the value is -128 - # When the cap key is Up and the caplock is on the value is 1 - # When the cap key is Up and the caplock is off the value is 0 - end + @@rightdown = InputStructure.mouse_input(0, 0, 0, 0x0008) + @@rightup = InputStructure.mouse_input(0, 0, 0, 0x0010) + @@leftdown = InputStructure.mouse_input(0, 0, 0, 0x0002) + @@leftup = InputStructure.mouse_input(0, 0, 0, 0x0004) + @@middledown = InputStructure.mouse_input(0, 0, 0, 0x0020) + @@middleup = InputStructure.mouse_input(0, 0, 0, 0x0040) + + def send_input(inputs) + n = inputs.size + ptr = inputs.collect { |i| i.to_s }.join + User32.SendInput(n, ptr, inputs[0].size) + end + + def get_screen_resolution + [User32.GetSystemMetrics(0), User32.GetSystemMetrics(1)] + end + + def mouse_move(x, y) + User32.SetCursorPos(x, y) + end + + def mouse_move_percentage(x, y) + screen_resolution = get_screen_resolution() + User32.SetCursorPos(get_screen_resolution[0] * x, get_screen_resolution[1] * y) + end + + def right_click + send_input([@@rightdown, @@rightup]) + end + + def left_click + send_input([@@leftdown, @@leftup]) + end + + def middle_click + send_input([@@middledown, @@middleup]) + end + + def mouse_down(button_name) + case button_name + when :right + send_input([@@rightdown]) + when :middle + send_input([@@middledown]) + else + send_input([@@leftdown]) + end + end + + def mouse_up(button_name) + case button_name + when :right + send_input([@@rightup]) + when :middle + send_input([@@middleup]) + else + send_input([@@leftup]) + end + end + + def double_click + left_click + left_click + end + + ################# TEMP ##################### + @@rightdown32 = InputStructure.mouse_input_32(0, 0, 0, 0x0008) + @@rightup32 = InputStructure.mouse_input_32(0, 0, 0, 0x0010) + @@leftdown32 = InputStructure.mouse_input_32(0, 0, 0, 0x0002) + @@leftup32 = InputStructure.mouse_input_32(0, 0, 0, 0x0004) + @@middledown32 = InputStructure.mouse_input_32(0, 0, 0, 0x0020) + @@middleup32 = InputStructure.mouse_input_32(0, 0, 0, 0x0040) + + def right_click_32 + send_input([@@rightdown32, @@rightup32]) + end + + def left_click_32 + send_input([@@leftdown32, @@leftup32]) + end + + def middle_click_32 + send_input([@@middledown32, @@middleup32]) + end + + def mouse_down_32(button_name) + case button_name + when :right + send_input([@@rightdown32]) + when :middle + send_input([@@middledown32]) + else + send_input([@@leftdown32]) + end + end + + def mouse_up_32(button_name) + case button_name + when :right + send_input([@@rightup32]) + when :middle + send_input([@@middleup32]) + else + send_input([@@leftup32]) + end + end + + def double_click_32 + left_click_32 + left_click_32 + end + + def left_drag_32(sx, sy, ex, ey) + mouse_move sx, sy + sleep 0.1 + send_input([@@leftdown32]) + sleep 0.1 + mouse_move ex, ey + sleep 0.1 + send_input([@@leftup32]) + sleep 0.1 + end + + def right_drag_32(sx, sy, ex, ey) + mouse_move sx, sy + sleep 0.1 + send_input([@@rightdown32]) + sleep 0.1 + mouse_move ex, ey + sleep 0.1 + send_input([@@rightup32]) + sleep 0.1 + end + + def key_stroke_32(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input_32(code, 0x0000), + InputStructure.keyboard_input_32(code, 0x0002)]) + end + + def key_down_32(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input_32(code, 0x0000)]) + end + + def key_up_32(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input_32(code, 0x0002)]) + end + + ################# END TEMP ##################### + def cursor_position + point = " " * 8 + User32.GetCursorPos(point) + point.unpack('LL') + end + + def mouse_scroll(d) + scroll = InputStructure.mouse_input(0, 0, d * 120, 0x0800) + send_input([scroll]) + end + + def left_drag(sx, sy, ex, ey) + mouse_move sx, sy + sleep 0.1 + send_input([@@leftdown]) + sleep 0.1 + mouse_move ex, ey + sleep 0.1 + send_input([@@leftup]) + sleep 0.1 + end + + def right_drag(sx, sy, ex, ey) + mouse_move sx, sy + sleep 0.1 + send_input([@@rightdown]) + sleep 0.1 + mouse_move ex, ey + sleep 0.1 + send_input([@@rightup]) + sleep 0.1 + end + + def key_stroke(*keys) + down_keys = keys.map do |key| + code = VirtualKey.code_from_name(key) + InputStructure.keyboard_input(code, 0x0000) + end + up_keys = keys.map do |key| + code = VirtualKey.code_from_name(key) + InputStructure.keyboard_input(code, 0x0002) + end + send_input(down_keys + up_keys) + end + + def key_down(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input(code, 0x0000)]) + end + + def key_up(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input(code, 0x0002)]) + end + + def type(string) + key_stroke(:capslock) if get_key_state(:capslock) == 1 + string = string.to_s + string.each_char do |c| + if ('a'..'z').include? c + key_stroke(c.to_sym) + elsif ('A'..'Z').include? c + key_down(:leftshift) + key_stroke(c.to_sym) + key_up(:leftshift) + elsif ('0'..'9').include? c + key_stroke(('num' + c).to_sym) + else + case c + when ' ' + key_stroke(:space) + when ';' + key_stroke(:semicolon) + when ':' + key_down(:leftshift) + key_stroke(:semicolon) + key_up(:leftshift) + when '=' + key_stroke(:equal) + when '+' + key_down(:leftshift) + key_stroke(:plus) + key_up(:leftshift) + when ',' + key_stroke(:comma) + when '<' + key_down(:leftshift) + key_stroke(:smallerthan) + key_up(:leftshift) + when '-' + key_stroke(:hyphen) + when '_' + key_down(:leftshift) + key_stroke(:underscore) + key_up(:leftshift) + when '.' + key_stroke(:period) + when '>' + key_down(:leftshift) + key_stroke(:greaterthan) + key_up(:leftshift) + when '/' + key_stroke(:slash) + when '?' + key_down(:leftshift) + key_stroke(:question) + key_up(:leftshift) + when '`' + key_stroke(:grave) + when '~' + key_down(:leftshift) + key_stroke(:tilde) + key_up(:leftshift) + when '/' + key_stroke(:slash) + when '?' + key_down(:leftshift) + key_stroke(:question) + key_up(:leftshift) + when '[' + key_stroke(:branket) + when '{' + key_down(:leftshift) + key_stroke(:branket) + key_up(:leftshift) + when ']' + key_stroke(:closebranket) + when '}' + key_down(:leftshift) + key_stroke(:closebranket) + key_up(:leftshift) + when '\\' # You need to esapce \ in the parameter string + key_stroke(:backslash) + when '|' + key_down(:leftshift) + key_stroke(:pipe) + key_up(:leftshift) + when '\'' # escape ' only for single quote string + key_stroke(:quote) + when '"' # escape " only for double quote string + key_down(:leftshift) + key_stroke(:doublequote) + key_up(:leftshift) + when '!' + key_down(:leftshift) + key_stroke(:num1) + key_up(:leftshift) + when '@' + key_down(:leftshift) + key_stroke(:num2) + key_up(:leftshift) + when '#' # The sharp sign need to be escape in single quote string + key_down(:leftshift) + key_stroke(:num3) + key_up(:leftshift) + when '$' + key_down(:leftshift) + key_stroke(:num4) + key_up(:leftshift) + when '%' + key_down(:leftshift) + key_stroke(:num5) + key_up(:leftshift) + when '^' + key_down(:leftshift) + key_stroke(:num6) + key_up(:leftshift) + when '&' + key_down(:leftshift) + key_stroke(:num7) + key_up(:leftshift) + when '*' + key_down(:leftshift) + key_stroke(:num8) + key_up(:leftshift) + when '(' + key_down(:leftshift) + key_stroke(:num9) + key_up(:leftshift) + when ')' + key_down(:leftshift) + key_stroke(:num0) + key_up(:leftshift) + end + end + end + end + + def get_key_state(key_name) + code = VirtualKey.code_from_name(key_name) + User32.GetKeyState(code) + # For normal keys (such as a) + # When the key is down the value is -128 + # When the key is up the value is 0 + # For toggle keys (such as capslock) + # When the cap key is down and the caplock is on the value is -127 + # When the cap key is down and the caplock is off the value is -128 + # When the cap key is Up and the caplock is on the value is 1 + # When the cap key is Up and the caplock is off the value is 0 + end end - # include AutoClick # This line allow auto include when the user require the gem - -class AutoClick - include AutoClickMethods +module AutoClick + include AutoClickMethods end diff --git a/lib/auto_click/input_structure.rb b/lib/auto_click/input_structure.rb index b4a1a0f..5489701 100644 --- a/lib/auto_click/input_structure.rb +++ b/lib/auto_click/input_structure.rb @@ -1,39 +1,37 @@ module InputStructure + def self.mouse_input(dx, dy, mouse_data, dw_flags) + mi = Array.new(7, 0) + mi[0] = 0 + mi[1] = dx + mi[2] = dy + mi[3] = mouse_data + mi[4] = dw_flags + mi.pack('QLLLLQQ') + end - def self.mouse_input(dx, dy, mouse_data, dw_flags) - mi = Array.new(7, 0) - mi[0] = 0 - mi[1] = dx - mi[2] = dy - mi[3] = mouse_data - mi[4] = dw_flags - mi.pack('QLLLLQQ') - end + def self.keyboard_input(wVk, dw_flags) + ki = Array.new(7, 0) + ki[0] = 1 + ki[1] = wVk + ki[2] = dw_flags + ki.pack('QLLLLQQ') + end - def self.keyboard_input(wVk, dw_flags) - ki = Array.new(7, 0) - ki[0] = 1 - ki[1] = wVk - ki[2] = dw_flags - ki.pack('QLLLLQQ') - end - - def self.mouse_input_32(dx, dy, mouse_data, dw_flags) - mi = Array.new(7, 0) - mi[0] = 0 - mi[1] = dx - mi[2] = dy - mi[3] = mouse_data - mi[4] = dw_flags - mi.pack('LLLLLLL') - end - - def self.keyboard_input_32(wVk, dw_flags) - ki = Array.new(7, 0) - ki[0] = 1 - ki[1] = wVk - ki[2] = dw_flags - ki.pack('LLLLLLL') - end + def self.mouse_input_32(dx, dy, mouse_data, dw_flags) + mi = Array.new(7, 0) + mi[0] = 0 + mi[1] = dx + mi[2] = dy + mi[3] = mouse_data + mi[4] = dw_flags + mi.pack('LLLLLLL') + end + def self.keyboard_input_32(wVk, dw_flags) + ki = Array.new(7, 0) + ki[0] = 1 + ki[1] = wVk + ki[2] = dw_flags + ki.pack('LLLLLLL') + end end \ No newline at end of file diff --git a/lib/auto_click/user32.rb b/lib/auto_click/user32.rb index 3bbd949..9c06096 100644 --- a/lib/auto_click/user32.rb +++ b/lib/auto_click/user32.rb @@ -1,9 +1,9 @@ module User32 - extend Fiddle::Importer - dlload 'user32' - extern "int GetCursorPos(char*)" - extern "int SetCursorPos(int,int)" - extern "int SendInput(int,char*,int)" - extern "int GetKeyState(int)" - extern "int GetSystemMetrics(int)" + extend Fiddle::Importer + dlload 'user32' + extern "int GetCursorPos(char*)" + extern "int SetCursorPos(int,int)" + extern "int SendInput(int,char*,int)" + extern "int GetKeyState(int)" + extern "int GetSystemMetrics(int)" end diff --git a/lib/auto_click/version.rb b/lib/auto_click/version.rb index e5be056..93355fe 100644 --- a/lib/auto_click/version.rb +++ b/lib/auto_click/version.rb @@ -1,3 +1,3 @@ module AutoClick - VERSION = "1.0.0" + VERSION = "1.0.1" end diff --git a/lib/auto_click/virtual_key.rb b/lib/auto_click/virtual_key.rb index 0962b4a..29e0eac 100644 --- a/lib/auto_click/virtual_key.rb +++ b/lib/auto_click/virtual_key.rb @@ -1,38 +1,137 @@ module VirtualKey - KEYNAMES_TO_CODES = { - back: 0x08, backspace: 0x08, tab: 0x09, clear: 0x0C, - return: 0x0D, enter: 0x0D, shift: 0x10, ctrl: 0x11, - control: 0x11, alt: 0x12, alternate: 0x12, pause: 0x13, - cap: 0x14, capslock: 0x14, caplock: 0x14, esc: 0x1B, - escape: 0x1B, space: 0x20, spacebar: 0x20, pageup: 0x21, - pagedown: 0x22, end: 0x23, home: 0x24, left: 0x25, - leftarrow: 0x25, leftkey: 0x25, up: 0x26, uparrow: 0x26, - upkey: 0x26, right: 0x27, rightarrow: 0x27, rightkey: 0x27, - down: 0x28, downarrow: 0x28, downkey: 0x28, select: 0x29, - print: 0x2A, exe: 0x2B, execute: 0x2B, printscr: 0x2C, - printscreen: 0x2C, ins: 0x2D, insert: 0x2D, del: 0x2E, - delete: 0x2E, help: 0x2F, num0: 0x30, number0: 0x30, - num1: 0x31, number1: 0x31, num2: 0x32, number2: 0x32, - num3: 0x33, number3: 0x33, num4: 0x34, number4: 0x34, num5: 0x35, number5: 0x35, - num6: 0x36, number6: 0x36, num7: 0x37, number7: 0x37, num8: 0x38, number8: 0x38, - num9: 0x39, number9: 0x39, a: 0x41, b: 0x42, c: 0x43, d: 0x44, - e: 0x45, f: 0x46, g: 0x47, h: 0x48, i: 0x49, j: 0x4A, - k: 0x4B, l: 0x4C, m: 0x4D, n: 0x4E, o: 0x4F, p: 0x50, - q: 0x51, r: 0x52, s: 0x53, t: 0x54, u: 0x55, v: 0x56, - w: 0x57, x: 0x58, y: 0x59, z: 0x5A, win: 0x5B, windows: 0x5B, - leftwin: 0x5B, rightwin: 0x5C, app: 0x5D, application: 0x5D, - # and so on... - - }.freeze - - def self.code_from_name(name) - return name if name.is_a? Integer - - if name.is_a? String - name = name.downcase.delete('_- ').to_sym - end - - KEYNAMES_TO_CODES.fetch(name, 0) - end + KEYNAMES_TO_CODES = { + a: 0x41, + alt: 0x12, + alternate: 0x12, + app: 0x5D, + application: 0x5D, + b: 0x42, + back: 0x08, + backspace: 0x08, + c: 0x43, + cap: 0x14, + caplock: 0x14, + capslock: 0x14, + clear: 0x0C, + control: 0x11, + ctrl: 0x11, + d: 0x44, + del: 0x2E, + delete: 0x2E, + down: 0x28, + downarrow: 0x28, + downkey: 0x28, + e: 0x45, + end: 0x23, + enter: 0x0D, + esc: 0x1B, + escape: 0x1B, + exe: 0x2B, + execute: 0x2B, + f: 0x46, + f1: 0x70, + f10: 0x79, + f11: 0x7A, + f12: 0x7B, + f13: 0x7C, + f14: 0x7D, + f15: 0x7E, + f16: 0x7F, + f17: 0x80, + f18: 0x81, + f19: 0x82, + f2: 0x71, + f20: 0x83, + f21: 0x84, + f22: 0x85, + f23: 0x86, + f24: 0x87, + f3: 0x72, + f4: 0x73, + f5: 0x74, + f6: 0x75, + f7: 0x76, + f8: 0x77, + f9: 0x78, + g: 0x47, + h: 0x48, + help: 0x2F, + home: 0x24, + i: 0x49, + ins: 0x2D, + insert: 0x2D, + j: 0x4A, + k: 0x4B, + l: 0x4C, + left: 0x25, + leftarrow: 0x25, + leftkey: 0x25, + leftwin: 0x5B, + m: 0x4D, + n: 0x4E, + num0: 0x30, + num1: 0x31, + num2: 0x32, + num3: 0x33, + num4: 0x34, + num5: 0x35, + num6: 0x36, + num7: 0x37, + num8: 0x38, + num9: 0x39, + number0: 0x30, + number1: 0x31, + number2: 0x32, + number3: 0x33, + number4: 0x34, + number5: 0x35, + number6: 0x36, + number7: 0x37, + number8: 0x38, + number9: 0x39, + numlock: 0x90, + o: 0x4F, + p: 0x50, + pagedown: 0x22, + pageup: 0x21, + pause: 0x13, + print: 0x2A, + printscr: 0x2C, + printscreen: 0x2C, + q: 0x51, + r: 0x52, + return: 0x0D, + right: 0x27, + rightarrow: 0x27, + rightkey: 0x27, + rightwin: 0x5C, + s: 0x53, + scrolllock: 0x91, + select: 0x29, + shift: 0x10, + sleep: 0x5F, + space: 0x20, + spacebar: 0x20, + t: 0x54, + tab: 0x09, + u: 0x55, + up: 0x26, + uparrow: 0x26, + upkey: 0x26, + v: 0x56, + w: 0x57, + win: 0x5B, + windows: 0x5B, + x: 0x58, + y: 0x59, + z: 0x5A + }.freeze + def self.code_from_name(name) + return name if name.is_a? Integer + if name.is_a? String + name = name.downcase.gsub(/[-_ ]/, '').to_sym + end + KEYNAMES_TO_CODES.fetch(name, 0) + end end diff --git a/sig/auto_click_methods.rbs b/sig/auto_click_methods.rbs new file mode 100644 index 0000000..de49c5d --- /dev/null +++ b/sig/auto_click_methods.rbs @@ -0,0 +1,59 @@ +module AutoClickMethods + def send_input: (Array[String]) -> void + + def get_screen_resolution: -> Array[Integer] + + def mouse_move: (Integer, Integer) -> void + + def mouse_move_percentage: (Integer, Integer) -> void + + def right_click: -> void + + def left_click: -> void + + def middle_click: -> void + + def mouse_down: (:right | :middle | :left) -> void + + def mouse_up: (:right | :middle | :left) -> void + + def double_click: -> void + + def right_click_32: -> void + + def left_click_32: -> void + + def middle_click_32: -> void + + def mouse_down_32: (:right | :middle | :left) -> void + + def mouse_up_32: (:right | :middle | :left) -> void + + def double_click_32: -> void + + def left_drag_32: (Integer, Integer, Integer, Integer) -> void + + def right_drag_32: (Integer, Integer, Integer, Integer) -> void + + def key_stroke_32: (:right | :middle | :left) -> void + + def key_down_32: (:right | :middle | :left) -> void + + def key_up_32: (:right | :middle | :left) -> void + + def cursor_position: -> Array[Integer] + + def mouse_scroll: (Integer) -> void + + def left_drag: (Integer, Integer, Integer, Integer) -> void + + def right_drag: (Integer, Integer, Integer, Integer) -> void + + def key_stroke: (*(:right | :middle | :left)) -> void + + def key_down: (:right | :middle | :left) -> void + + def key_up: (:right | :middle | :left) -> void + + def type: (String) -> void +end \ No newline at end of file diff --git a/virtual-key-codes.md b/virtual-key-codes.md new file mode 100644 index 0000000..60e3177 --- /dev/null +++ b/virtual-key-codes.md @@ -0,0 +1,197 @@ +# Virtual-Key Codes + +The following table shows the symbolic constant names, hexadecimal values, and mouse or keyboard equivalents for the +virtual-key codes used by the system. The codes are listed in numeric order. + +| Constant | Value | Description | +|--------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `VK_LBUTTON` | 0x01 | Left mouse button | +| `VK_RBUTTON` | 0x02 | Right mouse button | +| `VK_CANCEL` | 0x03 | Control-break processing | +| `VK_MBUTTON` | 0x04 | Middle mouse button | +| `VK_XBUTTON1` | 0x05 | X1 mouse button | +| `VK_XBUTTON2` | 0x06 | X2 mouse button | +| `-` | 0x07 | Reserved | +| `VK_BACK` | 0x08 | BACKSPACE key | +| `VK_TAB` | 0x09 | TAB key | +| `-` | 0x0A-0B | Reserved | +| `VK_CLEAR` | 0x0C | CLEAR key | +| `VK_RETURN` | 0x0D | ENTER key | +| `-` | 0x0E-0F | Unassigned | +| `VK_SHIFT` | 0x10 | SHIFT key | +| `VK_CONTROL` | 0x11 | CTRL key | +| `VK_MENU` | 0x12 | ALT key | +| `VK_PAUSE` | 0x13 | PAUSE key | +| `VK_CAPITAL` | 0x14 | CAPS LOCK key | +| `VK_KANA` | 0x15 | IME Kana mode | +| `VK_HANGUL` | 0x15 | IME Hangul mode | +| `VK_IME_ON` | 0x16 | IME On | +| `VK_JUNJA` | 0x17 | IME Junja mode | +| `VK_FINAL` | 0x18 | IME final mode | +| `VK_HANJA` | 0x19 | IME Hanja mode | +| `VK_KANJI` | 0x19 | IME Kanji mode | +| `VK_IME_OFF` | 0x1A | IME Off | +| `VK_ESCAPE` | 0x1B | ESC key | +| `VK_CONVERT` | 0x1C | IME convert | +| `VK_NONCONVERT` | 0x1D | IME nonconvert | +| `VK_ACCEPT` | 0x1E | IME accept | +| `VK_MODECHANGE` | 0x1F | IME mode change request | +| `VK_SPACE` | 0x20 | SPACEBAR | +| `VK_PRIOR` | 0x21 | PAGE UP key | +| `VK_NEXT` | 0x22 | PAGE DOWN key | +| `VK_END` | 0x23 | END key | +| `VK_HOME` | 0x24 | HOME key | +| `VK_LEFT` | 0x25 | LEFT ARROW key | +| `VK_UP` | 0x26 | UP ARROW key | +| `VK_RIGHT` | 0x27 | RIGHT ARROW key | +| `VK_DOWN` | 0x28 | DOWN ARROW key | +| `VK_SELECT` | 0x29 | SELECT key | +| `VK_PRINT` | 0x2A | PRINT key | +| `VK_EXECUTE` | 0x2B | EXECUTE key | +| `VK_SNAPSHOT` | 0x2C | PRINT SCREEN key | +| `VK_INSERT` | 0x2D | INS key | +| `VK_DELETE` | 0x2E | DEL key | +| `VK_HELP` | 0x2F | HELP key | +| | 0x30 | 0 key | +| | 0x31 | 1 key | +| | 0x32 | 2 key | +| | 0x33 | 3 key | +| | 0x34 | 4 key | +| | 0x35 | 5 key | +| | 0x36 | 6 key | +| | 0x37 | 7 key | +| | 0x38 | 8 key | +| | 0x39 | 9 key | +| `-` | 0x3A-40 | Undefined | +| | 0x41 | A key | +| | 0x42 | B key | +| | 0x43 | C key | +| | 0x44 | D key | +| | 0x45 | E key | +| | 0x46 | F key | +| | 0x47 | G key | +| | 0x48 | H key | +| | 0x49 | I key | +| | 0x4A | J key | +| | 0x4B | K key | +| | 0x4C | L key | +| | 0x4D | M key | +| | 0x4E | N key | +| | 0x4F | O key | +| | 0x50 | P key | +| | 0x51 | Q key | +| | 0x52 | R key | +| | 0x53 | S key | +| | 0x54 | T key | +| | 0x55 | U key | +| | 0x56 | V key | +| | 0x57 | W key | +| | 0x58 | X key | +| | 0x59 | Y key | +| | 0x5A | Z key | +| `VK_LWIN` | 0x5B | Left Windows key | +| `VK_RWIN` | 0x5C | Right Windows key | +| `VK_APPS` | 0x5D | Applications key | +| `-` | 0x5E | Reserved | +| `VK_SLEEP` | 0x5F | Computer Sleep key | +| `VK_NUMPAD0` | 0x60 | Numeric keypad 0 key | +| `VK_NUMPAD1` | 0x61 | Numeric keypad 1 key | +| `VK_NUMPAD2` | 0x62 | Numeric keypad 2 key | +| `VK_NUMPAD3` | 0x63 | Numeric keypad 3 key | +| `VK_NUMPAD4` | 0x64 | Numeric keypad 4 key | +| `VK_NUMPAD5` | 0x65 | Numeric keypad 5 key | +| `VK_NUMPAD6` | 0x66 | Numeric keypad 6 key | +| `VK_NUMPAD7` | 0x67 | Numeric keypad 7 key | +| `VK_NUMPAD8` | 0x68 | Numeric keypad 8 key | +| `VK_NUMPAD9` | 0x69 | Numeric keypad 9 key | +| `VK_MULTIPLY` | 0x6A | Multiply key | +| `VK_ADD` | 0x6B | Add key | +| `VK_SEPARATOR` | 0x6C | Separator key | +| `VK_SUBTRACT` | 0x6D | Subtract key | +| `VK_DECIMAL` | 0x6E | Decimal key | +| `VK_DIVIDE` | 0x6F | Divide key | +| `VK_F1` | 0x70 | F1 key | +| `VK_F2` | 0x71 | F2 key | +| `VK_F3` | 0x72 | F3 key | +| `VK_F4` | 0x73 | F4 key | +| `VK_F5` | 0x74 | F5 key | +| `VK_F6` | 0x75 | F6 key | +| `VK_F7` | 0x76 | F7 key | +| `VK_F8` | 0x77 | F8 key | +| `VK_F9` | 0x78 | F9 key | +| `VK_F10` | 0x79 | F10 key | +| `VK_F11` | 0x7A | F11 key | +| `VK_F12` | 0x7B | F12 key | +| `VK_F13` | 0x7C | F13 key | +| `VK_F14` | 0x7D | F14 key | +| `VK_F15` | 0x7E | F15 key | +| `VK_F16` | 0x7F | F16 key | +| `VK_F17` | 0x80 | F17 key | +| `VK_F18` | 0x81 | F18 key | +| `VK_F19` | 0x82 | F19 key | +| `VK_F20` | 0x83 | F20 key | +| `VK_F21` | 0x84 | F21 key | +| `VK_F22` | 0x85 | F22 key | +| `VK_F23` | 0x86 | F23 key | +| `VK_F24` | 0x87 | F24 key | +| `-` | 0x88-8F | Reserved | +| `VK_NUMLOCK` | 0x90 | NUM LOCK key | +| `VK_SCROLL` | 0x91 | SCROLL LOCK key | +| `-` | 0x92-96 | OEM specific | +| `-` | 0x97-9F | Unassigned | +| `VK_LSHIFT` | 0xA0 | Left SHIFT key | +| `VK_RSHIFT` | 0xA1 | Right SHIFT key | +| `VK_LCONTROL` | 0xA2 | Left CONTROL key | +| `VK_RCONTROL` | 0xA3 | Right CONTROL key | +| `VK_LMENU` | 0xA4 | Left ALT key | +| `VK_RMENU` | 0xA5 | Right ALT key | +| `VK_BROWSER_BACK` | 0xA6 | Browser Back key | +| `VK_BROWSER_FORWARD` | 0xA7 | Browser Forward key | +| `VK_BROWSER_REFRESH` | 0xA8 | Browser Refresh key | +| `VK_BROWSER_STOP` | 0xA9 | Browser Stop key | +| `VK_BROWSER_SEARCH` | 0xAA | Browser Search key | +| `VK_BROWSER_FAVORITES` | 0xAB | Browser Favorites key | +| `VK_BROWSER_HOME` | 0xAC | Browser Start and Home key | +| `VK_VOLUME_MUTE` | 0xAD | Volume Mute key | +| `VK_VOLUME_DOWN` | 0xAE | Volume Down key | +| `VK_VOLUME_UP` | 0xAF | Volume Up key | +| `VK_MEDIA_NEXT_TRACK` | 0xB0 | Next Track key | +| `VK_MEDIA_PREV_TRACK` | 0xB1 | Previous Track key | +| `VK_MEDIA_STOP` | 0xB2 | Stop Media key | +| `VK_MEDIA_PLAY_PAUSE` | 0xB3 | Play/Pause Media key | +| `VK_LAUNCH_MAIL` | 0xB4 | Start Mail key | +| `VK_LAUNCH_MEDIA_SELECT` | 0xB5 | Select Media key | +| `VK_LAUNCH_APP1` | 0xB6 | Start Application 1 key | +| `VK_LAUNCH_APP2` | 0xB7 | Start Application 2 key | +| `-` | 0xB8-B9 | Reserved | +| `VK_OEM_1` | 0xBA | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the `;:` key | +| `VK_OEM_PLUS` | 0xBB | For any country/region, the `+` key | +| `VK_OEM_COMMA` | 0xBC | For any country/region, the `,` key | +| `VK_OEM_MINUS` | 0xBD | For any country/region, the `-` key | +| `VK_OEM_PERIOD` | 0xBE | For any country/region, the `.` key | +| `VK_OEM_2` | 0xBF | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the `/?` key | +| `VK_OEM_3` | 0xC0 | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the `` `~ `` key | +| `-` | 0xC1-DA | Reserved | +| `VK_OEM_4` | 0xDB | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the `[{` key | +| `VK_OEM_5` | 0xDC | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the `\\|` key | +| `VK_OEM_6` | 0xDD | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the `]}` key | +| `VK_OEM_7` | 0xDE | Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the `'"` key | +| `VK_OEM_8` | 0xDF | Used for miscellaneous characters; it can vary by keyboard. | +| `-` | 0xE0 | Reserved | +| `-` | 0xE1 | OEM specific | +| `VK_OEM_102` | 0xE2 | The `<>` keys on the US standard keyboard, or the `\\|` key on the non-US 102-key keyboard | +| `-` | 0xE3-E4 | OEM specific | +| `VK_PROCESSKEY` | 0xE5 | IME PROCESS key | +| `-` | 0xE6 | OEM specific | +| `VK_PACKET` | 0xE7 | Used to pass Unicode characters as if they were keystrokes. The `VK_PACKET` key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in [`KEYBDINPUT`](/windows/win32/api/winuser/ns-winuser-keybdinput), [`SendInput`](/windows/win32/api/winuser/nf-winuser-sendinput), [`WM_KEYDOWN`](wm-keydown.md), and [`WM_KEYUP`](wm-keyup.md) | +| `-` | 0xE8 | Unassigned | +| `-` | 0xE9-F5 | OEM specific | +| `VK_ATTN` | 0xF6 | Attn key | +| `VK_CRSEL` | 0xF7 | CrSel key | +| `VK_EXSEL` | 0xF8 | ExSel key | +| `VK_EREOF` | 0xF9 | Erase EOF key | +| `VK_PLAY` | 0xFA | Play key | +| `VK_ZOOM` | 0xFB | Zoom key | +| `VK_NONAME` | 0xFC | Reserved | +| `VK_PA1` | 0xFD | PA1 key | +| `VK_OEM_CLEAR` | 0xFE | Clear key | From 1f89f366308cf0fbf51ff235dacb7616fa679c92 Mon Sep 17 00:00:00 2001 From: BrianPurgert Date: Fri, 26 Jan 2024 01:30:49 -0500 Subject: [PATCH 5/7] Refactor auto-click library and correct Ruby SDK version This commit refactors the auto-click library for cleaner code structure, mainly focusing on indentation and module inclusions. It also fixes a version mismatch in the Ruby SDK being used by correcting it from ruby-3.3.0 to ruby-3.3.0-p0. Consequently, unnecessary methods have been commented, seemingly in an aim to clean up the codebase. --- .idea/auto_click.iml | 2 +- lib/auto_click.rb | 595 +++++++++++++----------------- lib/auto_click/input_structure.rb | 33 +- sig/auto_click_methods.rbs | 65 ++-- 4 files changed, 302 insertions(+), 393 deletions(-) diff --git a/.idea/auto_click.iml b/.idea/auto_click.iml index d069114..3c30049 100644 --- a/.idea/auto_click.iml +++ b/.idea/auto_click.iml @@ -9,7 +9,7 @@ - + diff --git a/lib/auto_click.rb b/lib/auto_click.rb index 32fc1de..a56c406 100644 --- a/lib/auto_click.rb +++ b/lib/auto_click.rb @@ -3,361 +3,270 @@ require 'auto_click/virtual_key' require 'auto_click/user32' module AutoClickMethods - @@rightdown = InputStructure.mouse_input(0, 0, 0, 0x0008) - @@rightup = InputStructure.mouse_input(0, 0, 0, 0x0010) - @@leftdown = InputStructure.mouse_input(0, 0, 0, 0x0002) - @@leftup = InputStructure.mouse_input(0, 0, 0, 0x0004) - @@middledown = InputStructure.mouse_input(0, 0, 0, 0x0020) - @@middleup = InputStructure.mouse_input(0, 0, 0, 0x0040) - - def send_input(inputs) - n = inputs.size - ptr = inputs.collect { |i| i.to_s }.join - User32.SendInput(n, ptr, inputs[0].size) - end - - def get_screen_resolution - [User32.GetSystemMetrics(0), User32.GetSystemMetrics(1)] - end - - def mouse_move(x, y) - User32.SetCursorPos(x, y) - end - - def mouse_move_percentage(x, y) - screen_resolution = get_screen_resolution() - User32.SetCursorPos(get_screen_resolution[0] * x, get_screen_resolution[1] * y) - end - - def right_click - send_input([@@rightdown, @@rightup]) - end - - def left_click - send_input([@@leftdown, @@leftup]) - end - - def middle_click - send_input([@@middledown, @@middleup]) - end - - def mouse_down(button_name) - case button_name - when :right - send_input([@@rightdown]) - when :middle - send_input([@@middledown]) - else - send_input([@@leftdown]) - end - end - - def mouse_up(button_name) - case button_name - when :right - send_input([@@rightup]) - when :middle - send_input([@@middleup]) - else - send_input([@@leftup]) - end - end - - def double_click - left_click - left_click - end - - ################# TEMP ##################### - @@rightdown32 = InputStructure.mouse_input_32(0, 0, 0, 0x0008) - @@rightup32 = InputStructure.mouse_input_32(0, 0, 0, 0x0010) - @@leftdown32 = InputStructure.mouse_input_32(0, 0, 0, 0x0002) - @@leftup32 = InputStructure.mouse_input_32(0, 0, 0, 0x0004) - @@middledown32 = InputStructure.mouse_input_32(0, 0, 0, 0x0020) - @@middleup32 = InputStructure.mouse_input_32(0, 0, 0, 0x0040) - - def right_click_32 - send_input([@@rightdown32, @@rightup32]) - end - - def left_click_32 - send_input([@@leftdown32, @@leftup32]) - end - - def middle_click_32 - send_input([@@middledown32, @@middleup32]) - end - - def mouse_down_32(button_name) - case button_name - when :right - send_input([@@rightdown32]) - when :middle - send_input([@@middledown32]) - else - send_input([@@leftdown32]) - end - end - - def mouse_up_32(button_name) - case button_name - when :right - send_input([@@rightup32]) - when :middle - send_input([@@middleup32]) - else - send_input([@@leftup32]) - end - end - - def double_click_32 - left_click_32 - left_click_32 - end - - def left_drag_32(sx, sy, ex, ey) - mouse_move sx, sy - sleep 0.1 - send_input([@@leftdown32]) - sleep 0.1 - mouse_move ex, ey - sleep 0.1 - send_input([@@leftup32]) - sleep 0.1 - end - - def right_drag_32(sx, sy, ex, ey) - mouse_move sx, sy - sleep 0.1 - send_input([@@rightdown32]) - sleep 0.1 - mouse_move ex, ey - sleep 0.1 - send_input([@@rightup32]) - sleep 0.1 - end - - def key_stroke_32(key_name) - code = VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input_32(code, 0x0000), - InputStructure.keyboard_input_32(code, 0x0002)]) - end - - def key_down_32(key_name) - code = VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input_32(code, 0x0000)]) - end - - def key_up_32(key_name) - code = VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input_32(code, 0x0002)]) - end - - ################# END TEMP ##################### - def cursor_position - point = " " * 8 - User32.GetCursorPos(point) - point.unpack('LL') - end - - def mouse_scroll(d) - scroll = InputStructure.mouse_input(0, 0, d * 120, 0x0800) - send_input([scroll]) - end - - def left_drag(sx, sy, ex, ey) - mouse_move sx, sy - sleep 0.1 - send_input([@@leftdown]) - sleep 0.1 - mouse_move ex, ey - sleep 0.1 - send_input([@@leftup]) - sleep 0.1 + @@rightdown = InputStructure.mouse_input(0, 0, 0, 0x0008) + @@rightup = InputStructure.mouse_input(0, 0, 0, 0x0010) + @@leftdown = InputStructure.mouse_input(0, 0, 0, 0x0002) + @@leftup = InputStructure.mouse_input(0, 0, 0, 0x0004) + @@middledown = InputStructure.mouse_input(0, 0, 0, 0x0020) + @@middleup = InputStructure.mouse_input(0, 0, 0, 0x0040) + + def send_input(inputs) + n = inputs.size + ptr = inputs.collect { |i| i.to_s }.join + User32.SendInput(n, ptr, inputs[0].size) + end + + def get_screen_resolution + [User32.GetSystemMetrics(0), User32.GetSystemMetrics(1)] + end + + def mouse_move(x, y) + User32.SetCursorPos(x, y) + end + + def mouse_move_percentage(x, y) + screen_resolution = get_screen_resolution() + User32.SetCursorPos(get_screen_resolution[0] * x, get_screen_resolution[1] * y) + end + + def right_click + send_input([@@rightdown, @@rightup]) + end + + def left_click + send_input([@@leftdown, @@leftup]) + end + + def middle_click + send_input([@@middledown, @@middleup]) + end + + def mouse_down(button_name) + case button_name + when :right + send_input([@@rightdown]) + when :middle + send_input([@@middledown]) + else send_input([@@leftdown]) end + end - def right_drag(sx, sy, ex, ey) - mouse_move sx, sy - sleep 0.1 - send_input([@@rightdown]) - sleep 0.1 - mouse_move ex, ey - sleep 0.1 + def mouse_up(button_name) + case button_name + when :right send_input([@@rightup]) - sleep 0.1 + when :middle + send_input([@@middleup]) + else send_input([@@leftup]) end - - def key_stroke(*keys) - down_keys = keys.map do |key| - code = VirtualKey.code_from_name(key) - InputStructure.keyboard_input(code, 0x0000) - end - up_keys = keys.map do |key| - code = VirtualKey.code_from_name(key) - InputStructure.keyboard_input(code, 0x0002) - end - send_input(down_keys + up_keys) + end + + def double_click + left_click + left_click + end + + + def cursor_position + point = " " * 8 + User32.GetCursorPos(point) + point.unpack('LL') + end + + def mouse_scroll(d) + scroll = InputStructure.mouse_input(0, 0, d * 120, 0x0800) + send_input([scroll]) + end + + def left_drag(sx, sy, ex, ey) + mouse_move sx, sy + sleep 0.1 + send_input([@@leftdown]) + sleep 0.1 + mouse_move ex, ey + sleep 0.1 + send_input([@@leftup]) + sleep 0.1 + end + + def right_drag(sx, sy, ex, ey) + mouse_move sx, sy + sleep 0.1 + send_input([@@rightdown]) + sleep 0.1 + mouse_move ex, ey + sleep 0.1 + send_input([@@rightup]) + sleep 0.1 + end + + def key_stroke(*keys) + down_keys = keys.map do |key| code = VirtualKey.code_from_name(key) + InputStructure.keyboard_input(code, 0x0000) end - - def key_down(key_name) - code = VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input(code, 0x0000)]) + up_keys = keys.map do |key| code = VirtualKey.code_from_name(key) + InputStructure.keyboard_input(code, 0x0002) end - - def key_up(key_name) - code = VirtualKey.code_from_name(key_name) - send_input([InputStructure.keyboard_input(code, 0x0002)]) + send_input(down_keys + up_keys) + end + + def key_down(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input(code, 0x0000)]) + end + + def key_up(key_name) + code = VirtualKey.code_from_name(key_name) + send_input([InputStructure.keyboard_input(code, 0x0002)]) + end + + def type(string) + key_stroke(:capslock) if get_key_state(:capslock) == 1 + string = string.to_s + string.each_char do |c| if ('a'..'z').include? c + key_stroke(c.to_sym) + elsif ('A'..'Z').include? c + key_down(:leftshift) + key_stroke(c.to_sym) + key_up(:leftshift) + elsif ('0'..'9').include? c + key_stroke(('num' + c).to_sym) + else case c + when ' ' + key_stroke(:space) + when ';' + key_stroke(:semicolon) + when ':' + key_down(:leftshift) + key_stroke(:semicolon) + key_up(:leftshift) + when '=' + key_stroke(:equal) + when '+' + key_down(:leftshift) + key_stroke(:plus) + key_up(:leftshift) + when ',' + key_stroke(:comma) + when '<' + key_down(:leftshift) + key_stroke(:smallerthan) + key_up(:leftshift) + when '-' + key_stroke(:hyphen) + when '_' + key_down(:leftshift) + key_stroke(:underscore) + key_up(:leftshift) + when '.' + key_stroke(:period) + when '>' + key_down(:leftshift) + key_stroke(:greaterthan) + key_up(:leftshift) + when '/' + key_stroke(:slash) + when '?' + key_down(:leftshift) + key_stroke(:question) + key_up(:leftshift) + when '`' + key_stroke(:grave) + when '~' + key_down(:leftshift) + key_stroke(:tilde) + key_up(:leftshift) + when '/' + key_stroke(:slash) + when '?' + key_down(:leftshift) + key_stroke(:question) + key_up(:leftshift) + when '[' + key_stroke(:branket) + when '{' + key_down(:leftshift) + key_stroke(:branket) + key_up(:leftshift) + when ']' + key_stroke(:closebranket) + when '}' + key_down(:leftshift) + key_stroke(:closebranket) + key_up(:leftshift) + when '\\' # You need to esapce \ in the parameter string + key_stroke(:backslash) + when '|' + key_down(:leftshift) + key_stroke(:pipe) + key_up(:leftshift) + when '\'' # escape ' only for single quote string + key_stroke(:quote) + when '"' # escape " only for double quote string + key_down(:leftshift) + key_stroke(:doublequote) + key_up(:leftshift) + when '!' + key_down(:leftshift) + key_stroke(:num1) + key_up(:leftshift) + when '@' + key_down(:leftshift) + key_stroke(:num2) + key_up(:leftshift) + when '#' # The sharp sign need to be escape in single quote string + key_down(:leftshift) + key_stroke(:num3) + key_up(:leftshift) + when '$' + key_down(:leftshift) + key_stroke(:num4) + key_up(:leftshift) + when '%' + key_down(:leftshift) + key_stroke(:num5) + key_up(:leftshift) + when '^' + key_down(:leftshift) + key_stroke(:num6) + key_up(:leftshift) + when '&' + key_down(:leftshift) + key_stroke(:num7) + key_up(:leftshift) + when '*' + key_down(:leftshift) + key_stroke(:num8) + key_up(:leftshift) + when '(' + key_down(:leftshift) + key_stroke(:num9) + key_up(:leftshift) + when ')' + key_down(:leftshift) + key_stroke(:num0) + key_up(:leftshift) end - - def type(string) - key_stroke(:capslock) if get_key_state(:capslock) == 1 - string = string.to_s - string.each_char do |c| - if ('a'..'z').include? c - key_stroke(c.to_sym) - elsif ('A'..'Z').include? c - key_down(:leftshift) - key_stroke(c.to_sym) - key_up(:leftshift) - elsif ('0'..'9').include? c - key_stroke(('num' + c).to_sym) - else - case c - when ' ' - key_stroke(:space) - when ';' - key_stroke(:semicolon) - when ':' - key_down(:leftshift) - key_stroke(:semicolon) - key_up(:leftshift) - when '=' - key_stroke(:equal) - when '+' - key_down(:leftshift) - key_stroke(:plus) - key_up(:leftshift) - when ',' - key_stroke(:comma) - when '<' - key_down(:leftshift) - key_stroke(:smallerthan) - key_up(:leftshift) - when '-' - key_stroke(:hyphen) - when '_' - key_down(:leftshift) - key_stroke(:underscore) - key_up(:leftshift) - when '.' - key_stroke(:period) - when '>' - key_down(:leftshift) - key_stroke(:greaterthan) - key_up(:leftshift) - when '/' - key_stroke(:slash) - when '?' - key_down(:leftshift) - key_stroke(:question) - key_up(:leftshift) - when '`' - key_stroke(:grave) - when '~' - key_down(:leftshift) - key_stroke(:tilde) - key_up(:leftshift) - when '/' - key_stroke(:slash) - when '?' - key_down(:leftshift) - key_stroke(:question) - key_up(:leftshift) - when '[' - key_stroke(:branket) - when '{' - key_down(:leftshift) - key_stroke(:branket) - key_up(:leftshift) - when ']' - key_stroke(:closebranket) - when '}' - key_down(:leftshift) - key_stroke(:closebranket) - key_up(:leftshift) - when '\\' # You need to esapce \ in the parameter string - key_stroke(:backslash) - when '|' - key_down(:leftshift) - key_stroke(:pipe) - key_up(:leftshift) - when '\'' # escape ' only for single quote string - key_stroke(:quote) - when '"' # escape " only for double quote string - key_down(:leftshift) - key_stroke(:doublequote) - key_up(:leftshift) - when '!' - key_down(:leftshift) - key_stroke(:num1) - key_up(:leftshift) - when '@' - key_down(:leftshift) - key_stroke(:num2) - key_up(:leftshift) - when '#' # The sharp sign need to be escape in single quote string - key_down(:leftshift) - key_stroke(:num3) - key_up(:leftshift) - when '$' - key_down(:leftshift) - key_stroke(:num4) - key_up(:leftshift) - when '%' - key_down(:leftshift) - key_stroke(:num5) - key_up(:leftshift) - when '^' - key_down(:leftshift) - key_stroke(:num6) - key_up(:leftshift) - when '&' - key_down(:leftshift) - key_stroke(:num7) - key_up(:leftshift) - when '*' - key_down(:leftshift) - key_stroke(:num8) - key_up(:leftshift) - when '(' - key_down(:leftshift) - key_stroke(:num9) - key_up(:leftshift) - when ')' - key_down(:leftshift) - key_stroke(:num0) - key_up(:leftshift) - end - end - end end - - def get_key_state(key_name) - code = VirtualKey.code_from_name(key_name) - User32.GetKeyState(code) - # For normal keys (such as a) - # When the key is down the value is -128 - # When the key is up the value is 0 - # For toggle keys (such as capslock) - # When the cap key is down and the caplock is on the value is -127 - # When the cap key is down and the caplock is off the value is -128 - # When the cap key is Up and the caplock is on the value is 1 - # When the cap key is Up and the caplock is off the value is 0 end + end + + def get_key_state(key_name) + code = VirtualKey.code_from_name(key_name) + User32.GetKeyState(code) + # For normal keys (such as a) + # When the key is down the value is -128 + # When the key is up the value is 0 + # For toggle keys (such as capslock) + # When the cap key is down and the caplock is on the value is -127 + # When the cap key is down and the caplock is off the value is -128 + # When the cap key is Up and the caplock is on the value is 1 + # When the cap key is Up and the caplock is off the value is 0 + end end # include AutoClick # This line allow auto include when the user require the gem module AutoClick - include AutoClickMethods + include AutoClickMethods end diff --git a/lib/auto_click/input_structure.rb b/lib/auto_click/input_structure.rb index 5489701..d62e3bd 100644 --- a/lib/auto_click/input_structure.rb +++ b/lib/auto_click/input_structure.rb @@ -17,21 +17,20 @@ def self.keyboard_input(wVk, dw_flags) ki.pack('QLLLLQQ') end - def self.mouse_input_32(dx, dy, mouse_data, dw_flags) - mi = Array.new(7, 0) - mi[0] = 0 - mi[1] = dx - mi[2] = dy - mi[3] = mouse_data - mi[4] = dw_flags - mi.pack('LLLLLLL') - end - - def self.keyboard_input_32(wVk, dw_flags) - ki = Array.new(7, 0) - ki[0] = 1 - ki[1] = wVk - ki[2] = dw_flags - ki.pack('LLLLLLL') - end + # def self.mouse_input_32(dx, dy, mouse_data, dw_flags) + # mi = Array.new(7, 0) + # mi[0] = 0 + # mi[1] = dx + # mi[2] = dy + # mi[3] = mouse_data + # mi[4] = dw_flags + # mi.pack('LLLLLLL') + # end + # def self.keyboard_input_32(wVk, dw_flags) + # ki = Array.new(7, 0) + # ki[0] = 1 + # ki[1] = wVk + # ki[2] = dw_flags + # ki.pack('LLLLLLL') + # end end \ No newline at end of file diff --git a/sig/auto_click_methods.rbs b/sig/auto_click_methods.rbs index de49c5d..fb3842f 100644 --- a/sig/auto_click_methods.rbs +++ b/sig/auto_click_methods.rbs @@ -1,59 +1,60 @@ module AutoClickMethods - def send_input: (Array[String]) -> void + def send_input: (Array[String]) -> void - def get_screen_resolution: -> Array[Integer] + def get_screen_resolution: -> Array[Integer] - def mouse_move: (Integer, Integer) -> void + def mouse_move: (Integer, Integer) -> void - def mouse_move_percentage: (Integer, Integer) -> void + def mouse_move_percentage: (Integer, Integer) -> void - def right_click: -> void + def right_click: -> void - def left_click: -> void + def left_click: -> void - def middle_click: -> void + def middle_click: -> void - def mouse_down: (:right | :middle | :left) -> void + def mouse_down: (:right | :middle | :left) -> void - def mouse_up: (:right | :middle | :left) -> void + def mouse_up: (:right | :middle | :left) -> void - def double_click: -> void + def double_click: -> void - def right_click_32: -> void + def cursor_position: -> Array[Integer] - def left_click_32: -> void + def mouse_scroll: (Integer) -> void - def middle_click_32: -> void + def left_drag: (Integer, Integer, Integer, Integer) -> void - def mouse_down_32: (:right | :middle | :left) -> void + def right_drag: (Integer, Integer, Integer, Integer) -> void - def mouse_up_32: (:right | :middle | :left) -> void + def key_stroke: (*(:right | :middle | :left)) -> void - def double_click_32: -> void + def key_down: (:right | :middle | :left) -> void - def left_drag_32: (Integer, Integer, Integer, Integer) -> void + def key_up: (:right | :middle | :left) -> void - def right_drag_32: (Integer, Integer, Integer, Integer) -> void + def type: (String) -> void - def key_stroke_32: (:right | :middle | :left) -> void + def get_key_state: (:right | :middle | :left) -> Integer +end - def key_down_32: (:right | :middle | :left) -> void +module VirtualKey + def self.code_from_name: (Symbol | String | Integer) -> Integer +end - def key_up_32: (:right | :middle | :left) -> void +module User32 + def self.GetCursorPos: (String) -> Integer - def cursor_position: -> Array[Integer] + def self.SetCursorPos: (Integer, Integer) -> Integer - def mouse_scroll: (Integer) -> void + def self.SendInput: (Integer, String, Integer) -> Integer - def left_drag: (Integer, Integer, Integer, Integer) -> void + def self.GetKeyState: (Integer) -> Integer - def right_drag: (Integer, Integer, Integer, Integer) -> void + def self.GetSystemMetrics: (Integer) -> Integer +end - def key_stroke: (*(:right | :middle | :left)) -> void +module InputStructure + def self.mouse_input: (Integer, Integer, Integer, Integer) -> String - def key_down: (:right | :middle | :left) -> void - - def key_up: (:right | :middle | :left) -> void - - def type: (String) -> void -end \ No newline at end of file + def self.keyboard_input: (Integer, Integer) -> String From c4e5d364ac472a406ac83de97df2cd9ab46c0838 Mon Sep 17 00:00:00 2001 From: BrianPurgert Date: Tue, 18 Jun 2024 19:46:34 -0400 Subject: [PATCH 6/7] Continued development... --- .idea/active-tab-highlighter-v2.xml | 8 + .idea/auto_click.iml | 6 +- Gemfile | 2 +- lib/auto_click.rb | 491 ++++++++++++++-------------- lib/auto_click/input_structure.rb | 64 ++-- lib/auto_click/version.rb | 2 +- lib/auto_click/virtual_key.rb | 272 +++++++-------- sig/auto_click_methods.rbs | 1 + 8 files changed, 434 insertions(+), 412 deletions(-) create mode 100644 .idea/active-tab-highlighter-v2.xml diff --git a/.idea/active-tab-highlighter-v2.xml b/.idea/active-tab-highlighter-v2.xml new file mode 100644 index 0000000..bdaf016 --- /dev/null +++ b/.idea/active-tab-highlighter-v2.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/.idea/auto_click.iml b/.idea/auto_click.iml index 3c30049..320af29 100644 --- a/.idea/auto_click.iml +++ b/.idea/auto_click.iml @@ -9,15 +9,17 @@ - + + - + + - + +