Class: RAutomation::Adapter::MsUia::Window

Inherits:
Object
  • Object
show all
Includes:
Locators, WaitHelper
Defined in:
lib/rautomation/adapter/ms_uia/window.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(container, locators) ⇒ Window

Note:

this method is not meant to be accessed directly, but only through Window#initialize!

Possible locators are :title, :text, :hwnd, :pid, :class and :index. todo - update list of valid locators for UIA Creates the window object.

Parameters:

  • locators (Hash)

    for searching the window.

Options Hash (locators):

  • :title (String, Regexp)

    Title of the window

  • :text (String, Regexp)

    Visible text of the window

  • :class (String, Regexp)

    Internal class name of the window

  • :hwnd (String, Fixnum)

    Window handle in decimal format

  • :pid (String, Fixnum)

    Window process ID (PID)

  • :index (String, Fixnum)

    0-based index to specify n-th window if all other criteria match all other criteria match

See Also:



40
41
42
43
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 40

def initialize(container, locators)
  @container = container
  extract(locators)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args)

Redirects all method calls not part of the public API to the Functions directly.



189
190
191
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 189

def method_missing(name, *args)
  Functions.respond_to?(name) ? Functions.send(name, *args) : super
end

Instance Attribute Details

#locators (readonly)

Locators of the window.



25
26
27
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 25

def locators
  @locators
end

Class Method Details

.oleacc_module_handle



15
16
17
18
19
20
21
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 15

def oleacc_module_handle
  @oleacc_module_handle ||= begin
    oleacc = Functions.load_library "oleacc.dll"
    Functions.co_initialize nil
    oleacc
  end
end

Instance Method Details

#activate

See Also:



79
80
81
82
83
84
85
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 79

def activate
  return if !exists? || active?
  restore if minimized?
  Functions.activate_window(hwnd)
  restore if minimized?
  sleep 1
end

#active?Boolean

todo - replace with UIA version

Returns:

  • (Boolean)

See Also:



89
90
91
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 89

def active?
  exists? && Functions.foreground_window == hwnd
end

#bounding_rectangle



281
282
283
284
285
286
287
288
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 281

def bounding_rectangle
  window = UiaDll::element_from_handle(hwnd)

  boundary = FFI::MemoryPointer.new :long, 4
  UiaDll::bounding_rectangle(window, boundary)

  boundary.read_array_of_long(4)
end

#button(locator)



177
178
179
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 177

def button(locator)
  Button.new(self, locator)
end

#checkbox(locator)



328
329
330
331
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 328

def checkbox(locator)
  @container.wait_until_present
  Checkbox.new(self, locator)
end

#child(locators) ⇒ RAutomation::Window

Note:

This is an Win32 adapter specific method, not part of the public API

todo - replace with UIA version Creates the child window object.

Examples:

RAutomation::Window.new(:title => /Windows Internet Explorer/i).
  child(:title => /some popup/)

Parameters:

  • locators (Hash)

    for searching the window.

Returns:



351
352
353
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 351

def child(locators)
  RAutomation::Window.new Functions.child_window_locators(hwnd, locators)
end

#class_names

See Also:



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 66

def class_names
  root_element = UiaDll::element_from_handle(hwnd)

  root_class = FFI::MemoryPointer.new :char, UiaDll::get_class_name(root_element, nil) + 1
  UiaDll::get_class_name(root_element, root_class)

  classes = gather_children_classes(root_element)
  classes = classes.flatten
  classes.delete("")
  classes.sort
end

#click_mouse



294
295
296
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 294

def click_mouse()
  UiaDll::click_mouse
end

#close

todo - replace with UIA version

See Also:



171
172
173
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 171

def close
  Functions.close_window(hwnd)
end

#control(locator)



303
304
305
306
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 303

def control(locator)
  @container.wait_until_present
  Control.new(self, locator)
end

#controls(locator)



308
309
310
311
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 308

def controls(locator)
  @container.wait_until_present
  Controls.new(self, locator)
end

#count_children(element)



250
251
252
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 250

def count_children(element)
  UiaDll::find_children(element, nil)
end

#display_tree



218
219
220
221
222
223
224
225
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 218

def display_tree
  root_element = UiaDll::element_from_handle(hwnd)

  root_name = FFI::MemoryPointer.new :char, UiaDll::get_name(root_element, nil) + 1
  UiaDll::get_name(root_element, root_name)

  [root_name.read_string.inspect, gather_children(root_element)]
end

#element

MsUia adapter specific API methods



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 194

def element
  case
    when @locators[:focus]
      uia_control = UiaDll::get_focused_element
    when @locators[:id]
      uia_control = UiaDll::find_window(@locators[:id].to_s)
      raise UnknownElementException, "#{@locators[:id]} does not exist" if uia_control.nil?
    when @locators[:point]
      uia_control = UiaDll::element_from_point(@locators[:point][0], @locators[:point][1])
      raise UnknownElementException, "#{@locators[:point]} does not exist" if uia_control.nil?
    else
      hwnd = find_hwnd(locators, window_hwnd) do |hwnd|
        locators_match?(locators, control_properties(hwnd, locators))
      end
      raise UnknownElementException, "Element with #{locators.inspect} does not exist" if (hwnd == 0) or (hwnd == nil)
      uia_control = UiaDll::element_from_handle(hwnd)
  end
  uia_control
end

#exists?Boolean

todo - replace with UIA version

Returns:

  • (Boolean)

See Also:



101
102
103
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 101

def exists?
  hwnd && Functions.window_exists(hwnd)
end

#gather_children(root_element)



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 227

def gather_children(root_element)
  element_tree = []

  child_count = count_children(root_element)
  children = FFI::MemoryPointer.new :pointer, child_count
  UiaDll::find_children(root_element, children)

  children.read_array_of_pointer(child_count).each do |child|
    child_name = FFI::MemoryPointer.new :char, UiaDll::get_name(child, nil) + 1
    UiaDll::get_name(child, child_name)

    grandchild_count = count_children(child)

    if grandchild_count > 0
      element_tree << [child_name.read_string, gather_children(child)]
    else
      element_tree << child_name.read_string
    end
  end

  element_tree
end

#gather_children_classes(root_element)



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 254

def gather_children_classes(root_element)
  element_tree = []

  child_count = count_children(root_element)
  children = FFI::MemoryPointer.new :pointer, child_count
  UiaDll::find_children(root_element, children)

  children.read_array_of_pointer(child_count).each do |child|
    child_name = FFI::MemoryPointer.new :char, UiaDll::get_class_name(child, nil) + 1
    UiaDll::get_class_name(child, child_name)

    grandchild_count = count_children(child)

    if grandchild_count > 0
      element_tree << [child_name.read_string, gather_children_classes(child)]
    else
      element_tree << child_name.read_string
    end
  end

  element_tree
end

#get_focused_element



277
278
279
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 277

def get_focused_element
  UiaDll::get_focused_element()
end

#hwnd

Note:

Searches only for visible windows.

todo - replace with UIA version Retrieves handle of the window.

See Also:



49
50
51
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 49

def hwnd
  @hwnd ||= Functions.window_hwnd(@locators)
end

#label(locator)



298
299
300
301
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 298

def label(locator)
  @container.wait_until_present
  Label.new(self, locator)
end

#list_box(locator)



313
314
315
316
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 313

def list_box(locator)
  @container.wait_until_present
  ListBox.new(self, locator)
end

#list_item(locator)



318
319
320
321
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 318

def list_item(locator)
  @container.wait_until_present
  ListItem.new(self, locator)
end

#maximize

todo - replace with UIA version

See Also:



113
114
115
116
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 113

def maximize
  Functions.show_window(hwnd, Constants::SW_MAXIMIZE)
  sleep 1
end

#minimize

todo - replace with UIA version

See Also:



120
121
122
123
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 120

def minimize
  Functions.show_window(hwnd, Constants::SW_MINIMIZE)
  sleep 1
end

#minimized?Boolean

todo - replace with UIA version

Returns:

  • (Boolean)

See Also:



127
128
129
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 127

def minimized?
  Functions.minimized(hwnd)
end

#move_mouse(x, y)



290
291
292
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 290

def move_mouse(x, y)
  UiaDll::move_mouse(x, y)
end

#new_pid



214
215
216
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 214

def new_pid
  UiaDll::current_process_id(uia_control())
end

#pid

todo - replace with UIA version

See Also:



55
56
57
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 55

def pid
  Functions.window_pid(hwnd)
end

#radio(locator)



333
334
335
336
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 333

def radio(locator)
  @container.wait_until_present
  Radio.new(self, locator)
end

#restore

todo - replace with UIA version

See Also:



133
134
135
136
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 133

def restore
  Functions.show_window(hwnd, Constants::SW_RESTORE)
  sleep 1
end

#select_list(locator)



323
324
325
326
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 323

def select_list(locator)
  @container.wait_until_present
  SelectList.new(self, locator)
end

#send_keys(args)

Activates the window and sends keys to it.

Refer to Keys::KEYS for all the special keycodes.

Examples:

RAutomation::Window.new(:title => //).send_keys "hello!"
RAutomation::Window.new(:title => //).send_keys [:control, "a"], "world!"

See Also:



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 145

def send_keys(args)
  Keys.encode(args).each do |arg|
    wait_until do
      activate
      active?
    end

    if arg.is_a?(Array)
      arg.reduce([]) do |pressed_keys, k|
        if k == Keys[:null]
          pressed_keys.each {|pressed_key| release_key pressed_key}
          pressed_keys = []
        else
          pressed_keys << press_key(k)
        end
        pressed_keys
      end
    else
      send_key arg
    end
  end
  sleep 1
end

#table(locator)



338
339
340
341
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 338

def table(locator)
  @container.wait_until_present
  Table.new(self, locator)
end

#text

todo - replace with UIA version

See Also:



95
96
97
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 95

def text
  Functions.window_text(hwnd)
end

#text_field(locator)



183
184
185
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 183

def text_field(locator)
  TextField.new(self, locator)
end

#title

todo - replace with UIA version

See Also:



61
62
63
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 61

def title
  Functions.window_title(hwnd)
end

#visible?Boolean

todo - replace with UIA version

Returns:

  • (Boolean)

See Also:



107
108
109
# File 'lib/rautomation/adapter/ms_uia/window.rb', line 107

def visible?
  Functions.window_visible(hwnd)
end