Introduction
Major Concepts
Window Object Location
Each Win32 object is located using the combination of the following parameters:
- Window class - identifies internal window class
- Caption - corresponds to internal window text which is usually window caption
- Index - corresponds to the number of element which goes in the sequence
Window Hierarchy Organization
Additional Features
Locator Attributes
When we operate with window objects containing multiple fields representing some controls it’s inconvenient to declare the fields and then initialize them separately while it can be done implicitly. E.g. the following code describes some window with fields and their initialization inside the constructor:
- Java Sample
| public class NotepadWindow extends MainWindow {
public OpenDialog openDialog;
SaveMessageDialog dSave;
public Edit edtText;
/**
* @param client
* @param locator
*/
public NotepadWindow(Win32Client client, Win32Locator locator) {
super(client, locator);
openDialog = new OpenDialog(client, this, new Win32Locator("#32770(.*)",0));
dSave = new SaveMessageDialog(client, this, new Win32Locator("#32770(.*)",0));
edtText = new Edit(this,new Win32Locator("Edit",0));
}
}
|
Some of the lines and entries look redundant. E.g. in the above code we explicitly define this as the reference to parent window however it should be meant by default as we define some controls as the fields of this class. So, obviously, the window object instance should be the instance of the current class.
And generally, it looks like duplicating effort declaring the objects and then initialize them explicitly inside the constructor.
In order to minimize the writing effort for window declarations there was introduced the feature of locator attributes. It means that we declare fields and assign them annotations/attributes (whatever they’re called in programming language in use) and these fields will be initialized automatically as soon as the holding class instance is initialized.
In Java the above code looks like:
| public class NotepadWindow extends MainWindow {
@Locator(winClass="#32770(.*)",index=0)
public OpenDialog openDialog;
@Locator(winClass="#32770(.*)",index=0)
public SaveMessageDialog dSave;
@Locator(winClass="Edit",index=0)
public Edit edtText;
/**
* @param client
* @param locator
*/
public NotepadWindow(Win32Client client, Win32Locator locator) {
super(client, locator);
}
}
|
As it’s seen the window object definition became more compact.
Window Object Aliases
In some cases there’s a need to get the control disregard it’s location and position in the entire window hierarchy. E.g. we reserved some global name to some specific button and we want to get this object only by given name instead of typing all the window hierarchy for that. It can be typical case when we operate with Keyword-Driven or BDD scenarios when we cannot pass the actual object in the text instructions. But we always can reference them by specific name.
That’s the main purpose for Aliases object and Alias annotation in particular.
How it is used? Alias is another annotation/attribute which can be applied to field representing some control or child window in window declarations. All those objects are recorded into global structure which return actual window object just by specifying the alias name.
Declaration example:
- Java
| public class NotepadWindow extends MainWindow {
@Alias(name="Open Dialog")
@Locator(winClass="#32770(.*)",index=0)
public OpenDialog openDialog;
@Alias(name="Save Message Dialog")
@Locator(winClass="#32770(.*)",index=0)
public SaveMessageDialog dSave;
@Alias(name="Edit Area")
@Locator(winClass="Edit",index=0)
public Edit edtText;
/**
* @param client
* @param locator
*/
public NotepadWindow(Win32Client client, Win32Locator locator) {
super(client, locator);
}
}
|
Once we have aliases declared we can use them like the following:
| Win32Client client = new Win32Client();
NotepadWindow notepad = new NotepadWindow(client,new Win32Locator("Notepad","(.*) - (.*)",0));
...
OpenDialog dialog = (OpenDialog)Aliases.get("Open Dialog");
|
Main feature is that the code in line 4 from the above example may be even invoked in absolutely different module from the code called in first 2 lines.
In order to force aliases initialization you must create at least one window object instance. Only initialized window aliases will be stored in the memory.