lib/rautomation/adapter/ms_uia/uia_dll.rb in rautomation-0.8.0 vs lib/rautomation/adapter/ms_uia/uia_dll.rb in rautomation-0.9.0
- old
+ new
@@ -5,105 +5,273 @@
module Adapter
module MsUia
module UiaDll
extend FFI::Library
+ HowToFind = enum(:hwnd, 1,
+ :id,
+ :value,
+ :focus,
+ :point)
+
+
+ class FindData < FFI::Union
+ layout :string_data, [:uint8, 256],
+ :int_data, :int,
+ :point_data, [:int, 2]
+ end
+
+ class SearchCriteria < FFI::Struct
+ def self.from_locator(parent, locator)
+ info = SearchCriteria.new
+ info.parent_window = parent
+ info.index = locator[:index] || 0
+
+ case
+ when locator[:hwnd]
+ info.how = :hwnd
+ info.data = locator[:hwnd]
+ when locator[:id]
+ info.how = :id
+ info.data = locator[:id]
+ when locator[:value]
+ info.how = :value
+ info.data = locator[:value]
+ when locator[:point]
+ info.how = :point
+ info.data = locator[:point]
+ when locator[:focus]
+ info.how = :focus
+ end
+ info
+ end
+
+ def how
+ self[:how]
+ end
+
+ def how=(value)
+ self[:how] = value
+ end
+
+ def index
+ self[:index]
+ end
+
+ def index=(value)
+ self[:index] = value
+ end
+
+ def parent_window
+ self[:hwnd]
+ end
+
+ def parent_window=(parent)
+ self[:hwnd] = parent
+ end
+
+ def data
+ case how
+ when :hwnd
+ return self[:data][:int_data]
+ when :id, :value
+ return self[:data][:string_data].to_ptr.read_string
+ when :point
+ return self[:data][:point_data].to_ptr.read_array_of_int(2)
+ else
+ return nil
+ end
+ end
+
+ def data=(value)
+ case how
+ when :hwnd
+ self[:data][:int_data] = value
+ when :id, :value
+ self[:data][:string_data] = value
+ when :point
+ self[:data][:point_data].to_ptr.write_array_of_int(value)
+ end
+ end
+
+ layout :hwnd, :int,
+ :index, :int,
+ :how, HowToFind, :data, FindData
+ end
+
ffi_lib File.dirname(__FILE__) + '/../../../../ext/UiaDll/Release/UiaDll.dll'
ffi_convention :stdcall
- attach_function :find_window, :RA_FindWindow,
- [:string], :pointer
- attach_function :is_offscreen, :RA_IsOffscreen,
- [:pointer], :bool
+ # Generic Control methods
+ attach_function :ElementExists, [SearchCriteria.by_ref], :bool
+ attach_function :process_id, :ProcessId, [SearchCriteria.by_ref], :int
+ attach_function :Control_GetValue, [:long, :pointer, :int], :void
+ attach_function :set_control_value, :Control_SetValue, [:long, :string], :void
+ attach_function :BoundingRectangle, [SearchCriteria.by_ref, :pointer], :int
+ attach_function :current_control_type, :ControlType, [SearchCriteria.by_ref], :int
+ attach_function :Name, [SearchCriteria.by_ref, :pointer, :int], :void
+ attach_function :ClassName, [SearchCriteria.by_ref, :pointer, :int], :void
+ attach_function :GetClassNames,
+ [SearchCriteria.by_ref, :pointer], :int
+
+ def self.exists?(search_information)
+ ElementExists search_information
+ end
+
+ def self.bounding_rectangle(search_information)
+ boundary = FFI::MemoryPointer.new :long, 4
+ BoundingRectangle search_information, boundary
+ boundary.read_array_of_long(4)
+ end
+
+ def self.get_control_value(hwnd)
+ string_from(:Control_GetValue, hwnd)
+ end
+
+ def self.name(search_information)
+ string_from(:Name, search_information)
+ end
+
+ def self.class_name(search_information)
+ string_from(:ClassName, search_information)
+ end
+
+ def self.children_class_names(search_information)
+ strings_from :GetClassNames, search_information
+ end
+
+ # Toggle methods
+ attach_function :is_set, :IsSet, [SearchCriteria.by_ref], :bool
+
+ # Selection Item methods
+ attach_function :is_selected, :IsSelected, [SearchCriteria.by_ref], :bool
+
+ # Select List methods
+ attach_function :SelectList_Selection,
+ [SearchCriteria.by_ref, :pointer, :int], :void
+ attach_function :select_list_count, :SelectList_Count,
+ [SearchCriteria.by_ref], :int
+ attach_function :select_list_selected_index, :SelectList_SelectedIndex,
+ [:long], :int
+ attach_function :select_list_value_at, :SelectList_ValueAt,
+ [:long, :int, :pointer, :int], :bool
+ attach_function :select_list_select_index, :SelectList_SelectIndex,
+ [SearchCriteria.by_ref, :int], :bool
+ attach_function :select_list_select_value, :SelectList_SelectValue,
+ [SearchCriteria.by_ref, :pointer], :int
+
+ def self.selection(search_information)
+ string_from(:SelectList_Selection, search_information)
+ end
+
+ # Menu methods
+ attach_function :select_menu_item, :Menu_SelectPath,
+ [:long, :pointer, :int, :varargs], :void
+ attach_function :menu_item_exists, :Menu_ItemExists,
+ [:long, :varargs], :bool
+
+ # Table methods
+ attach_function :Table_GetHeaders,
+ [:long, :pointer], :int
+ attach_function :Table_GetValues,
+ [:long, :pointer], :int
+ attach_function :Table_FindValues,
+ [SearchCriteria.by_ref, :pointer], :int
+ attach_function :table_row_count, :Table_RowCount,
+ [:long], :int
+ attach_function :Table_CoordinateIsValid,
+ [:long, :int, :int], :bool
+ attach_function :Table_ValueAt,
+ [:long, :int, :int, :pointer, :int], :void
+ attach_function :Table_SelectByIndex,
+ [:long, :int], :void
+ attach_function :Table_SelectByValue,
+ [:long, :string], :void
+ attach_function :table_row_is_selected, :Table_IsSelectedByIndex,
+ [:long, :int], :bool
+
+ def self.table_select(hwnd, which_item)
+ case which_item
+ when Integer
+ Table_SelectByIndex hwnd, which_item
+ when String
+ Table_SelectByValue hwnd, which_item
+ end
+ end
+
+ def self.table_value_at(hwnd, row, column=0)
+ string_from(:Table_ValueAt, hwnd, row, column)
+ end
+
+ def self.table_coordinate_valid?(hwnd, row, column=0)
+ Table_CoordinateIsValid hwnd, row, column
+ end
+
+ def self.table_headers(hwnd)
+ strings_from :Table_GetHeaders, hwnd
+ end
+
+ def self.table_values(hwnd)
+ strings_from :Table_GetValues, hwnd
+ end
+
+ def self.find_table_values(search_information)
+ strings_from :Table_FindValues, search_information
+ end
+
+ # String methods
+ attach_function :clean_up_strings, :String_CleanUp,
+ [:pointer, :int], :void
+
attach_function :element_from_handle, :RA_ElementFromHandle,
[:long], :pointer
attach_function :element_from_point, :RA_ElementFromPoint,
[:int, :int], :pointer
- attach_function :get_focused_element, :RA_GetFocusedElement,
- [], :pointer
attach_function :find_child_by_id, :RA_FindChildById,
[:pointer, :string], :pointer
- attach_function :find_child_by_name, :RA_FindChildByName,
- [:pointer, :string], :pointer
attach_function :current_native_window_handle, :RA_CurrentNativeWindowHandle,
[:pointer], :long
attach_function :set_focus, :RA_SetFocus,
[:pointer], :bool
- attach_function :current_control_type, :RA_GetCurrentControlType,
- [:pointer], :int
- attach_function :desktop_handle, :RA_GetDesktopHandle,
- [], :long
attach_function :move_mouse, :RA_MoveMouse,
[:int,:int], :long
attach_function :click_mouse, :RA_ClickMouse,
[], :long
- attach_function :bounding_rectangle, :RA_CurrentBoundingRectangle,
- [:pointer, :pointer], :int
attach_function :is_offscreen, :RA_CurrentIsOffscreen,
[:pointer, :pointer], :int
attach_function :find_children, :RA_FindChildren,
[:pointer, :pointer], :int
- attach_function :get_name, :RA_GetName,
- [:pointer, :pointer], :int
- attach_function :get_class_name, :RA_GetClassName,
- [:pointer, :pointer], :int
- attach_function :get_is_selected, :RA_GetIsSelected,
- [:pointer], :bool
- attach_function :get_is_set, :RA_GetIsSet,
- [:pointer], :bool
+ attach_function :get_control_name, :RA_GetControlName,
+ [:long, :pointer, :int], :bool
attach_function :select, :RA_Select,
[:pointer], :int
- attach_function :find_window_by_pid, :RA_FindWindowByPID,
- [:int], :pointer
- attach_function :current_process_id, :RA_GetCurrentProcessId,
- [:pointer], :int
- attach_function :select_combo_by_index, :RA_SelectComboByIndex,
- [:long, :int], :bool
- attach_function :set_value, :RA_SelectComboByValue,
- [:pointer, :pointer], :int
- attach_function :select_menu_item, :RA_SelectMenuItem,
- [:long, :pointer, :int, :varargs], :void
- attach_function :menu_item_exists, :RA_MenuItemExists,
- [:long, :varargs], :bool
- attach_function :get_combobox_count, :RA_GetComboOptionsCount,
- [:long], :int
- attach_function :get_combobox_value, :RA_GetComboValueByIndex,
- [:long, :int, :pointer, :int], :bool
- attach_function :get_combobox_selected_index, :RA_GetSelectedComboIndex,
- [:long], :int
- attach_function :get_data_item_count, :RA_GetDataItemCount,
- [:long], :int
- attach_function :select_data_item, :RA_SelectDataItem,
- [:long, :int], :void
attach_function :expand_by_value, :RA_ExpandItemByValue,
[:long, :string], :void
attach_function :expand_by_index, :RA_ExpandItemByIndex,
[:long, :int], :void
attach_function :collapse_by_value, :RA_CollapseItemByValue,
[:long, :string], :void
attach_function :collapse_by_index, :RA_CollapseItemByIndex,
[:long, :int], :void
- attach_function :data_item_exists_by_value, :RA_DataItemExistsByValue,
- [:long, :string], :bool
- attach_function :RA_DataItemExists,
- [:long, :int, :int], :bool
-
- attach_function :RA_CellValueAt,
- [:long, :int, :int, :pointer, :int], :void
-
attach_function :control_click, :RA_Click,
[:long, :pointer, :int], :void
attach_function :control_mouse_click, :RA_PointAndClick,
[:long, :pointer, :int], :void
- def self.cell_value_at(hwnd, row, column=0)
- string = FFI::MemoryPointer.new :char, 1024
- RA_CellValueAt hwnd, row, column, string, 1024
- string.read_string
+ private
+ def self.strings_from(method, hwnd)
+ string_count = send method, hwnd, nil
+ pointer = FFI::MemoryPointer.new :pointer, string_count
+ send method, hwnd, pointer
+ strings = pointer.get_array_of_string 0, string_count
+ clean_up_strings pointer, string_count
+ strings
end
- def self.data_item_exists(hwnd, row, column=0)
- RA_DataItemExists hwnd, row, column
+ def self.string_from(method, *args)
+ pointer = FFI::MemoryPointer.new :pointer, 1024
+ send method, *(args << pointer << 1024)
+ pointer.read_string
end
end
end
end
end