View on GitHub

Sirius

Sirius Win32 Client Interaction

Download this project as a .zip file Download this project as a tar.gz file

Introduction

Major Concepts

Window Object Location

Each Win32 object is located using the combination of the following parameters:

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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
	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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
	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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
	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:

1
2
3
4
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.