BX User's Guide
Doug Lee
Last Revised March, 2017

Welcome to BX, the JAWS toolbox!

Copyright (c) 2006-2017 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:
Category Description
Window Functions Go to first, last, parent, child, next, previous, current, focus, real, foreground, top-level, or other windows directly; and get a window's class, name, control ID, display style, dimensions and location, contents, etc.
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. This navigation is not possible in JAWS' Script Utility mode.
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.
HTML and XML Navigation
  • 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, edit live DOM elements or trees by hand in place and test the results, and run many tests on HTML documents for accessibility issues and HTML structure problems.
  • In any browser supported by JAWS, obtain and navigate a web page's XML view as provided by JAWS 17 and later.
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.
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.
Program-specific Functions Find out the version number or version info strings for the active application, the name and version information for the current application or default script files, etc.
COM Object Functions Find out if any of the JAWS functions returning COM object interfaces work from the current cursor location.

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 14.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.

BX Usage

BX is activated via the command that normally activates JAWS script utility mode, formerly called home-row mode before JAWS 11. By default, pressing this command once will enter BX mode, and pressing it twice in quick succession will enter JAWS' normal script utility mode instead. (BX can easily be configured to enter script utility mode on a single press and BX mode on a double press if desired.) When in either BX or script utility mode, typing this command while in BX will return you to normal operation.

In JAWS 10 and older, the command to enter home-row or script utility mode was JAWSKey+Space on most systems. In current JAWS versions, this keystroke is a prefix for various other JAWS functions. For convenience (and for the BX author's preference) (the normal script utility mode keystroke being sometimes inconvenient to type), typing JAWSKey+Space or Ins+Space twice will enter BX, or script utility mode if so configured. Typing this command four times quickly will enter the other mode.

In JAWS' original script utility mode, you had a location, defined by a window handle, and a set of possible commands. The possible keystrokes never changed, but their output did: You could 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 arrow, and down arrow, 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 control key. Thus, when navigating among windows, control+f will jump to the window in focus, and control+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, 'w for Window Navigation or 'm for MSAA Navigation), setting a starting point (for example, control+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 with the standard JAWS home-row mode command.
  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 control+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 control+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.
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.
control+tab and control+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.
. 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.
; 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.
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+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.
Escape 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 (' 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+Ins+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.
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.

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.

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 230 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

Updating Scripts With BX

BX includes features to facilitate updating BX and application scripts from the BX author. See the Global Functions map and the Default QuickKey map for related keystrokes and bx.cnf for related configuration options.

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

  1. Open Internet Explorer and go to Tools > Internet Options, Connections tab. Press the "LAN Settings" button.
  2. Obtain the proxy address and port from the dialog that appears, then close Internet Explorer and all of its open dialogs.
  3. Open the System Settings page from Control Panel or by typing Windows+Pause.
  4. Press the "Advanced System Settings" button (quickly reached via Shift+Tab).
  5. Find "Environment Variables" and create a user variable named HTTP_PROXY. For its value, use the proxy address, a colon (:), and the port.
  6. Close all dialogs just opened and restart JAWS.
The above procedure should not require administrative rights and should provide update functionality until and unless the new environment variable is removed or the proxy address or port changes.

Advanced Usage and Tips

These are uses of BX that go outside the norm.

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.

Reading an HTML Report While Navigating the DOM

The following trick allows you to read through an HTML report while navigating the tree being reported on:

  1. Load an HTML page and run a report on it, either directly via the Report map or indirectly from the BXQuickKey.
  2. When the report comes up in the JAWS virtual buffer, select all of its text with Ctrl+A, then copy it to the clipboard.
  3. Load NotePad and paste the report into it. Move to the top of the report.
  4. Switch back to the HTML page, start BX, enter the HTML Navigation map, and jump to the top of the document by typing Ctrl+D twice. Move right once with RightArrow to land on the root HTML object for the page.
  5. Type JAWSKey+3 to pass the next keystroke through to the current application, then type Alt+Tab. This will put NotePad back in focus without closing BX, and thus without losing your place in the HTML map.
  6. Now use the Cursor Navigation map to read the report and the HTML Navigation map to examine the DOM to which the report applies. Arrows and all other normal text navigation commands should work in Cursor Navigation. If you want to find a particular element mentioned in the report, such as element 235, use the numeric navigation commands in HTML Navigation (pageUp/Down, alone and with Shift and/or Control) to find it.
  7. When done, close BX. Do not close BX before you are done though, because this will clear your current position in the HTML Navigation map.

The HTML Report

This is not complete documentation on the HTML report but should serve to explain what it does and how to fine-tune it.

Report Categories

Categories of information can be included or excluded from HTML reports based on user preference. The bx_cache.ini file will now, as reports are run, begin to contain keys in a "HTML Report" section that specify whether to include or exclude certain types of information. If you are seeing a lot of something you don't want to see, edit bx_cache.ini and change the number after the appropriate key to 0. The number assigned automatically to keys not already found is -1, which means use the default value. The default value is 1 (which means include) unless you add a "default" key yourself, in which case you can set the default to whatever you want. This way, you could request only certain things instead of including everything except certain things. In summary, everything will be included by default, setting a key to 0 will take out that item, setting default to 0 will take everything out, and then setting a specific thing to 1 will guarantee it is included no matter what the default is.

The following category keys exist and indicate the described types of information:

AttribBlank
An attribute important to an element has a blank value. This can be good or bad depending on context.
AttribContainsTag_tagName
An attribute value actually appears to contain an opening tag, such as <P>. This is not a problem except that JAWS 7.0 and earlier could misinterpret this as an actual opening tag and produce very strange results.
AttribExpando_attribName
Attribute attribName was found in the document but appears not to be recognized by the browser. This may be fine but may also indicate a typo or other mistake. Separate category keys are created for each different attribName.
AttribHasContent
An attribute important to an element is not null or blank. As for null and blank attribute values, whether this is good or bad depends on context.
AttribNotFound
An expected attribute is not found for an element that should have it.
AttribNull
An attribute that matters for an element has a null value. This can be good or bad depending on context.
AttribUnspecified
An attribute that should be found for an element is found but was given a default value rather than being specified by the document author.
ButtonWithLabel
A button has an attached Label tag. This is normally not necessary, as the Value attribute is used for the button name.
ButtonWithTitle
A button has a Title attribute. This is not always a problem but can cause confusion when the Title and Value (effective name) of the button are significantly different.
ButtonWithoutValue
A button does not have a Value attribute, which effectively means it has no name.
CountBehaviorURNs
The presence of this category causes counts of BehaviorURNs per element to be checked and non-zero counts to be reported.
CountFilters
The presence of this category causes counts of Filters per element to be checked and non-zero counts to be reported.
EventFound_eventName
Causes all instances of event eventName to be reported. Separate category keys are created for each eventName found.
IDCaseMismatch
An ID reference and the ID referred to match except for character case. This could potentially confuse applications or access technology, though no such occasions are known.
IDNotFound
An attribute that should be a link to one or more IDs specifies an ID that does not exist. Attributes checked for this are For and Headers. Due to an IE6 behavior of GetElementByID returning a non-null result when no ID matches but a Name does, this category also includes mention of cases where an ID reference matches a Name attribute of an element exactly but does not match an ID.
InnerHTMLContainsTag_tagName
The text between a particular element's opening and closing tags appears to contain the opening tag tagName. This is reported because certain tag nestings can confuse JAWS versions 7.0 and older; example, a Script tag containing a document.write call whose text contains a Label tag. Separate category keys are created for each nested tagName (unfortunately not for each outerTag-innerTag pair).
ItemLabeled
An element has an attached Label. This is usually a good thing.
ItemLabeledAndTitled
An element has both a Title attribute and an attached Label tag. This can be fine, but it is helpful if the two are similar because users may hear only one, the other, or both when using access technology.
ItemNoAlt
An element is missing an Alt attribute and should have one.
ItemNoIDOrTitle
An element that needs a name has no Title and no ID to which a Label tag could be linked.
ItemNoLabelOrTitle
An element that needs a name has no Title and, though it has an ID, has no Label tag linked to it.
ItemTitleButNoAlt
An element that should normally have an Alt tag does not but has a Title attribute. This may work but should be inspected manually.
ItemTitled
An element has a Title but no attached Label. This should be ok but is not always preferred.
LabelBlank
A Label contains only whitespace. This is irregular and should be inspected manually for its actual effect.
LabelNoFor
A Label tag has no For attribute, which prevents it from being linked to a field explicitly. This could mean the For attribute was omitted accidentally or that the Label is an implicit label, wrapping rather than linking to its field. Implicit labeling is not recommended.
LabelNull
A Label contains nothing. This is irregular and should be inspected manually for its actual effect.
LinkToMultipleLabels
An element's ID matches For attributes of more than one Label tag. This can cause confusion and should be avoided.
SamePageLinkNotFound
An element (generally a link) has an href attribute that points to an anchor in the current document, but that anchor seems not to exist.
TabIndex
The presence of this category causes all non-zero TabIndex values to be reported.
TagExtraClose
A closing tag was found where no matching opening tag seems to exist. This often means there was a typo but can also result from code generation problems. This situation is generally harmless unless it signals a larger issue, for which reason a manual inspection is recommended.
TagFound_tagName
Tag tagName was found in the document. Tags reported in this way deserve special attention. Embed, Applet, and BGSound tags are examples.

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.

BX Past and Future

Here are documented the origins of and plans for BX.

BX History

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

BX In the Future

I intend to keep using and developing BX just as I have been, in response to needs and suggestions I receive. In gratitude to the company that helped and encouraged me to develop BX, which has been known as Bartimaeus Group, then BART Group, then SSB BART Group, and now Level Access, I intend to continue shaping BX based on company and project needs.

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 greatful.

Beyond current and former coworkers, Michael Damian Curran, also known just as Mick, 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.