Module: Vigilem::Win32API::DOM::InputRecordUtils Abstract
- Includes:
- Constants, CodeValuesTables, Utils::Keyboard, VirtualKeys
- Included in:
- Adapter
- Defined in:
- lib/vigilem/win32_api/dom/input_record_utils.rb
Overview
requires a dom_ir_utils_source method and included into the same module as RubyizedAPI
module KeyEventRecordUtils
msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx methods to convert InputRecords to DOM Events
Constant Summary collapse
- NULL_STR =
"\x00"- UNKNOWN_VAL =
'Unidentified'
Constants included from VirtualKeys
VirtualKeys::Map, VirtualKeys::VK
Constants included from CodeValuesTables
CodeValuesTables::ArrowPadSection, CodeValuesTables::ControlPadSection, CodeValuesTables::FunctionSection, CodeValuesTables::FunctionalKeys, CodeValuesTables::LegacyKeysandNon_StandardKeys, CodeValuesTables::MediaKeys, CodeValuesTables::NumpadSection, CodeValuesTables::WritingSystemKeys
Constants included from Constants
Constants::BACKGROUND_BLUE, Constants::BACKGROUND_GREEN, Constants::BACKGROUND_INTENSITY, Constants::BACKGROUND_RED, Constants::CONSOLE_TEXTMODE_BUFFER, Constants::DOUBLE_CLICK, Constants::ENABLE_ECHO_INPUT, Constants::ENABLE_LINE_INPUT, Constants::ENABLE_MOUSE_INPUT, Constants::ENABLE_PROCESSED_INPUT, Constants::ENABLE_PROCESSED_OUTPUT, Constants::ENABLE_WINDOW_INPUT, Constants::ENABLE_WRAP_AT_EOL_OUTPUT, Constants::FILE_SHARE_READ, Constants::FILE_SHARE_WRITE, Constants::FOREGROUND_BLUE, Constants::FOREGROUND_GREEN, Constants::FOREGROUND_INTENSITY, Constants::FOREGROUND_RED, Constants::FROM_LEFT_1ST_BUTTON_PRESSED, Constants::FROM_LEFT_2ND_BUTTON_PRESSED, Constants::FROM_LEFT_3RD_BUTTON_PRESSED, Constants::FROM_LEFT_4TH_BUTTON_PRESSED, Constants::GENERIC_READ, Constants::GENERIC_WRITE, Constants::INVALID_HANDLE_VALUE, Constants::MOUSE_MOVED, Constants::MOUSE_WHEELED, Constants::MapVK, Constants::RIGHTMOST_BUTTON_PRESSED, Constants::STD_ERROR_HANDLE, Constants::STD_INPUT_HANDLE, Constants::STD_OUTPUT_HANDLE
Constants included from Constants::MapType
Constants::MapType::MAPVK, Constants::MapType::MAPVK_VK_TO_CHAR, Constants::MapType::MAPVK_VK_TO_VSC, Constants::MapType::MAPVK_VSC_TO_VK, Constants::MapType::MAPVK_VSC_TO_VK_EX
Constants included from Constants::Events
Constants::Events::CTRL_BREAK_EVENT, Constants::Events::CTRL_CLOSE_EVENT, Constants::Events::CTRL_C_EVENT, Constants::Events::CTRL_LOGOFF_EVENT, Constants::Events::CTRL_SHUTDOWN_EVENT, Constants::Events::FOCUS_EVENT, Constants::Events::KEY_EVENT, Constants::Events::MENU_EVENT, Constants::Events::MOUSE_EVENT, Constants::Events::WINDOW_BUFFER_SIZE_EVENT
Constants included from Constants::DWControlKeys
Constants::DWControlKeys::CAPSLOCK_ON, Constants::DWControlKeys::ENHANCED_KEY, Constants::DWControlKeys::LEFT_ALT_PRESSED, Constants::DWControlKeys::LEFT_CTRL_PRESSED, Constants::DWControlKeys::NUMLOCK_ON, Constants::DWControlKeys::RIGHT_ALT_PRESSED, Constants::DWControlKeys::RIGHT_CTRL_PRESSED, Constants::DWControlKeys::SCROLLLOCK_ON, Constants::DWControlKeys::SHIFT_PRESSED
Class Method Summary collapse
-
.empty_or_null?(str) ⇒ TrueClass || FalseClass
is #empty? or just contains NULL_STR.
-
.flip_lr_sides(str) ⇒ String<'R'||'r'||'L'||'l'>
Its opposite.
- .lr_location_from_name(key_name) ⇒ String || NilClass
Instance Method Summary collapse
-
#current_keys ⇒ Array
the current keys being pressed.
- #dom_code(virtual_key, u_char_value, location, *dw_state_names) ⇒ Object
- #dom_key(virtual_key, u_char) ⇒ String
- #dom_location(vk_name, v_scancode, dw_state_names) ⇒ Integer<0|1|2>
- #dom_modifiers(*dw_control_state_names) ⇒ Array
-
#dw_control_key_state_vks(dw_control_key_state) ⇒ Array<Symbol>
converts a Integer representing dwControlKeyState from KEY_EVENT_RECORD to an array of virtual-keys, Symbols.
- #location_less_vks_map ⇒ Hash
-
#lr_not_in_name(vk_name, v_scancode, dw_state_names) ⇒ String<'l'||'r'>
gets the l or r using other params than just the name.
-
#lr_not_in_name!(vk_name, v_scancode, dw_state_names) ⇒ String<'l'|'r'>
gets the l or r using other params than just the name.
- #shift_scan_code_to_location_vk ⇒ Hash
-
#to_dom_key_event(event_record) ⇒ Array<Vigilem::DOM::KeyboardEvent>
converts and event_record to DOM KeyEvent.
- #vk_without_location_info?(vk_name) ⇒ TrueClass || FalseClass
Methods included from Utils::Keyboard::ControlPadKeys
Methods included from Utils::Keyboard::NavigationKeys
#arrow_key?, #nav_arrow_key?, #nav_control_key?
Methods included from Utils::Keyboard::NumpadKeys
#numlock?, #numpad?, #numpad_arrow?, #numpad_control_key?, #numpad_number_function?, #numpad_return?
Class Method Details
.empty_or_null?(str) ⇒ TrueClass || FalseClass
is #empty? or just contains NULL_STR
127 128 129 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 127 def empty_or_null?(str) str.strip.empty? or (str == NULL_STR * str.length) end |
.flip_lr_sides(str) ⇒ String<'R'||'r'||'L'||'l'>
Returns its opposite.
112 113 114 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 112 def flip_lr_sides(str) str.tr('LlRr', 'RrLl') end |
.lr_location_from_name(key_name) ⇒ String || NilClass
119 120 121 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 119 def lr_location_from_name(key_name) key_name.to_s.gsub(/VK_(L(?!EFT)|R(?!IGHT))?.+/, '\1')[/L|R/] end |
Instance Method Details
#current_keys ⇒ Array
the current keys being pressed
36 37 38 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 36 def current_keys @current_keys ||= [] end |
#dom_code(virtual_key, u_char_value, location, *dw_state_names) ⇒ Object
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 209 def dom_code(virtual_key, u_char_value, location, *dw_state_names) if (code = CodeTable.dom_code(Support::Utils.unwrap_ary([*dw_state_names.grep(:ENHANCED_KEY), virtual_key]))) if code.is_a? Array dom_loc = location.is_a?(String) ? ::VDOM::Utils.common_str_to_dom_location(location.upcase) : location code.grep(::VDOM::Utils.codes_regex[dom_loc]).first else code end else if(char = u_char_value.chr) =~ /^[a-z]$/i "Key#{char.upcase}" elsif char =~ /^[0-9]$/ "Digit#{char}" else UNKNOWN_VAL end end end |
#dom_key(virtual_key, u_char) ⇒ String
192 193 194 195 196 197 198 199 200 201 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 192 def dom_key(virtual_key, u_char) vk = :"VK_#{virtual_key.to_s.gsub(/^VK_/, '')}" # returns 0 when no character available if KeyValuesTables::WhitespaceKeys.has_key?(vk) or (character = dom_ir_utils_source.map_virtual_key(Map.virtual_key_code(vk), MAPVK::VK_TO_CHAR)) == 0 KeyTable.dom_key(vk) || UNKNOWN_VAL else u_char.chr end end |
#dom_location(vk_name, v_scancode, dw_state_names) ⇒ Integer<0|1|2>
137 138 139 140 141 142 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 137 def dom_location(vk_name, v_scancode, dw_state_names) l_r_location = InputRecordUtils.lr_location_from_name(vk_name) || lr_not_in_name(vk_name, v_scancode, dw_state_names) || "" ::VDOM::Utils.common_str_to_dom_location(l_r_location.upcase) || DOM_KEY_LOCATION_STANDARD end |
#dom_modifiers(*dw_control_state_names) ⇒ Array
231 232 233 234 235 236 237 238 239 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 231 def dom_modifiers(*dw_control_state_names) ::VDOM::KeyboardEvent::shared_keyboard_and_mouse_event_init(dw_control_state_names.map do |mod| if mod == :RIGHT_ALT_PRESSED :metaKey else mod.to_s.gsub(/right|left|pressed|on|_/i, '').downcase.to_sym end end) end |
#dw_control_key_state_vks(dw_control_key_state) ⇒ Array<Symbol>
converts a Integer representing dwControlKeyState from KEY_EVENT_RECORD to an array of virtual-keys, Symbols
82 83 84 85 86 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 82 def dw_control_key_state_vks(dw_control_key_state) DWControlKeys.constants.select do |const| (dw_control_key_state & (value = DWControlKeys.const_get(const))) == value end end |
#location_less_vks_map ⇒ Hash
90 91 92 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 90 def location_less_vks_map @location_less_vks_map ||= {:VK_MENU => /alt/i, :VK_CONTROL => /control|ctrl/i, :VK_SHIFT => /shift/i } end |
#lr_not_in_name(vk_name, v_scancode, dw_state_names) ⇒ String<'l'||'r'>
gets the l or r using other params than just the name
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 165 def lr_not_in_name(vk_name, v_scancode, dw_state_names) if vk_name == :VK_SHIFT if lr = InputRecordUtils.lr_location_from_name(shift_scan_code_to_location_vk[v_scancode]) lr.downcase end else regexp = location_less_vks_map[vk_name] # other side key pressed? weird but eh if other_location = current_keys.find {|current| current.key =~ regexp } InputRecordUtils.flip_lr_sides(::VDOM::Utils.to_dom_location_common_str(other_location.location)).downcase # ok other one isn't being pressed then the one showing up in dw_control_state is this else applicable_state_names = dw_state_names.grep(regexp) # there are no previous keys if applicable_state_names.size > 1 raise "Both `#{vk_name}' are pressed but there is no record in the current keys:#{current_keys.join(',')}" elsif location = InputRecordUtils.lr_location_from_name(dw_state_names.grep(regexp).first) location.downcase end end end end |
#lr_not_in_name!(vk_name, v_scancode, dw_state_names) ⇒ String<'l'|'r'>
gets the l or r using other params than just the name
151 152 153 154 155 156 157 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 151 def lr_not_in_name!(vk_name, v_scancode, dw_state_names) if lr = lr_not_in_name(vk_name, v_scancode, dw_state_names) lr else raise RuntimeError, "Cannot get location from #{vk_name}, #{v_scancode}, #{current_keys}, #{dw_state_names}" end end |
#shift_scan_code_to_location_vk ⇒ Hash
103 104 105 106 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 103 def shift_scan_code_to_location_vk @shift_scan_location ||= { dom_ir_utils_source.map_virtual_key(VK[:LSHIFT], MAPVK::VK_TO_VSC) => :VK_LSHIFT, dom_ir_utils_source.map_virtual_key(VK[:RSHIFT], MAPVK::VK_TO_VSC) => :VK_RSHIFT } end |
#to_dom_key_event(event_record) ⇒ Array<Vigilem::DOM::KeyboardEvent>
the righ Alt and right ctrl are ‘enhanced’
converts and event_record to DOM KeyEvent
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 44 def to_dom_key_event(event_record) dw_state_names = dw_control_key_state_vks(event_record.dwControlKeyState) # all test need fixed # will this work for a range? if not it needs to virtual_key_name = Map.virtual_keyname(vk_code = event_record.wVirtualKeyCode) modifiers = dom_modifiers(*dw_state_names) dom_loc = dom_location(virtual_key_name, event_record.wVirtualScanCode, dw_state_names) key = dom_key(virtual_key_name, u_char = event_record.uChar.UnicodeChar) code = dom_code(virtual_key_name, u_char, dom_loc, *dw_state_names) = {:key => key, :code => code, :location => dom_loc, :repeat => false, :modifiers => modifiers, :os_specific => ::FFIUtils.struct_to_h(event_record) } if event_record.bKeyDown == 1 if (prev_event = current_keys.last) and %w(keypress keydown).include?(prev_event.type) and prev_event.key == [:key] [:repeat] = true end key_event = ::VDOM::KeyboardEvent.new('keydown', ) key_down_events = [key_event, key_event.copy_to('keypress')] @current_keys += key_down_events.flatten key_down_events else key_event = ::VDOM::KeyboardEvent.new('keyup', ) current_keys.delete_if {|current| current.key == key_event.key and current.location == key_event.location } [*key_event].flatten end end |
#vk_without_location_info?(vk_name) ⇒ TrueClass || FalseClass
97 98 99 |
# File 'lib/vigilem/win32_api/dom/input_record_utils.rb', line 97 def vk_without_location_info?(vk_name) location_less_vks_map.keys.include? vk_name end |