WindowInfo plugin for Take Command / TCC / TCC/LE

beta version 0.95.3     2025-03-26

Charles Dye

Purpose:

This plugin adds a few new functions to find windows and return information about them. I also include one new command to list windows using a user-defined format string.

Installation:

To use this plugin, copy WindowInfo.dll and WindowInfo.chm to some known location on your hard drive. (If you are still using the 32-bit version of Take Command, take WindowInfo-x86.dll instead of WindowInfo.dll.) Load the .DLL file with a PLUGIN /L command, for example:

plugin /l c:\bin\tcmd\test\windowinfo.dll

If you copy these files to a subdirectory named PlugIns within your Take Command program directory, the plugin will be loaded automatically when TCC starts.

Plugin Features:

New Commands:
LISTWINDOWS
New Functions:
@HWNDPID@PIDHWND@PIDHWNDS@TITLEHWND@WINALPHA
@WINMONITOR@WINOWNER@WINPARENT@WINSNAPPED@WINSTYLES
@WINSTYLESEX@WINVDESK

Syntax Note:

The syntax definitions in the following text use these conventions for clarity:

BOLD CODEindicates text which must be typed exactly as shown.
CODEindicates optional text, which may be typed as shown or omitted.
Bold italicnames a required argument; a value must be supplied.
Regular italicnames an optional argument.
ellipsis…after an argument means that more than one may be given.

Examples are shown in a gray box:

rem   This is an example:
listwindows /c:*console*


Some command options take an argument. These are shown with a colon between the option and its argument: /A:arg

If you like, you may substitute an equals sign for the colon: /A=arg This is handy if the arg is a filename, and you want to use tab completion to enter the filename.

Or you can omit the colon: /Aarg

New Commands:

LISTWINDOWS — List windows, using a user-defined format string.

Syntax:
LISTWINDOWS /C:class /E:prog /F:"fmt" /I /L:n /O:flags /P /R /T:title /V /W:win

/C:classfilter top-level windows by class name (supports wildcards)
/E:proglist windows created by the specified program (name or PID)
/F:"fmt"format string
/Iinvisible windows only
/L:nline length
/O:flagssort windows
/Ppage output
/Rlist child windows recursively
/T:classfilter top-level windows by title (supports wildcards)
/Vvisible windows only
/W:winlist child windows of the specified window (title or handle)

With /E:prog, this command lists all top-level windows created by the specified program. With /W:win, this command lists all child windows of the specified window. With neither /E: nor /W:, it lists all top-level windows.

If no /F:"fmt" is given, the default format string is "$08h:  $v  $-25c  \u201c$t\u201d" to list each window’s handle, visibility, class name, and title.


/E:prog lists windows created by a specific program. The prog may be either a process ID or a filename. If it’s a process ID, you can enter it in decimal, or hexadecimal with a leading 0x. Only windows created by that one specific process will be listed.

If it’s a filename, it much match exactly (no wildcards). You can enter either a base name (e.g. /E:tcc.exe ) or a complete pathname (e.g. /E:c:\bin\tcmd34\tcc.exe ). This syntax can match multiple processes — you might have multiple copies of the same program running at once. If you try to combine a process ID with a filename, the process ID wins; the filename will be ignored.


/O: can sort by several criteria. The available sort keys are:

Csort by window class
Psort by process ID
Rsort by thread ID
Ssort by styles word
Tsort by title
Vsort by visibility
Wsort by window handle
Xsort by extended styles word
-reverses the following key

These can be combined, e.g. /O:CT to sort by window class name first, then by title where two windows have the same class. If you do not give any /O:flags, the default is to sort by window handles. To disable sorting altogether, you can use /OU.

Format String:

These are the tokens supported in the format string:

Token:Gives:
$cthe window’s class name
$hthe window handle
$pthe window owner’s pid
$sthe window’s styles word
$tthe window’s title
$vV for visible or I for not visible
$xthe window’s extended styles word
$Hthe window’s height
$Nthe name of the program which created the window
$Othe handle of the window’s owner window
$Pthe handle of the window’s parent window
$Vthe name of the window’s virtual desktop, if available
$Wthe window’s width
$Xthe window’s left edge
$Ythe window’s top edge
$$dollar sign

You can use modifiers between the dollar sign and the letter to change how the value is displayed:

Modifier:Changes the value:
-left-aligns a field
0zero-pads a numeric field
#uses decimal instead of hex
!forces uppercase
,forces lowercase
widthset the field’s width (decimal only)

A few character escapes are also supported:

Escape:Gives:
\eASCII escape
\kbackquote
\nnewline
\ppercent sign
\qdouble quote
\rcarriage return
\ttab
\\backslash
\unnnnUnicode character, up to U+FFFF
\UnnnnnnUnicode character, up to U+10FFFF


New Functions:

@HWNDPID — Returns the process ID of the process which created a given window.

Syntax:
%@HWNDPID[hwnd,flags]

hwndthe window’s handle; decimal or hex with a leading 0x
flagsbitmapped:
    1: return process ID in hexadecimal

This function only takes a window handle, not a title. It’s basically a wrapper around the Windows GetWindowThreadProcessId() function.

If the specified window does not exist, or on any other error, this function returns 0.



@PIDHWND — Searches for a window created by the specified process, and returns its handle.

Syntax:
%@PIDHWND[program,flags]

programprogram name or process ID; wildcards are supported
flagsbitmapped:
    1: return handle in hexadecimal

You can specify the program as:


@PIDHWND returns the window handle (HWND) of a matching window. If no matching window is found, @PIDHWND returns 0.

Note that a process may have no windows, one window, or many windows. The window that @PIDHWND chooses may not necessarily be the same one that you would pick. To get a list of all top-level windows created by a process, use @PIDHWNDS.



@PIDHWNDS — Returns a list of windows created by the specified process.

Syntax:
%@PIDHWNDS[program,flags]

programprogram name or process ID; wildcards are supported
flagsbitmapped:
    1: return handles in hexadecimal
    128: sort the list into ascending order

You can specify the program as:

Window handles will be returned as a space-separated list of decimal or hexadecimal numbers.

If no matching process is found, or if no windows belong to that process, then @PIDHWNDS will return an empty string.



@TITLEHWND — Searches for a window with a matching title, and returns its handle.

Syntax:
%@TITLEHWND[title,flags]

titlewildcards are supported
flagsbitmapped:
    1: return handle in hexadecimal

@TITLEHWND returns the window handle (HWND) of a matching window. If no matching window is found, @TITLEHWND returns 0.



@WINALPHA — Searches for a matching window, and returns its alpha transparency.

Syntax:
%@WINALPHA[window,flags]

windowwindow title, program name, PID, or HWND
flagsbitmapped:
    1: return alpha value in hexadecimal

The return value ranges from 0 (completely transparent; invisible) to 255 (completely opaque). If the window is not using alpha transparency, the return value is 255. If no matching window is found, @WINALPHA will return 00.



@WINMONITOR — Searches for a matching window, and returns the monitor on which it appears.

Syntax:
%@WINMONITOR[window,flags]

windowwindow title, program name, PID, or HWND
flagsbitmapped:
    1: return a monitor name; otherwise it’s a monitor number

@WINMONITOR returns a monitor index: 1 for the first monitor, 2 for the second, and so on. If no matching window was found, or if the window does not overlap any display monitor, @WINMONITOR returns 0.



@WINOWNER — Searches for a window, and returns its owner window’s handle.

Syntax:
%@WINOWNER[window,flags]

windowwindow title, program name, PID, or HWND
flagsbitmapped:
    1: return window handle in hexadecimal

If no matching window is found, the return value will be 0.

See also: @WINPARENT.



@WINPARENT — Searches for a window, and returns its parent window’s handle.

Syntax:
%@WINPARENT[window,flags]

windowwindow title, program name, PID, or HWND
flagsbitmapped:
    1: return window handle in hexadecimal

If no matching window is found, the return value will be 0.

See also: @WINOWNER.



@WINSNAPPED — Tests whether a window has been “snapped” to the edge.

Syntax:
%@WINSNAPPED[window,flags]


windowwindow title, program name, PID, or HWND
flags(not used in this version)

@WINSNAPPED returns nonzero if the window is snapped, 0 if it is not.

Window snapping is supported in Windows 10 and later. Under earlier versions of Windows, @WINSNAPPED will always return 0. If no matching window is found, the return value is also 0.

@WINSNAPPED gives you access to the Windows IsWindowArranged() function.



@WINSTYLES — Searches for a window, and returns its style bits.

Syntax:
%@WINSTYLES[window,flags]

windowwindow title, program name, PID, or HWND
flagsbitmapped:
    1: return styles value in hexadecimal

Window styles are documented here. Note that some only apply to child windows (e.g. controls such as buttons). Others specify initial conditions for when the window was created, not the current state of the window.

If no matching window is found, the return value will be 0.

See also: @WINSTYLESEX.



@WINSTYLESEX — Searches for a window, and returns its extended style bits.

Syntax:
%@WINSTYLESEX[window,flags]

windowwindow title, program name, PID, or HWND
flagsbitmapped:
    1: return extended styles value in hexadecimal

Extended window styles are documented here.

If no matching window is found, the return value will be 0.

See also: @WINSTYLES.



@WINVDESK — Searches for a matching window, and returns the virtual desktop on which it appears.

Syntax:
%@WINVDESK[window,flags]

windowwindow title, program name, PID, or HWND
flagsbitmapped:
    1: return a GUID; otherwise it’s the virtual desktop’s name

Virtual Desktops require at least Windows 10. Under earlier versions of Windows, @WINVDESK will always return 0.



Windows Searches:

Most of the functions in this plugin have a window argument to search for a window. You can specify the window in a number of ways. If you want to match against titles, quote this parameter. If you want to match against program names, do not quote it.

•  Search for a matching window title:"*VISUAL*"
•  Search for a filename with an extension:NOTEPAD.EXE
•  Search for a base name:NOTEPAD (.* is assumed)
•  Search for a fully-qualified filename:C:\WINDOWS\SYSTEM32\NOTEPAD.EXE
•  Search for a process ID in decimal:=5892
•  Search for a process ID in hexadecimal:=0x1704
•  Pass a window handle:HWND==0x002D0B12 (NB: two equals signs)
•  Use TCC’s own display window:**ME**
•  Use the current foreground window:**FG**

The first four support wildcards.


When you search by titles, the function will temporarily set TCC’s console window title to an empty string. This step prevents accidental wildcard matches against the console window, Take Command’s window, or the Windows Terminal window.

Startup Message:

This plugin displays an informational line when it initializes. The message will be suppressed in transient or pipe shells. You can disable it for all shells by defining an environment variable named NOLOADMSG, for example:

set /e /u noloadmsg=1

Status and Licensing:

Consider this beta software. It may well have issues. Try it at your own risk. If you find a problem, you can report it in the JP Software support forum.

WindowInfo is currently licensed only for testing purposes. I may make binaries and source code available under some free license once I consider it ready for use.

Download:

You can download the current version of this plugin from https://charlesdye.net/dl/windowinfo.zip.