jarmo / RAutomation

RAutomation
MIT License
100 stars 33 forks source link

How to get an array of objects with same property #78

Closed andreimarfievici closed 10 years ago

andreimarfievici commented 10 years ago

Hi all,

I have a Siebel app that runs in IE8 and I want to interact with some ActiveX controls that are basically some windows. These controls don't have any name or id, but I can get their hwnds with WinSpy++:

w = RAutomation::Window.new :hwnd=>'00090BB2'.to_i(16)

The problem is that the hwnds are changing every time I open the app so I was thinking getting their parent that is the Internet Explorer Server inside the IE browser, then get the children and reference each child by index. I want to get the parent cause it actually has a class name. Or can I get an array with all the children if I know their class name (#32770 in this case)?

So how can I interact with these elements if their hwnds change all the time?

I have attached a screenshot of the app taken with WinSpy++.

Thanks a lot!\ Andrei siebel

leviwilson commented 10 years ago

Have you tried using the :ms_uia adapter? I'm curious if either Inspect or UISpy see these controls (by either their AutomationId or Name properties).

jarmo commented 10 years ago

You can get all the children via class name like this:

controls = window.controls(class: "#32770")
puts controls[0].hwnd

Not sure if this works with ms_uia adapter too.

andreimarfievici commented 10 years ago

Thank you guys, it works great using controls, now I can have a model like

ie = RAutomation::Window.new :title => /Siebel/
sieb_controls = ie.controls(:class => 'Edit')
customer_name = RAutomation::Window.new :hwnd => sieb_controls[7]
customer_name.send_keys 'test customer'

Keep up the good work!

andreimarfievici commented 10 years ago

By the way, it works with ms_uia too and then instead of getting value, I use control_name:

ie = RAutomation::Window.new(:title=>/Siebel/, :adapter => 'ms_uia')
ie.controls(:class=>'Edit').each{|o| p o.control_name}

Thanks again!

Still, would be great to be able to get the parent window. Is there any way to do that?

leviwilson commented 10 years ago

Currently there isn't any way to get the immediate parent of a control. You can get the Window that it is within (through control.instance_variable_get(:@window)) but it isn't publicly exposed. What would be the use case for that?

andreimarfievici commented 10 years ago

In my example, I have a window with an edit control. For this edit field, I want to set and get text.

#to get the text of an Edit field I use the Window object with the text method
w = RAutomation::Window.new :hwnd => '004308BC'.to_i(16)
w.text
=> "6421586488"
#if we do w.send_keys, it doesn't work
#to set the value of an edit field, we have to get the Edit control inside the window, create a new window with its hwnd and send keys to it
edit_field = w.control(:class=>'Edit')
edit = RAutomation::Window.new :hwnd => edit_field.hwnd
edit.send_keys 'blah'
#but if I do edit.text I don't get blah, I have to refer the parent again
edit.text
=> ""
w.text
=> "blah"

It would be a little bit more intuitive if I can do edit.parent.text, although I don't understand why it doesn't work with edit.text

The problem is I have to create 2 separate windows and use one as a setter and the other one as a getter. Using the parent reference would make things easier rather than getting the hwnd and create new object.

Maybe it's just my example, anyway I can totally work around this. Hope I made my self clear enough...

Thanks, Andrei