BX User's Guide
Doug Lee
Last Revised November, 2023

Welcome to BX, the JAWS toolbox! For installation instructions and a download link, go to the Script Installation Instructions section. For news on updates, go to the Revision History section.

Copyright (c) 2003-2023 Doug Lee.

All rights reserved.

Redistribution and use in binary form is permitted provided that the following conditions are met:

Except via specific prior written permission, distribution, acquisition, or discovery of source code, such as by reverse engineering or decompiling, is not permitted.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Table of Contents

What Is BX?

BX is a very comprehensive navigation and testing tool. It will allow you to test many JAWS scripting functions without writing scripts. Using BX, you will be able to use single keystrokes to get the results of most any function in each of the following categories:

Summary of BX features by category
Category Description
Window Functions
  • Go to first, last, parent, child, next, previous, current, focus, real, foreground, top-level, or other windows directly.
  • Get a window's class, name, control ID, display style, dimensions and location, contents, etc.
  • Move directly from a window to various other exploration environments attainable from it, such as its SDM elements, MSAA or UIA object tree, AccessibleObject tree, or screen rectangle.
SDM Window Functions
  • Move to first, last, next, previous, current, or focused SDM control and test all functions you might use to present the control to the user.
MSAA Navigation
  • Navigate among MSAA objects by all standard MSAA methods (spatial, logical, hierarchical, or to focus or selection) and query all properties of each object (name, role, state, value, etc.). (This is done by direct manipulation of MSAA COM objects.)
UIA support testing
  • Exercise the features of the UIAScriptAPI introduced publicly in JAWS 15 but also available (though with more limited and slightly different functionality) in JAWS 14.
  • Explore UIA trees, filter their content, collect UIA elements matching specific criteria, examine all available properties, list available UIA patterns for an element and test related properties and methods, and move among related UIA elements, MSAA elements, window handles, and screen rectangles.
  • Capture any of up to about 200 events on a UIA element or tree and analyze them via an XML structure that can also be examined in BX.
AccessibleObject tree testing
  • Test navigation and properties in an AccessibleObject tree obtained from a window handle.
Internet Explorer HTML testing
  • In Internet Explorer, navigate an HTML document's tree of elements, query for attributes, fire events by name on specific elements, retrieve HTML source code blocks by element for display or copying, and edit live DOM elements or trees by hand in place and test the results.
XML testing and navigation
  • In any browser supported by JAWS, obtain and navigate a web page's FSXML view as provided by JAWS 17 and later.
  • Explore XML views of AccessibleObject trees built from MSAA or UIA, and an XML view of JAWS' Off-Screen Model (OSM).
  • Explore an arbitrary XML file by loading it into BX for examination.
  • Explore events captured from UIA.
Cursor-Sensitive Functions
  • Use any standard JAWS navigation or cursor-changing/routing command, plus a few for moving by other units such as text chunks; and test cursor-sensitive functions such as GetGroupBoxName, GetTreeViewLevel, GetControlAttributes, etc.
JAWS Object Functions
  • Navigate with cursors as above and test functions like GetObjectName/Type/Value.
  • Navigate and examine the JAWS internal object information hierarchy by level.
  • Initiate MSAA or UIA refresh to test when these might be necessary.
Pixel navigation
  • Move one screen pixel at a time, or search for color changes, detect color patterns on screen, etc., using the JAWS or invisible cursor.
Java and Nav Module Functions
  • Test JAWS functions for dealing directly with Java controls, including the Nav Module system functions introduced in JAWS 5.0.
Global (non-location-specific) Functions
  • Test functions such as GetMenuMode and DialogActive which don't relate to a location.
  • Check JAWS or Windows version and obtain detailed version information about the application in focus.
  • Update the scripts for the application in focus without running a script installer, or update BX itself.
Braille support functions
  • Test functions related to JAWS' support of Braille displays and the JAWS Braille Viewer application.
COM Object Functions
  • Find out if any of the JAWS functions returning COM object interfaces work from the current cursor location.
  • Explore the properties and methods of specific COM objects obtained from other BX functions or directly by instantiation from an edit box.
Report generation
  • Generate a list of keystrokes scripted for the active application along with their descriptions.

Additionally, you will be able to do all of the following:

Finally, power users may customize the BX interface or add commands by editing a .ini-style file and using a BX-specific syntax that permits scripts and functions to be called directly from a text file without the need to compile new code.

System Requirements

BX works with JAWS versions 15.0 and up. BX may contain features that only work in newer versions of JAWS. These features will fail under older versions of JAWS, but this will not prevent BX from performing properly otherwise. In other words, BX will do its best to adapt to what it can find and will do as much as it can.

Script Installation Instructions

To install BX on a new system:

  1. Load JAWS if this has not already been done. This will require administrative privileges on the computer.
  2. Run JAWS as the user for whom the scripts are to be installed. This and the following steps must be performed for each user of the computer who will be using JAWS with these scripts.
  3. Download and run, or run directly, the installer for these scripts; and follow the on-screen directions. Be sure to install the scripts in the currently running JAWS version if a JAWS version list is presented.

BX Usage Overview

BX is activated, and also deactivated, by typing Insert+Space or JAWSKey+Space twice in a row. BX will announce its state when turned on or off in this manner, e.g., by saying "BX on."

Note that before April, 2020, it was possible to use the JAWS "Script Utility Mode" commands to turn BX on or off. This is no longer the case, and the Script Utility Mode works entirely as determined by JAWS itself.

In JAWS' script utility mode, you have a location, defined by a window handle, and a set of possible commands. The possible keystrokes never change, but their output does: You can cycle through output modes with F3 and through attribute search types with F4 and thus change the effects of other commands.

BX extends these concepts significantly. In BX, a "location" is simply a sufficient set of information to define where you are. Your current location could be a window (as in script utility mode), an SDM control, an MSAA object, a cursor position, etc. Naturally, each different type of location has associated with it a unique set of possible commands, corresponding to the things you can do there. When in a window, you might want its class; when on an SDM control, you might want to hear the result of calling SDMSayControl; and when examining an MSAA object, you might want to hear its name and role. You might even want to combine various means of navigation to achieve one goal, such as by finding a list box by navigating the window tree, then getting that window's MSAA client object (which will be a Role_System_List object), and finally using arrows to read all the list items whether or not they are shown on screen.

Because there are a number of different location types in BX (window, MSAA object, etc.), each with its own unique requirements and capabilities, there will be different commands available depending on where you are. The set of keystrokes available for a specific location type in BX is called a map. Whenever possible, commands are uniform across maps: To move to the first, last, previous, or next location from the current one in any mode, use Home, End, Up, and Down, respectively (except when using screen coordinates as locations, at which time all normal JAWS movement commands will work as expected). Commands for which uniformity is impossible or unreasonable tend to have mnemonic key assignments: C for window class, I for control ID, etc. Finally, some conventions apply for grouping commands. For instance, commands that jump to a new location by means other than relative movement are activated with keys involving the Ctrl key. Thus, when navigating among windows, Ctrl+F will jump to the window in focus, and Ctrl+R will jump to the "real" window (the first window above the current one with a title). Say commands and commands that affect the environment, such as by changing focus, tend to involve the Alt key; thus, during Window Navigation, Alt+T is SayWindowTypeAndText and Alt+F is SetFocus.

In summary then, BX is simply a system which gives you the ability to navigate among locations and between types of locations and to test numerous JAWS scripting functions pertinent to each type of location. As such, it is of primary and considerable use to scripters; however, it is also very helpful as an instructional tool for those wishing to learn how to write scripts, and it can sometimes be used as a very effective means of handling application accessibility problems on the fly--for example, setting focus to an otherwise unreachable control, monitoring the progress of a long operation by parking on an MSAA progress control and pressing V periodically to check the position of the gauge, etc.

A Quick-Start Guide

There are several help facilities in BX which will be explained shortly. It is not necessary to memorize a lot of commands right away; you can find them all interactively. However, before presenting the help system, this section will do a little to explain common BX usage.

The most frequent type of BX usage involves turning BX on, choosing the map you want (for example, Apostrophe W for Window Navigation or Apostrophe M for MSAA Navigation), setting a starting point (for example, Ctrl+F to move to the current location of focus), and starting to navigate and test functions and properties. An example: To find the name of the current window and the class of the top-level window above it in the window tree, you could do the following:

  1. Turn BX on.
  2. Choose the Window Navigation map (if not already active) by typing an apostrophe (which will say "Map") and a w (which will say "Window Navigation").
  3. Type a Ctrl+F to jump to the window with focus.
  4. Type an "n" to get the name of that window. This will answer the first of our two questions.
  5. Type Ctrl+T to jump to the top-level window above the current one.
  6. Type C to get the class of this window.

Here is a list of basic commands that should help you figure out the rest of them. These commands work in all maps except where noted. A few commands, shown at the end of this list, are not really related to the help system but are helpful in just about any map sometimes.

Summary of basic BX commands available in all maps
Keystroke Description
JAWSKey+1 (normal JAWS Keyboard Help command) Activates a mode in which you can type any key to get JAWS to announce its function at the current location.
Space The Describe-Next-Key function: Press just before pressing another key or key combination to hear its function without having to enter help mode first.
JAWSKey+H Display in the JAWS virtual buffer a list of commands available at the current location. F1 and JAWSKey+F1 also do this.
Tab, Shift+Tab, and Enter Move among and execute, respectively, the commands available at the current location.
Ctrl+Tab and Ctrl+Shift+Tab Jump to the first or last command available at the current location.
Apostrophe (') Switch to another key map. This key actually puts you into a map whose purpose is to choose a map though, so the above help facilities work here to help you find a map to use.
JAWSKey+T The Where-Am-I function: Announce the current map name and location.
Period (.) The Context key (not available in all maps): In maps supporting it, goes to a context map for the current location. This is, for example, a way to get the MSAA Window or Client object from a window handle.
/ Find or Search: In maps supporting this feature, moves to a map of commands for searching and reviewing search results related to the original map. For example, typing / from the UIA Navigation map reaches a "UIA Find" map for performing UIAScriptAPI searches, whereas typing / from an XML map reaches a map for performing XPath queries on an XML tree.
; In maps supporting this feature, cycles among related maps for the current type of location. For example, ; cycles among Cursor Navigation, Pixel Navigation, and other related maps that address physical screen locations.
Alt+Shift+Up and Alt+Shift+Down BX history navigation: Move backward and forward among locations already visited, via any map, in visitation order.
M The BX Mark system: This goes to a small map used for setting, clearing, and jumping to marks. A "mark" is a location (a window, an MSAA object, an HTML object, etc.).
Windows with a letter A shortcut for jumping to a specific mark. For example, if you created mark A earlier, Windows+A will return to it. Jumping to a mark will also return you to the map you were in when you created that mark.
Alt+E Brings up an edit box in which you can type a JAWS function call with parameters and press Enter to run it immediately. Nested function calls will not work.
JAWSKey+C Cycle through available cursors. Useful in maps where the normal PC and JAWS cursor commands are not available.
" Object type name: Press once to hear the name of the current object's type, assuming the current location involves an object, and twice to hear its interface name. This is an advanced feature and may require TLBInf32.dll to be registered.
Alt+O Object overview: Brings up a virtual buffer describing the interface to the current object, assuming the current location involves an object. This is another advanced feature requiring TLBInf32.dll.
Esc Exit a nested key map if one is active, returning to the one active before it was loaded. This is a way out if, for example, you hit an apostrophe (map switch) by mistake and don't really wish to switch maps.
Alt+C Starts and stops text collection. Type once to start text collection, then use one or more BX commands that produce collectable output (most output is collectable, but the output of Say commands, such as SayWindowTypeAndText is not). Finally, type this command a second time to place all collected output in the virtual buffer for viewing, copying to clipboard, etc.
Alt+M Cycle through the three possible MSAA modes available in JAWS. The first press of this command simply announces the current mode; subsequent presses (without other intervening commands) will cycle through the remaining modes. The MSAA mode can have an effect on the output of numerous JAWS commands, notably commands like GetObjectName, GetObjectValue, etc.

The BX Quick Key

A more recent feature of BX is the so-called "BX Quick Key," sometimes also written as "QuickKey" (without the space). This is a key that provides access to a miscellaneous set of functions without requiring BX itself to be activated first with JAWSKey+Space. By default, the Quick Key is not set up; but it can be set up simply by adding a QuickKey assignment to bx_user.cnf in the JAWS user folder. The BX author prefers to assign the right bracket key (]) key as the BX Quick Key.

To assign a quick key:

  1. Enter BX and go to the BX Configuration map (Apostrophe Ctrl+B).
  2. Type J to load bx_user.cnf into Notepad. If it does not exist, let Notepad create it.
  3. Add a line saying, for example, "QuickKey=]" (without the quotes) to the [BX Options] section. If the section does not exist, add that section header as well:
    [BX Options]
    QuickKey=]
    Replace "]" with the key you wish to use as a quick key.
  4. Save the file, then restart JAWS once or reload all scripts and configurations with Ctrl+Insert+Esc.

Once the key is functioning, tapping it will cause JAWS to say "BX" and wait for another key. The Tab and other help facilities work here just as in BX itself to help you find commands and features of interest.

As of this writing, the built-in Quick Key functions fall into the following categories:

Task switching
Commands to speed jumping among running tasks when many are open at once. This system is designed to be somewhat similar to that used by the "Screen" utility found on some systems running Linux and similar text-based operating systems.
Text management
Commands for cutting, copying, pasting, and combining text blocks and holding blocks of text in up to 26 buffers named by single letters. This system was inspired by the buffer system in the "Vi" text editor found under Linux and other similar operating systems.
Reports
A command for getting to a collection of reports that BX can generate.
Test Functions
A command for running any of 27 different functions you can write for testing scripts etc. without requiring you to assign keys to them in a jkm file. This approach also has the advantage of keeping test code out of the way of script end users, as these test functions do not appear in lists of available scripts for users to run.
App-specific functions
Two commands for running functions related to specific applications: one that brings you to a list of applications with such functions available, and one that lets you run functions related to the currently active application if any exist.
Call logging functions
Commands for tracing/logging function calls, events, etc., in JAWS scripting.
Script updating functions
Commands for updating BX itself and updating the running scripts for the focused application, if such updates are available from the BX author.
Miscellaneous functions
Functionality that does not clearly fall into any other of the above categories.

Warning: The Quick Key functionality itself is stable, but the specific available commands and their current layout are subject to change. The text management commands in particular could use rethinking.

Task Management Features

The BX Quick Key command set includes the following commands for managing tasks:

W
List available tasks. The W keystroke comes from the Screen utility mentioned in the previous section.
Numbers from the number row
Switch to a task by its number. Digits 1 through 9 and 0 switch to tasks numbered 1 through 10. With Shift, these keys switch to tasks 11 through 20. With Ctrl, they switch to tasks 21 through 30, and with Ctrl+Shift, tasks 31 through 40. Note that while most Windows applications work well with the BX task switching methods, a few may not. Also, though the intention is for the BX task list to duplicate the task list available via Alt+Tab, deviations may occasionally occur. In particular, the BX task list will include tasks from all virtual desktops. Switching to a task on a non-current desktop will also activate that desktop.
Shift+N
Announce the number and name of the currently focused task.
`
Allow the currently focused task to be renumbered to a number of your choosing. This numbering assignment will last as long as the task remains open, even if JAWS restarts. This is a handy way to group tasks by purpose, get infrequently used tasks out of the way, etc. One interesting trick is to number tasks such that tasks from a particular desktop are all in a unique range of ten, so that for example, a lone digit will go to a main desktop task while shifted digits will go to tasks on the second desktop.

Test Function Support

The BX Quick Key includes a "Test" sublayer, accessed via T, in which the following commands are available:

Letters A through Z
Invoke a function whose name is "BXTest" followed by the letter typed; for example, typing QuickKey T S will run a function called BXTestS. Any return value that is speakable will be spoken when the function completes.
Letters A through Z with Shift, Ctrl, or Shift+Ctrl
Run the same function but pass the integer 1 as a function argument for Shift, 2 for Ctrl, and 3 for Ctrl+Shift. This quickly allows test function runs with special behaviors requested.
Digits 1 through 9 and 0 from the number row, possibly with modifiers
Run a test function called BXTestNum passing, respectively, 1 through 9 and 10 as an integer function argument. Add Shift to a digit key to pass 11 through 20, Ctrl to pass 21 through 30, and Ctrl+Shift to pass 31 through 40.
? (Shift+Slash)
Bring into a JAWS virtual view a list of the test functions available in current scope, with a description of each. See below for how descriptions are determined.

Calling any test function that does not exist will, naturally, produce an "Unknown function call" message.

Test function descriptions, for the above QuickKey T ? command, are retrieved in either of the following ways, the first to succeed for each function being the one that is used:

  1. If a function has a Synopsis or, failing that, a Description entry in any currently active jsd file, the text of this entry is used as a function description. OR
  2. BX will call the test function with an integer argument of -1 and use whatever string returns as a function description. Note that typing QuickKey T ? will make this call for exactly and only the above function names that exist and that do not have jsd entries as just described. It is therefore important to provide either a jsd Synopsis or Description or in-code handling of a -1 argument so that users who type QuickKey T ? get sensible results for each available test function.

An example of a well-formed test function (this form works for both letter types and the BXTestNum variant):

variant function BXTestS(int num)
if num == -1
	return "Window class of top-level window, or window name if modifiers are typed"
endIf
var handle hwnd = getTopLevelWindow(getFocus())
var string val = getWindowClass(hwnd)
if num > 0
	; The user typed Shift, Ctrl, or Ctrl+Shift with this call.
	val = getWindowName(hwnd)
endIf
return val
enddFunction

Event Logging and Tracing Features

BX is capable of generating, to clipboard and to JAWS virtual view, a log of event calls. This can be very useful in determining which events fire at certain times or in response to certain actions. At this writing, about 245 event and say functions can be logged.

How To Log Events

To use this feature:

  1. Get to the point where you want to start logging events.
  2. Type the BXQuickKey, then D for default (non-app-specific) application actions, and finally Ctrl+E. This will load a script file responsible for watching event calls. If the active application has any associated script, key, or other JAWS configuration files, they will be temporarily unloaded at this time. If this is a problem, use Ctrl+Shift+E instead of Ctrl+E. If your interest is primarily Braille-related events, try Ctrl+B or Ctrl+Shift+B instead.
  3. To start logging events, type JAWSKey+E twice in quick succession.
  4. Perform any actions and/or wait for events to fire and log.
  5. When ready to stop logging and see results, type JAWSKey+E once. The accumulated event log will appear in the JAWS virtual viewer. A copy of the log will also be placed on the Windows clipboard.
  6. Press Esc when done viewing the log.
  7. To save the log in a file, paste the clipboard into Notepad or a similar text editor and save it.
  8. To unload the logging code and reload any application-specific scripts, Alt+Tab out of and back into the application once.

Caveats

Some applications may, such as during a login process, relinquish and then retake focus, causing any loaded scripts to unload and then load again. If this happens while events are being logged, the event logging will stop and the event-logging scripts will be unloaded and not reloaded automatically. You can retrieve the logs accumulated up to the time of focus switch out of the application by repeating steps 2 and 5 from the above instructions (i.e., load the event-logging scripts and type JAWSKey+E once to view the already-accumulated log). It is currently not possible to log events safely through the out-of-and-back-into-application focus switch.

Customizing Logs

The event logging system supports customization through callback functions. These functions should reside in the custom default.jss file that loads BX itself, so they will not go out of scope when the event-logging code is loaded. Code in these functions should execute quickly when possible, as these functions may be called very frequently and rapidly.

To filter what is included in the output, write a logcallInclude function like the following:

int function logcallInclude(string call)
; Call is the full function call being logged, e.g., "WindowCreatedEvent(12345)."
if call == "keymapchange" || call == "keyPressedEvent" then
	; Do not log these events.
	return False
	elif logcallLevel("FocusChangedEventEx") > 2 then
		; Log FocusChangedEventEx and whatever it calls directly,
		; but do not log any deeper calls stemming from this event.
		; (level 1 is the event itself, 2 is a direct call from it, etc.)
		return False
		elif stringContains(stringLower(logcallName(call)), "highlighted") then
			; Do not log SayHighlightedText or SayNonHighlightedText.
			; logcallName() returns the name from the call without the parameters.
			return False
		endIf
		; Log all other events being traced.
		return True
		endFunction

To add extra log lines for specific events, write a function like the following. Any return value, which may contain multiple lines, will be included and properly indented in the log output. This example adds two lines below each original WindowCreatedEvent call (two lines because of the \n in the FormatString specification).

string function logCallExtra(string call, int isReturning)
; Call is the full function call being logged, e.g., "WindowCreatedEvent(12345)."
; IsReturning is True if this is a function return and False if it is the original function call.
if isReturning then
	; No extra log lines for returns, just for original calls.
	return ""
endIf
if call == "WindowCreatedEvent" then
	; Log useful information about the window being created.
	var
		handle hwnd
	let hwnd = stringToHandle(stringSegment(call, "(,", 2))
	return formatString("Class %1, name %2, IDString %3\nOwningApp %4, type %5 (%6)",
			getWindowClass(hwnd), getWindowName(hwnd), getControlIDString(hwnd),
			getOwningAppName(hwnd), intToString(getWindowTypeCode(hwnd)), getWindowType(hwnd)
	)
endIf
; No extra lines for any other events.
return ""
endFunction

Capturing and Examining UIA Events

BX allows capture and examination of any or all of up to about 200 different UIA events on a UIA element or tree. (This actually refers to about 35 different event types plus numerous change events for specific UIA properties.) As has admittedly been typical for BX in general, the documentation for this system currently lags behind the system itself; but this is a summary of how to use it:

  1. Activate BX and go to the UIA Navigation map with Apostrophe U.
  2. Find a UIA element of interest, and decide whether you want to capture events on just the element, on all its direct children, or on its entire subtree.
  3. Type Ctrl+E to open a box for entry of an event capture specification.
  4. To capture all possible events on the entire subtree (except for FocusChange events, which do not depend on current location), type a colon (:) by itself and press Enter. Be aware that, in many cases, this will capture enough events to slow the system down. The syntax of event capture specifications will be explained shortly.
  5. If necessary, perform tasks in the active application that trigger events. This may of course require you to exit and return to BX. During event capture, a brief announcement of each captured event is made. The announcement indicates the event type (e.g., Automation, PropertyChanged, etc.), specific information about the event when appropriate (e.g., event id or property id), and when possible, identifying information about the UIA element that generated the event.
  6. To stop capturing events, type Ctrl+E again from UIA Navigation and press Enter without typing an event capture specification.
  7. To examine the events captured, which can also be done while they are being captured, type the sequence Period Ctrl+E to move to the UIA Navigation map's Context map and then to the "Events" node in the XML view of the captured event information. This will also move you to the XML Navigation map and allow you to peruse the events using all of the features provided in BX for examining an XML structure.
  8. To clear the events captured, type Ctrl+Shift+E from UIA Navigation.

An event capture specification consists of one or more event type specifications separated by a Space. In general, only one event type specification should be required for a capture session. The elements of an event type specification are, in order

  1. A letter indicating the event type. Use the first letter of any of these: Automation, FocusChange, Notification, PropertyChange, StructureChange, or TextEditTextChange.
  2. If required, a letter indicating tree scope for this capture. Use the first letter of Ancestors, Children, Descendants, Element, Parent, or Subtree. (The UIAScriptAPI, and probably UIA itself, does not support scopes of Parent or Ancestors at this time, however.) Subtree is assumed if this letter is omitted.
  3. If the event type requires a further parameter, values of this parameter may be listed after a colon (:). This applies to Automation events (which require an event id), PropertyChange events (which require a property id), and others. In general, BX allows simple names for values of these parameters; see below examples. To capture all except certain events, include an exclamation mark (!) immediately after the colon and before the names of items to exclude.

Example event capture specifications:

F
Captures FocusChange events (these apply to UIA as a whole, not just to the current element or its subtree).
A:asynccontentloaded
Captures the Automation event AsyncContentLoaded on the current element's subtree.
Pc:!isoffscreen,name
Captures all except two possible PropertyChange events; those for the Name and IsOffscreen properties are ignored. These are captured on just the direct children of the current UIA element.
F A:asynccontentloaded Pc:!isoffscreen,name
Captures all of the above, with their respective tree scopes, in a single capture session (this is an example of a capture specification containing three event type specifications).
:
Capture everything imaginable (except FocusChange events) on the current element's entire subtree.

Caveats on the UIA event capture system at this time:

Updating Scripts With BX

BX includes features to facilitate updating BX and application scripts from the BX author. In BX itself, the Global Functions map includes three commands for updating scripts from this author's website. For those who have set up a BX Quick Key, there are parallel key sequences using the quick key:

bx_user.cnf also can contain a few options that govern the behavior of this script update feature. In general, these will not be of interest except in circumstances where they are necessary.

The update system works without issue on many systems, but some special preparation is needed for systems behind a web proxy:

  1. Open Internet Options, such as by typing that into the Windows Search bar and selecting it from the Control Panel section.
  2. Go to the Connections tab and press the "LAN Settings" button.
  3. Obtain the proxy address and port from the dialog that appears, then close all dialogs opened by this process.
  4. If that method is unsuccessful, obtain the required proxy information from other sources, such as a system administrator.
  5. Enter BX and go to the BX Configuration map (Apostrophe Ctrl+B).
  6. Type J to load bx_user.cnf into Notepad. If it does not exist, let Notepad create it.
  7. Make sure there is a [BX Options] section header in the file.
  8. Within that section, add lines for any required proxy settings. Usually this will be an http_proxy line or an https_proxy line, such as in the following example. In rare cases, user and password information may be required by the proxy server. The final line in the below example demonstrates how to handle this.
    [BX Options]
    http_proxy=my.proxy.com:8888
    wget_args=--proxy-user=myUserName --proxy-password=my_password_which_better_be_better_than_this
  9. Save the file, then restart JAWS once or reload all scripts and configurations with Ctrl+Insert+Esc. To avoid problems with Ctrl+Insert+Esc when controlling a JAWS Tandem session, instead make JAWS reload all configurations by compiling a script, such as the default.jss stub in the JAWS user folder.
The above procedure should not require administrative rights and should provide update functionality until and unless the proxy address or port changes.

Advanced Usage and Tips

These are uses of BX that go outside the norm.

Examining Beep Call Stacks and Process Launch History

BX quietly records the script call stack every time the beep() function is called. To see the recorded call stacks, type JAWSKey+Shift+B three times in quick succession. Press Esc when done examining the stacks. BX will begin throwing away the oldest calls after the number of entries reaches 20. This feature is intended to help debug scripts. Note that beeps generated by something other than a JAWS script will not cause entries to appear here. Entries appear newest first.

Below the call stack information, a list of process launches will also appear, one entry per line. Contrary to the call stack entry list, this list appears in chronological order (oldest first). This means that typing Ctrl+End in the JAWS virtual view and then arrowing up will traverse the list from the newest entry backward. This list is intended to help diagnose system and user activities that might slow JAWS processing, keyboard handling, etc. Due to restrictions on the JAWS event used to make this list, however, processes whose executable files live under the Windows folder will not be included.

Reading Invisible Lists, Combo Boxes, and HTML

Standard list and combo box controls support MSAA and thus make their contents available even when not displayed on screen. This is also true of standard HTML controls. This can sometimes be useful, as in the following examples:

BX can be used to find and monitor this type of activity as follows:

  1. Pick a running program of interest, even if not displayed, and search for its top-level window using Window Navigation. Alternatively, if you're just curious what's out there on your machine, just skim through the top-level windows looking for lists and combo boxes.
  2. Once you find a window of interest, mark it using the Mark system. This will make it easy to return here later to check for changes.
  3. Get the MSAA object for your chosen list or combo box by typing a dot and then c for the client object. For a list, this will be the List object. For a combo box, this will be the root ComboBox object, and you'll need to find the List object under that.
  4. Use RightArrow and then Up and DownArrows to explore the list's contents. You may want to mark other positions in your navigation to return to later as well.

The BX Configuration Files

BX ships with a bx.cnf file and can also read a bx_user.cnf file for user-specific configuration options. Users are strongly urged to change only bx_user.cnf and not bx.cnf so that future BX updates do not overwrite personal preferences. See bx.cnf for information on the options available.

Known Issues

The BX author is aware of the following issues but has not managed to address them to date:

BX Development History Overview (for the Curious)

BX has its beginnings as far back as 2001 in a lot of code snippets I tinkered with as I found time. I kept trying to figure out a way to reduce the amount of time I had to spend testing things for scripting projects, but I couldn't come up with a satisfactory interface just by creating scripts., because the interface invariably became unwieldy. I wanted a way to redefine any key on the keyboard dynamically, and also a way to specify what each key should do in a more concise way than by writing a new script for each case. I made several attempts at both problems, one of which used the JAWS virtual buffer and allowed keystrokes to add to it dynamically; but I was still not happy with the results. The virtual buffer idea made me realize I also needed a system that had absolutely no effect on what was in focus or on the results returned by all the JAWS scripting functions. Using the virtual buffer violated this requirement.

In late February of 2003, I finally met with success and began collecting code snippets into a coherent system. Predicting, accurately as it turned out, that some of my coworkers might also want to use the result, I named the budding tool Bart Explorer and sent a copy to a few coworkers for them to play with. (This name is where the name BX initially came from.)

Although I created much of BX in my spare time and outside any project under company direction, I actually thought it might one day become either a part of JAWS itself or a Bartimaeus Group company product for commercial distribution. Neither happen, although one or two binary copies were actually sold. Because of this thought though, because I had such a complete lack of experience in the legal arena and did not know how to craft an appropriate license agreement,, and perhaps mostly because I knew the tool suffered from a profound lack of documentation, I said little of the tool's existance to people outside the company. I did, however, keep developing it regularly and kept my coworkers apprised of my progress, adding features as I found need for them and occasionally in response to coworkers' requests and suggestions. At some point I realized I was also leaving a trail of BX installations behind as I went from site to site scripting for various companies and agencies, because I never scripted without it and found it decidedly inconvenient to have to uninstall and reinstall it on each visit to a site (BX at that time had no installer).

BX first went officially public on September 11, 2007. Shortly thereafter, and to my surprise, a link to it appeared on a prominant Freedom Scientific web page. The public release had no other noted significant impact however, possibly due to the aforementioned profound lack of documentation.

At some point after the above public release, I began implementing features for myself and coworkers in what had by this time become SSB BART Group, but features that I was reluctant to release to the public for various reasons. For example, BX became capable of altering HTML code on an active web page, in place. This concern caused me to begin keeping a separate, "Pro" version of BX for myself and other SSB employees. As a side effect though, my efforts to keep the public BX up to date suffered greatly.

In early 2017, prompted by several needs to give out BX copies to SSB clients and by the existence of other easily available tools that duplicated Pro features of BX (e.g., Firebug for editing HTML in place), I decided to again unify BX into a single version. I also decided to stop including source code at this time, however. Reasons for this included

In February, 2019, many more of my free public projects also stopped including source code. See my Script Distribution Policy document for details.

Acknowledgements

I would like to thank Victor Tsaran for his constructive input in the very early days of BX's creation, and for writing and allowing Bartimaeus Group and me to use a Nullsoft installation script for it (some of Victor's installer code is still in the BX installer as of this writing).

I also thank Jonathan Avila for suggestions that guided some of BX's early development and, as he was my manager for BX's early years, for encouragement to write it and permission to work on it from time to time between projects at the office. Chad Foster also contributed some ideas while he worked with us in the early 2000's, for which I am grateful.

Beyond former coworkers, Michael (Mick) Curran deserves appreciation as well, for contributing one major idea to BX, that being the irregular-looking use of GetObjectFromEvent to retrieve MSAA objects directly from window handles (I saw that his JFWTechnical scripts did that in the early 2000's).

I could try thanking all the companies and individuals who, in the course of my doing scripting both on and off the job, caused me to think of or need various specific BX features; but the list would be long and the time to pull it together even longer. I will just say that it was the widely varying character of my scripting projects over the years that caused so much to happen to BX.

Last but certainly not least, and in the spirit and style of Larry Wall, author of the Perl programming language among other major public offerings, I wish to thank the Author of my story for prospering the work of my hands.

Revision History

This is the revision history of BX, most recent revision first.

Revision 2558, November 11, 2023

Revision 2548, October 12, 2023

Revision 2533, August 28, 2023

Revision 2525, July 12, 2023

Revision 2501, June 24, 2023

Revision 2490, January 19, 2023

43 older revisions back through June 16, 2008

Revision 2483, November 27, 2022

Revision 2469, November 22, 2021

Revision 2444, December 28, 2020

FSXML Testing map enhancements:

MSAA Navigation map enhancements:

Object Examination map enhancements:

Window Navigation and related enhancements:

Miscellaneous updates:

Revision 2425, October 30, 2020

Revision 2421, September 28, 2020

Revision 2410, June 24, 2020

This is a big enough update to warrant a subsection in the release notes! Changes are listed by category, followed by a subsection describing one particularly complicated feature update, that being the method to capture and examine up to about 200 different UIA events. (This subsection was moved into the main document on November 27, 2022; see Capturing and Examining UIA Events.)

General changes:

Changes in the BX documentation:

Changes in Global Functions:

Changes in UIA Navigation:

XML-related changes:

The final section of these release notes was moved on November 27, 2022; see Capturing and Examining UIA Events.

Revision 2325, March 08, 2020

A block of BX code that has been active since 2003 is suspected of occasionally causing performance problems during focus switching between applications. This update is therefore recommended for all BX users. The performance issue appears to affect JAWS 2020 and possibly 2019 and consists of speech and keyboard stalls of several seconds' duration when the user switches between applications and then very quickly tries to issue commands to the newly focused app.

Update, April 8, 2020: Such stalls have, since publication of this release, been seen to occur without older BX versions active; but the advice to upgrade BX remains.

Along with removal of this code block, the following four BX commands are removed:

Revision 2303, February 15, 2020

Revision 2246, October 14, 2019

Revision 2244, October 9, 2019

Revision 2214, July 3, 2019

This revision fixes a problem some users experienced with the BX Update system. It also replaces some oddly-located features with more sensibly located and flexible commands and maps. The new commands and maps will be described first, followed by the removed commands and how they were replaced, and finally some other changes and enhancements beyond the new commands and maps.

New commands and maps:

Removed commands and how to accomplish what they once did:

Other changes and enhancements:

Revision 2171, June 7, 2019

Typeing QuickKey B toggles on/off a battery watching feature described below and also speaks, and shows in Braille where applicable, "on" or "off" indicating whether the watch feature is on or off, then the following very briefly summarized computer power status information:

Typical battery status examples:
ph 100%
bl 25% 21 minutes remaining

If the watch feature is on, any change in the above status information, except for hours/minuts/seconds remaining, is reported as it occurs. To turn the watch off again, type QuickKey B again.

Revision 2127, April 22, 2019

Revision 2085, March 5, 2019

Revision 2041, November 19, 2018

This release contains several miscellaneous changes as well as a coordination of features for updating scripts.

Miscellaneous changes:

BX now includes means to pull updates to itself and to scripts for running applications from the BX author's website. All updates use secure https rather than http to retrieve update files.

Warning: Use of the below update commands should be considered equivalent to following a beta track, as incomplete and experimental features may appear from time to time via such updates. This warning applies to both updating BX and updating scripts for other applications. Also, the update system's ability to function may be dependent on local and network policy restrictions on web access and/or local file and folder access.

The following commands from the Global Functions map are available for performing updates:

For those who have defined a BX Quick Key, the same three keys typed after QuickKey D will also work. See "The BX Quick Key" in the BX User's Guide for more information.

Revision 1982, August 9, 2018

Revision 1970, June 25, 2018

S in Object Examination includes the hex value from GetObjectStateCode, a function that has been around for a long time. In sufficiently new versions of JAWS 2018 and later, pressing S twice will report the hex values from GetObjectMSAAState and GetObjectIA2State, and pressing three times will report the hex value from GetObjectStateCodeEx. At least the first two of these three new functions are documented in versions of JAWS 2018 prior to their actual implementation in JAWS itself.

Revision 1961, May 8, 2018

Revision 1876, September 6, 2017

Revision 1813, April 1, 2017

Revision 1797, March 28, 2017

There are numerous improvements and additions over the 15a release, unfortunately not at this time listed here.

Revision 1164 (Version 15a), January 20, 2014

This version was long considered experimental. It is the last version supporting JAWS 13 and older and is not recommended for newer JAWS versions.

Bug fixes:

Enhancements and changes:

UIA Filter Specifications:

BX now includes a system for letting users specify UIA tree filters via an edit box. This system encapsulates the various Condition-building features of the new JAWS 15 (and undocumented but present in JAWS 14) UIAScriptAPI COM system.

Filter strings, or specifications, consist of a series of one or more items separated by single spaces. The items comprise an expression that forms a filter condition. The expression is in post-fix, or Reverse Polish Notation (RPN) format. This may be unfamiliar to some users but significantly simplifies expressions by avoiding the need for parentheses and for recursion in parsing (which JAWS does not support). Example expressions:

rawView
Requests the entire UIA tree be visible for navigation.
contentView focusedProcess and
Include only content-view elements and only those in the focused Windows process.
FPContentView
Shorthand for the above.
FPRawView controlType checkBox controlType edit or and
Include only checkboxes and edit controls in the focused process (this much complexity is rarely necessary).

Here are all the types of items permitted in a filter specification:

contentView, controlView, rawView
Require the given UIA tree view type.
focusedProcess
Require the process ID to match the focused application's process ID.
FPRaw/Control/ContentView
One of the above with focusedProcess.
not
Reverse the previous condition: "focusedProcess not."
and, or
Combine previous two conditions: "contentView focusedProcess and."
property name
The name of a property with a PropertyID. These are from UIA.jsh without the UIA_ prefix and PropertyId suffix. Examples: Name, ControlType.
value name
The name of a value with an ID. Categories:
  • Control types like CheckBox, Edit, and Hyperlink.
  • Other constants without *_ prefix, like Horizontal and LargeIncrement.
  • Other raw constants like Next that contain no underscore.
False, True
Create a boolPropertyCondition with the previous item. Example: "IsEnabled True." If not after a property, creates a False or True condition (directly in JAWS 15.0.5056+, simulated before that).
int like 1, -50, etc.
An integer value. Makes an IntPropertyCondition with the previous item. Example: "RangeValueMinimum -5"
String like 'hello'
A string value. Makes a StringPropertyCondition with the previous item. Example: "Name 'My UIA Application'" To get a literal apostrophe in a string, write two of them together. Backslash escapes like \t also work.

Version 10a, January 14, 2014

This is the last BX version supporting JAWS 10 and older and is not recommended for newer JAWS versions. This version calls itself "BX10" when Insert+Q is typed while BX is active. There is no listed revision number for this release because it was for a while maintained in a separate code branch.

Window Navigation updates:

HTML Testing updates:

Miscellaneous updates:

Revision 921, March 1, 2013

New features:

MSAA Navigation updates:

Object Examination updates:

AccessibleObject Tree navigation updates:

Cursor Navigation updates:

Global Functions updates:

Miscellaneous:

Revision 818, December 19, 2011

AccessibleObject Tree Navigation (.a from Window Navigation):

COM Object Testing:

Global Functions:

MSAA Navigation:

Object Examination:

SDM Navigation:

Window Navigation:

BXQuickKey functions:

Miscellaneous:

Known remaining issues:

Revision 718, August 6, 2011

New Maps and Features:

General:

Window Navigation:

MSAA Navigation:

Revision 582, January 31, 2011

Window Navigation:

MSAA Navigation:

General:

Known issues that have not yet been addressed:

Revision 533, October 25, 2010

General (multiple map) changes:

Window Navigation:

MSAA Navigation:

Inspect Objects navigation:

HTML Testing:

Pixel Navigation:

COM Object Testing:

Miscellaneous changes:

Distribution fixes:

Revision 377, May 11, 2010

Revision 304, February 16, 2010

Revision 280, November 25, 2009

Revision 244, September 27, 2009

The BXTest system is enhanced as follows:

The intent of this BXTest enhancement is to allow creation of comprehensive code testing systems that have no end-user impact, document themselves, and can remain in production code without causing any harm.

Revision 238, September 23, 2009

Revision 233, September 22, 2009

Revision 212, September 17, 2009

Miscellaneous quick changes:

Installer changes:

And one big change:

This update eliminates a lot of JAWS-based tricks for identifying VARIANT variable types, in favor of a much more reliable VBScript-based approach. This enables the following new features:

In addition, the following are included to aid in identifying exactly how MSAA calls respond:

Revision 204, September 16, 2009

BX is now versioned in Bazaar rather than CVS.

Installation notes:

Changes:

June 2, 2009

BX development silence as preparations were made to convert versioning from CVS to Bazaar.

Revision 103 (end of CVS history), May 20, 2009

CVS tag bx_rel081211_sam, December 11, 2008

The CVS tag for this revision is so named because this version of BX was sent to a coworker named Sam for a project.

CVS tag bx_rel081017_scott, October 17, 2008

Like the above revision, this one was sent to a coworker after whom the CVS tag is named.

CVS tag bx_rel081013_roy, October 13, 2008

Yet another CVS tag named after a coworker recipient of the revision.

CVS tag bx_rel081010, October 10, 2008

(This text is drawn from an email.)

The most notable update is the addition of bx_evwatch.jsb and a system that allows for event watching without requiring application script files to be edited. The new system is documented in BXMan.htm under its own section, which should be easier to find because BXMan.htm also has a table of contents now. In summary, it works like this:

While the bx_evwatch code is running, application script and configuration files will not be loaded, so the events logged will be what JAWS does by itself.

The system currently tracks about 134 events and Say functions, all I know of to date through JAWS 10 including some undocumented stuff. You can fine-tune what events are logged and even what is logged for each by writing logcallInclude() and logcallExtra() functions (names subject to change though). You can even pick functions to log by whether or not, and how deep, they are found in the calling chain of another function; for example, log FocusChangedEventEx but nothing called from it.

In the log output, which is also placed on the Windows clipboard automatically when shown, the first column is the decimal number of seconds from log start when the call occurred, the second column is "c" for a call and "r" for its return, and the rest is the call itself with parameters, and return value where appropriate.

Other changes:

The semicolon key (;), which cycles among related maps from some maps, is now documented. In the Window Navigation map, it toggles with a new Window Messages map, which can be used to see what happens when various messages are sent to a specific window using SendMessage or PostMessage. Among other things, this map provides means to test methods of moving focus through a dialog or among MDI children that Microsoft says are better than using SetFocus.

N in Window Navigation, which has always reported the result of the JAWS GetWindowName function, now also reports when the length of that result differs from the result of the WM_GetTextLength message, which can help detect when JAWS is "guessing" at a window name instead of providing what WM_GetText would provide. We can't get WM_GetText directly in JAWS, but this at least helps determine when this might matter. Caveat: The two lengths often differ by one character even when the strings otherwise would match, so at best this new report is just a heads-up, not an indication of missing info.

E in COM Object Testing will now allow parameters to be passed to method calls.

P and Ctrl+P in HTML Navigation and Ctrl+P and Ctrl+Shift+P in MSAA Navigation should now work with the Virtual PC cursor active.

There are a few improvements in how the Braille map is implemented.

BXMSAA.jsh includes some extra MSAA constants listed as Gecko navigation commands. These have not been tested but will not apply to many applications.

When you navigate in the MSAA map, you may occasionally hear "AutoAccChild," indicating that BX automatically called .AccChild to get somewhere even though you did not explicitly ask for this. The behavior is not new, but the announcement of it is.

A few superfluous files are no longer included in the src folder in the zip file.

CVS tag bx_rel080616, June 16, 2008

Revision history documentation stops here for now.