When creating some recipes, you may need to find a specific window to operate on it. This how-to explains how.
Many of the commands available for use in recipes accept a
/Window
parameter, which lets you locate a specific window.
To use it, you will have to know a few things about how windows (and programs in general) works on Windows.
There are three pieces of information available for determining if a window is the window you are looking for: process name, window class and window title.
A process is a single instance of a program. The process name is the name of the executable (e.g. the .exe file) without the .exe extension.
A window has a title and a class. The window title is the part you can see in the title bar of the window. The window class is a value that is normally hidden from everyone but programmers, but is a value that would typically be shared across multiple windows from the same program. The developer of the program decides what the window class is.
Window classes
When a program in Windows wants to show a window, it first needs to register a window class. The developer gives their window class a name, which sets some properties of the windows that are created using that window class. They can create multiple windows from a single window class, which is typically what is done in MDI programs, where each document is opened in a new window (like in Microsoft Word).
If you want a tool to find the window class of a window, Spy++, which ships with Visual Studio, is the tool we use ourselves.
In most cases it makes sense to compose your recipes relying on the process name and window title, and ignoring the window class. There are specific cases where the window class is required.
Searching for windows
When you want to locate a window, you can provide a search string for each of these 3 properties. In the user interface, for the move window command, it looks like this:
The user interface does a good job of separating the 3 parts you are searching for, so you can learn what exactly
is matched. In this case, we've chosen to both limit matched windows to any Notepad processes, and any window that
ends in - Notepad
(which is a pattern all Notepad windows follow in English versions of Windows).
The *
character is a wildcard, meaning it will match anything.
This query is quite broad, in that it finds all currently open Notepad windows, and in some cases you may want that.
However, you may also want to be more strict and e.g. use mylogfile.txt - Notepad
as the window title.
From the command line
If you were to invoke the previous command from the command line, MaxTo has its own query format for window queries, as we call them. Here is an overview of the syntax where all the parts have been specified:
\MSPaint\MSPaintApp\* - Paint
Part | Description | Value |
---|---|---|
Process name | The name of the process executable (without the .exe ending). | MSPaint |
Window class | The window class of the window. | MSPaintApp |
Window title | The window title, as seen in the title bar or the taskbar. | * - Paint |
Notice that you can look at this as a path into a strange filesystem, where the folders are organized hierarchically by process name, window class and then window title.
Wildcards and regular expressions
MaxTo supports both wildcards and regular expressions when dealing with window queries. In most cases you will want to stick to using wildcards, as they are easier to read. However, regular expressions provide some specificity, in that you can exclude windows based on stricter patterns.
We'll use Visual Studio Code as an example. As I am editing the file for the contents of this page, its title bar
reads:
● find-window.svelte - maxto-docs [WSL: Ubuntu] - Visual Studio Code
. That
is quite the complex title bar. Notice the dot at beginning, which indicates that I have unsaved changes in the file,
and the WSL part, which indicates that it is connected to a remote WSL environment.
So if I wanted to find a Visual Studio Code window that was not using a remote environment, it would be impossible to do using simply wildcards. It is possible to find windows that are using remote environments, that would look like this:
\VSCode\\* - * [*] - Visual Studio Code
If you wanted to find windows not using a remote environment, the regular expression we need to use is
^(● )?(.+?) - ([^[]+?) - Visual Studio Code$
This regular expression is quite complex, and while we consider teaching regular expressions to be outside of the scope of MaxTo's manual, here is a quick overview of what this regular expression does:
The
^
and$
at the start and end of the expression ensures that the expression matches the entire window title.(• )?
matches both if there are saved and unsaved changes.(.+?)
matches the file name.([^[]+?)
matches the project name, but excludes anything in brackets (the remote environment).
Learning regular expressions
Regular expressions are powerful, but can take a bit of time to become proficient at. Here are some resources that I've found helpful:
regular-expressions.info and their tool RegexBuddy (Windows program), which I've used extensively over the years.
RegExr is a online tool to help you write and test regular expressions.
regular expressions 101 is another online tool to write and test regular expressions.
Note that MaxTo supports C#/.NET's regular expression syntax, which only RegexBuddy supports at the time of writing. Most regular expression syntaxes are very similar, and in practice you should be able to use whichever tool above you feel comfortable with.