Paths

Paths are used to select an element from a hierarchical structure. The most well-known example is, obviously, the filesystem, but there are other tree-like structures there as well, for example windows (and their controls), menus (and their submenus) or the so-called "accessible objects" which build a tree usually parsed by a screenreader software to assist blind users to "see" what is on the screen. Although searching in paths does not depend on the kind of objects you want to traverse, there are different commands for traversing filesystem paths, window paths, or accessible object paths. One way to express paths, several different ways to use them.

Elements that can be accessed by paths (called nodes) share a common structure. Besides from the obvious (one) parent and (from zero to several) children, each Node has a default property (whose value is a string) and several named properties (whose name and value are both strings). While the property values may be any strings, the names may consist of letters, digits and underscores only. The names of the properties depend on the object kind; for example, a file in a filesystem may have (besides the default property which is most likely the file name) filesystem attributes, a file type, a size and a last modification date. There might be properties that have yes/no values, like whether a file is a directory. "True" is usually stored as 1, "False" either as 0 or as the empty string (the latter if the property is false in most cases to make printed representation of objects easier to read).

Path syntax

Paths consist of several parts, or components. These components are separated by pipe (|) characters. (Just like file paths are separated by backslashes. Backslashes are used quite a lot in the Windows operating system, so the path syntax tried to avoid using them for yet another thing.)

Paths have a "base point" (or a list of base points) where they originate. Every component gives a filter which child components to include (or whether to include the parent component). This description is checked for every base point of the path (which may each result in a list of result), ll the results are combined. This is like paths in filesystems work, if you look for C:\Sample*\*\*.txt you will find all text files which are in a folder whose parent is located directly on the C: drive and starts with Sample*. There might be a folder C:\Sample9\Documents which does not contain any text files; it will be included nevertheless in the intermediate result before checking the last component of the path; checking the last component will result in an emtpy result, therefore effectively removing the path.

Every component starts with a mask for the default property. A mask is just a string with some special characters in them (all characters except "*&|{}^" stand for themselves):

{Regex}
A regular expression. This part of the property value must match the given regular expression. Paired braces are allowed inside the regular expression if they nest properly.
*
A short form for {.*}, matching any text. Useful as a filter for the default property, if you want to match other properties only. Note that there is no shortcut for {.} (single character), unlike with filesystem paths where the question mark serves this purpose.
^char
Escape the character (one of "*&|{}^") and use it as literal. If the value has to contain a ^ for example, use ^^; for & use ^&.
{#from..to}
matches any (integral) number between from and to. Note that negative numbers are supported, and that this rule is greedy, i. e. the expression v{1..9}* will not match v90bis, as the number matches 90 here and 90 is larger than 9.

After the default property, other properties can be added in the form &name=pattern. name is literal here (no matching), for the pattern you can use the same characters like for the default property. Note that names will never contain equals signs or other special characters, so there is no need to escape anything here.

There are two special component forms that will only be recognized if they form the whole component (i. e. there are no other properties appended). One of them is .. which stands for the parent element (like in file paths). The other is ** which stands for a path of arbitrary length (0 or more) of arbitrary elements. If you want to find a file somewhere on your disc named sample.txt, you could use **|sample.txt. For filesystems this can be very slow, but for other, more limited trees (like menus or windows) this can be ideal. There is no need to use ** inside an expression (it is equivalent to *), but if you want to search a node that is named .., you can write ^.. instead.

A few other paths starting with a . have a special meaning as well; if you want to match a default property that starts with a dot, you can always escape the dot. A dot alone stands for the current element (analogous to . in the filesystem); you can add additional properties with an & as usual. An expression in the form .#number..number will select the specified range of elements of the current elements (ordered in the order they are currently parsed). You can sort element lists by a property by using a component like .!propname (or .!propname) for descending sorting; this can be used both for sorting a list before filtering it, as well as sorting the final list for path operations that return all results.

For most object types that can be selected, there is an Info command available (for example WindowInfo, AccObjInfo, FileInfo, ProcessInfo). Those commands expect a search result (for example, a window, a file a process) as their first parameter, and a property name as their second parameter. If the property name is the empty string, the default property is returned. If the property name is -1, all properties are returned.

You can combine multiple paths into one string by separating them with newlines. The result will contain all objects that are matched by at least one of the strings.

Window Paths

If you have ever programmed any low-level Windows program, HWND will be familiar to you. For all the others: Every object on the screen that is handled by the operating system (be it a menu bar, a button, a check box, an input box, a whole window or something completely different) is assigned a so-called "window handle" (and called a "window", even if it is just a button. "Real" windows are called "toplevel windows" because they have no window that contains them). These handles are used to both manipulate those objects (like check a checkbox) and to query their state – both from the program itself and from other programs like this macro recorder. Working with these handles can be cumbersome, as they are assigned each time the program starts. Each of these windows will also have a class name (assigned by the person who built the kind of control; for example all "standard" textboxes will have the classname "Edit" (assigned by someone from Microsoft), Winforms textboxes will have a classname like "WindowsForms10.EDIT.app", etc. Toplevel windows will either have a classname defined by the application, or by the framework used to build the application. As you can see, filtering on the classname is one of the most powerful filters. Therefore, the classname is the default property of a window. Other useful properties are "id" (which is unique only among sibling windows, but is fixed between executions, if IDs are set) for subwindows , or "process" (the filename of the process that created the window) for toplevel windows.

Here is a list of all supported properties:

title
Window title or text inside the window
x
X coordinate relative to parent window
y
Y coordinate relative to parent window
screenx
X coordinate relative to screen
screeny
Y coordinate relative to screen
w
window width
h
window height
r
right X coordinate relative to parent window
b
bottom Y coordinate relative to parent window
index
index of the window in the Z order, i. e. how many windows are lying above this window
handle
The (in)famous window handle, also valled HWND
invisible
1, if the window is not shown on screen
enabled
1, if the window accepts input, 0 if grayed out
relation
Only defined for toplevel windows. The relation of this window to the currently active window (one of "child", "current", "parent", "sibling"). Parent and sibling refer to ownership here, not to the window tree. (If a parent owns a dialog, the dialog will always stay on top of the parent and the parent cannot be focused until the dialog is closed).
process
uppercase filename of the process that created the window
processid
internal (numeric) ID of the process that created the window, as seen in Task Manager (PID)
topmost
1, if the window is topmost ("always on top")
movable
1, if the window can be moved with the mouse, 0 otherwise
resizable
1, if the window can be resized, 0 if it has a static size
state
minimized, maximized or normal
checkstate
Used for checkboxes. Can be yes, maybe or no
shortcontent
What is written inside the window
longcontent
Everything that is written inside the window. This will also include the list part of a dropdown list, for example.
id
the id of this element among its siblings (defined by the application programmer)
mdi
1, if the window is a Multiple Document Interface window
parenthandle
HWND of the parent window

These properties can not only be used in window paths, but also be queried by the WindowInfo command.

Accessible Object Paths

Accessible Objects are objects seen by a screen reader. Every window (or control) consists of multiple accessible objects, representing a variety of different "logical" objects - from scrollbars to menus and list items. These items can be enumerated like windows, and can contain child items (a menu can contain items, for example), so they are represented by paths as well. Every accessible object is assigned to a "window" and a child ID; the child ID is used to distinguish multiple objects from the same window.

Default property is the role of the object, which is one of the following list: Default, None, TitleBar, MenuBar, ScrollBar, Grip, Sound, Cursor, Caret, Alert, Window, Client, MenuPopup, MenuItem, ToolTip, Application, Document, Pane, Chart, Dialog, Border, Grouping, Separator, ToolBar, StatusBar, Table, ColumnHeader, RowHeader, Column, Row, Cell, Link, HelpBalloon, Character, List, ListItem, Outline, OutlineItem, PageTab, PropertyPage, Indicator, Graphic, StaticText, Text, PushButton, CheckButton, RadioButton, ComboBox, DropList, ProgressBar, Dial, HotkeyField, Slider, SpinButton, Diagram, Animation, Equation, ButtonDropDown, ButtonMenu, ButtonDropDownGrid, WhiteSpace, PageTabList, Clock, SplitButton, IpAddress, OutlineButton

Supported properties:

ChildID
The Child ID.
DefaultAction
Name of the default action.
Description
Description of the element.
KeyboardShortcut
Keyboard shortcut
X
X coordinate on screen
Y
Y coordinate on screen
W
width
H
height
R
right X coordinate
B
bottom Y coordinate
Name
Name of the item
Role
Role (like the default property)
RoleIndex
Numeric role value
RoleString
String value of role, localized
State
State flags, numeric
StateString
State flags, localized string
Value
Value
Visible
1 if visible, 0 otherwise
Window
window handle

Filesystem paths

TODO.

Process paths

TODO.