Ranorex 2.0 and Controls
-
- Posts: 17
- Joined: Tue Dec 02, 2008 10:09 am
Ranorex 2.0 and Controls
Anyone know how to get the underlying Control from an Element?
- Support Team
- Site Admin
- Posts: 12145
- Joined: Fri Jul 07, 2006 4:30 pm
- Location: Houston, Texas, USA
- Contact:
There are fundamental differences between the ways Ranorex 1.5 and Ranorex 2.0 represent GUI elements:
In Ranorex 1.5 every window (i.e. every GUI element having a window handle) is represented as a Control object. GUI elements inside a window, not having window handles by themselves are represented by Element objects.
Ranorex 2.0 represents all GUI elements by Element objects. Each element has a distinct role and can have multiple capabilities. The role depends on the type of the GUI element, capabilities provide additional features specific to the technology Ranorex uses to interact with the GUI element. E.g. both a Win32 button and a WinForms button have the Button role. The Win32 button has the NativeWindow capability (giving access to its window handle), whereas the WinForms button has the Control capability providing additional features for Windows Forms controls. To use capability features you can create adapters from elements:
Creating an adapter from an element will only work if the element provides the corresponding capability, otherwise a CapabilityNotSupportedException will be raised.
So, there is no "underlying" control of an element, however, you can create a Control adapter from an element if it supports the Control capability. Just be sure to have references to the Ranorex plugin DLLs in your project when using plugin specific adapters.
Regards,
Alex
Ranorex Support Team
In Ranorex 1.5 every window (i.e. every GUI element having a window handle) is represented as a Control object. GUI elements inside a window, not having window handles by themselves are represented by Element objects.
Ranorex 2.0 represents all GUI elements by Element objects. Each element has a distinct role and can have multiple capabilities. The role depends on the type of the GUI element, capabilities provide additional features specific to the technology Ranorex uses to interact with the GUI element. E.g. both a Win32 button and a WinForms button have the Button role. The Win32 button has the NativeWindow capability (giving access to its window handle), whereas the WinForms button has the Control capability providing additional features for Windows Forms controls. To use capability features you can create adapters from elements:
Code: Select all
Element buttonElement = "pathToButton";
Control buttonControl = new Control(buttonElement);
// or simply
Control buttonControl = "pathToButton";
So, there is no "underlying" control of an element, however, you can create a Control adapter from an element if it supports the Control capability. Just be sure to have references to the Ranorex plugin DLLs in your project when using plugin specific adapters.
Regards,
Alex
Ranorex Support Team
-
- Posts: 17
- Joined: Tue Dec 02, 2008 10:09 am
That works as to getting the control. It even tells me what it is from the Control Type Property. But I want to be able to get hold of what it actually is.
The reason I want to do this, is because the GUI I'm trying to automate gives me a whole bunch of Ranorex.Unknown entries in my repository because the controls are custom, and don't report their roles. I can imagine this being the case for lots of GUI's out there that don't use standard WinForms controls for everything.
The Control instance gained from the above code tells me what the object is, my thinking would be to get at that object and interrogate it's properties myself.
The reason I want to do this, is because the GUI I'm trying to automate gives me a whole bunch of Ranorex.Unknown entries in my repository because the controls are custom, and don't report their roles. I can imagine this being the case for lots of GUI's out there that don't use standard WinForms controls for everything.
The Control instance gained from the above code tells me what the object is, my thinking would be to get at that object and interrogate it's properties myself.
- Support Team
- Site Admin
- Posts: 12145
- Joined: Fri Jul 07, 2006 4:30 pm
- Location: Houston, Texas, USA
- Contact:
As the actual Windows.Forms.Control you want to get access to resides in another process, you can't get a direct reference to that object. However, the Control adapter provides methods to get/set properties of the control (GetPropertyValue and SetPropertyValue) and to invoke methods on the control (InvokeMethod).
The only thing to be aware of is that you implicitly access a control in another process and that all parameters and return values of the properties/methods need to be serializable (e.g. all primitive types are serializable). If the values are not serializable, you can use the Control.InvokeRemotely method as a workaround.
I wrote a blog covering this topic some time ago. It was written for Ranorex 1.5, but everything written there is true for Ranorex 2.0 as well:
http://www.ranorex.com/blog/transfering ... et-control
Regards,
Alex
Ranorex Support Team
Code: Select all
Control myCustomControl = "pathToCustomControl";
object customPropertyValue = myCustomControl.GetPropertyValue("MyCustomPropertyName");
I wrote a blog covering this topic some time ago. It was written for Ranorex 1.5, but everything written there is true for Ranorex 2.0 as well:
http://www.ranorex.com/blog/transfering ... et-control
Regards,
Alex
Ranorex Support Team
-
- Posts: 17
- Joined: Tue Dec 02, 2008 10:09 am
- Support Team
- Site Admin
- Posts: 12145
- Joined: Fri Jul 07, 2006 4:30 pm
- Location: Houston, Texas, USA
- Contact:
Imagine you have a class MyUserControl inheriting from System.Windows.Forms.Control, then you can construct a delegate that is executed in the process that is running that control. For the following sample you have to add a reference to the DLL that defines the MyUserControl class:
Just be sure that the method is declared static and that all parameters as well as return values are serializable.
Regards,
Alex
Ranorex Support Team
Code: Select all
static void Main()
{
Ranorex.Control userControl = "pathToTheUserControl";
string value = (string)userControl.InvokeRemotely(MethodToExecuteRemotely);
}
static object MethodToExecuteRemotely(System.Windows.Forms.Control control, object inputData)
{
// this code is executed in the automated process
MyUserControl myControl = control as MyUserControl;
if (myControl != null)
{
string stringValue = myControl.SomeProperty.Name;
return stringValue;
}
return null;
}
Regards,
Alex
Ranorex Support Team
-
- Posts: 29
- Joined: Tue Mar 03, 2009 11:43 pm
Hi there guys,
i'm not getting it all here...
you say that the InvokeRemotely() method is to help in getting unserializable data from the process running the control.
In the end you say "Just be sure that the method is declared static and that all parameters as well as return values are serializable. "
This is a way to get unserializable data...
Please clarify me as we are having an issue with the ChartFx.AxisX property which is not serializable. We are using the procedure above to get the value as follows:
Test execution throws an ActionFailedException stating "Action 'invokeremotely' failed on element '{Unknown:mChart}'. ---> System.NullReferenceException: Object"."
Should i be passing a "System.Windows.Forms.Control" to GetAxisXTitle() or a "ChartFx.WinForms.Chart" ?
Thanks in advance!
Cheers,
Ricardo
i'm not getting it all here...
you say that the InvokeRemotely() method is to help in getting unserializable data from the process running the control.
In the end you say "Just be sure that the method is declared static and that all parameters as well as return values are serializable. "
This is a way to get unserializable data...
Please clarify me as we are having an issue with the ChartFx.AxisX property which is not serializable. We are using the procedure above to get the value as follows:
Code: Select all
Ranorex.Control chart = "pathToChart";
try
{
string axisXtitle = (string) chart.InvokeRemotely(GetAxisXTitle);
}
catch (Exception ex)
{
throw ex;
}
private static string GetAxisXTitle(System.Windows.Forms.Control control, object inputData)
{
ChartFX.WinForms.Chart chart = control as ChartFX.WinForms.Chart;
if(chart.AxisX != null)
{
return chart.AxisX.Title.ToString();
}
return string.Empty;
}
Should i be passing a "System.Windows.Forms.Control" to GetAxisXTitle() or a "ChartFx.WinForms.Chart" ?
Thanks in advance!
Cheers,
Ricardo
- Support Team
- Site Admin
- Posts: 12145
- Joined: Fri Jul 07, 2006 4:30 pm
- Location: Houston, Texas, USA
- Contact:
You can't get unserializable data directly, even with the InvokeRemotely method. However, using the InvokeRemotely method you can split up the unserializable data into chunks of serializable bits and return them to the automating process.rcd.guearra wrote:you say that the InvokeRemotely() method is to help in getting unserializable data from the process running the control.
In the end you say "Just be sure that the method is declared static and that all parameters as well as return values are serializable. "
I assume that in your GetAxisXTitle method the chart variable is null (did you pass the element corresponding to the right control?) and that's why a NullReferenceException is raised. Please make sure that the ControlType attribute of the chart variable (the one you assign the "pathToChart" path to) is "ChartFX.WinForms.Chart".
Regards,
Alex
Ranorex Support Team
-
- Posts: 29
- Joined: Tue Mar 03, 2009 11:43 pm
Well, it seems this exception is thrown inside the delegate. How can i debug the code inside the delegate method as it is being run in another process ? I tried attaching my application process and it crashes Ranorex...I assume that in your GetAxisXTitle method the chart variable is null (did you pass the element corresponding to the right control?) and that's why a NullReferenceException is raised.
The ControlType is correct.Please make sure that the ControlType attribute of the chart variable (the one you assign the "pathToChart" path to) is "ChartFX.WinForms.Chart".
I've also double-checked that the chart element is not null and it is the correct one, at the time the InvokeRemotely() method is being called.
Should i be passing a System.Windows.Forms.Control to the GetAxisXTitle() method or a Ranorex.Control ?
Thanks,
Ricardo
- Support Team
- Site Admin
- Posts: 12145
- Joined: Fri Jul 07, 2006 4:30 pm
- Location: Houston, Texas, USA
- Contact:
What do you mean by that? You should not be passing anything to the GetAxisXTitle method, you simply call chart.InvokeRemotely(GetAxisXTitle); where chart is a Ranorex.Control.rcd.guerra wrote:Should i be passing a System.Windows.Forms.Control to the GetAxisXTitle() method or a Ranorex.Control ?
You should be able to attach to the processing being automated using RanorexStudio or VisualStudio. What do you mean with "it crashes Ranorex"? Does RanorexStudio crash when you attach to your application?
Regards,
Alex
Ranorex Support Team
-
- Posts: 29
- Joined: Tue Mar 03, 2009 11:43 pm
Alex,
The first parameter is "System.Windows.Forms.Control control". Is this correct or should it be a "Ranorex.Control" ?
Thanks,
Ricardo
What i wanted to ask was if the GetAxisXTitle() signature was correct.You should not be passing anything to the GetAxisXTitle method, you simply call chart.InvokeRemotely(GetAxisXTitle); where chart is a Ranorex.Control.
The first parameter is "System.Windows.Forms.Control control". Is this correct or should it be a "Ranorex.Control" ?
In RanorexStudio, once i attach the process being automated an exception is thrown stating "JIT settings most likely bad configured".You should be able to attach to the processing being automated using RanorexStudio or VisualStudio. What do you mean with "it crashes Ranorex"? Does RanorexStudio crash when you attach to your application?
Thanks,
Ricardo
- Support Team
- Site Admin
- Posts: 12145
- Joined: Fri Jul 07, 2006 4:30 pm
- Location: Houston, Texas, USA
- Contact:
Hello rcd.querra,
I have tried your code above with the BubbleChart ChartFX7 Sample Application and it worked perfectly.
Maybe you use a wrong RxPath. The type in Ranorex Spy should be from ControlType "ChartFX.WinForms.Chart"
The signature of the GetAxisXTitle method is correct. The first parameter needs to be of type System.Windows.Forms.Control - if you had another type there, your code would not compile.
Regards,
Christian
Ranorex Support Team
I have tried your code above with the BubbleChart ChartFX7 Sample Application and it worked perfectly.
Maybe you use a wrong RxPath. The type in Ranorex Spy should be from ControlType "ChartFX.WinForms.Chart"
The signature of the GetAxisXTitle method is correct. The first parameter needs to be of type System.Windows.Forms.Control - if you had another type there, your code would not compile.
Regards,
Christian
Ranorex Support Team
-
- Posts: 29
- Joined: Tue Mar 03, 2009 11:43 pm
Its very strange, we tried in a clean solution and it works correctly. Thanks!
When we spy the element, its ControlType is the correct (ChartFX.WinForms.Chart) but in the Repository the element is a Ranorex.Unknown.
For calling the InvokeMethod() we need a Ranorex.Control. How can we convert a Ranorex.Unknown in a Ranorex.Control ?
By now we are getting a Ranorex.Control directly in the code through its RanoreXPath, which i think its not clean since we hold a repository.
Thanks in advance.
Feature request: show a repository item type in the Properties window or enable direct navigation to the source code.
When we spy the element, its ControlType is the correct (ChartFX.WinForms.Chart) but in the Repository the element is a Ranorex.Unknown.
For calling the InvokeMethod() we need a Ranorex.Control. How can we convert a Ranorex.Unknown in a Ranorex.Control ?
By now we are getting a Ranorex.Control directly in the code through its RanoreXPath, which i think its not clean since we hold a repository.
Thanks in advance.
Feature request: show a repository item type in the Properties window or enable direct navigation to the source code.
- Support Team
- Site Admin
- Posts: 12145
- Joined: Fri Jul 07, 2006 4:30 pm
- Location: Houston, Texas, USA
- Contact:
.NET User Controls will almost always have the role Ranorex.Unknown, unless it's derived from a standard Windows Forms control. However, every Windows Forms Control (including user controls) have the Control capability, so you can use the Ranorex.Control adapter on those elements.
There are several ways to get a Ranorex.Control adapter from another adapter like Unknown:
Currently, in the repository editor you see which adapter is created for the repository item by the icon next to it. I add a feature request that the adapter type should be shown in the property grid of the item.
Regards,
Alex
Ranorex Support Team
There are several ways to get a Ranorex.Control adapter from another adapter like Unknown:
Code: Select all
Unknown button = repo.MyApp.MyButton;
Control buttonControl = button.As<Control>();
// or
buttonControl = new Control(button);
Regards,
Alex
Ranorex Support Team