Thunder Scripting Manual

13 August 2011. Alasdair King.

Thunder has a powerful scripting mechanism, allowing you to tailor hotkeys and speech output to particular applications.

There are built-in Thunder scripting features, and there are additional Thunder scripting features provided by AccessScripting. The latter are only available for installed versions of Thunder. Built-in features are available for both installed and USB memory stick versions of Thunder.

1 Thunder Scripts

Thunder scripts are written in VBScript. The script must have the same name as the program it is being used for but with the extension ".lsc". So, for example, the Windows calculator (calc.exe) has the script calc.lsc. The script is placed in the Thunder program folder.

Start the Thunder script debugging window by starting Thunder and pressing the "+" key. This will let you see what is running and usable. You can write to the Script Debugging List in your script by calling ScriptDebug with a string. Make sure it's a string by appending & " " (that's ampersand, quotation marks, space, quotation marks).

You may find it easier to copy the Thunder folder out of Program Files into your Documents folder and work on the scripts there, so you don’t have to be an administrator or turn off UAC to edit the scripts. Thunder will work fine there.

To start scripting for Thunder you are probably best to start looking at some existing scripts. Try calc.lsc first and then Excel.lsc - they should get you going.

Variables for Scripts

LastSpeak

The last string that was spoken by the speech synthesizer.

RectTop, RectBottom, RectLeft, RectRight

Integer values populated by the Rectangle functions. Call the appropriate function before using them.

ScreenX, ScreenY

Resolution of the whole screen. Like every other x, y value, measured in pixels.

ScriptX, ScriptY

Populated by CursorPos and ReadingPos, giving you the location of the screen cursor (mouse pointer) and Thunder reading cursor respectively.

NoviceMode

Corresponds to the novice mode setting in Thunder settings. Adds extra explanatory text to speech output for new users.

SpeakHomeEndEtc

Corresponds to the Speak Home, End etc. setting in Thunder settings.

SpellNos

Corresponds to the Spell Numbers setting in Thunder settings.

UseMusic

If set/true then plays the tones as you cursor around the screen. Corresponds to the UseMusic setting in Thunder settings.

KillMidi

Stops all Midi interaction with Thunder to leave your application free to do its own music. (There's a Midi function in Thunder!)

MoveBy

When the Thunder reading cursor is moved by a hot key it moves either by 4 pixels (MoveBy = 0) or by object (MoveBy = 1) (Thunder versions before 1.0.46 moved by 7 pixels) Moving by object means that the cursor is moved until a new MSAA object is under the mouse (testing at 7 pixel intervals).

KeyEcho

Corresponds to the "Echo characters" and "Echo words" checkboxes in Thunder settings. 0 is both off, 1 is characters only, 2 is words only, 3 is characters and words.

PunctuationLevel

Corresponds to the Punctuation setting in Thunder settings. 0 is none, 1 is some and 2 is all.

ScriptObjectName

If an application has an object model accessible through COM via CreateObject or GetObject then set this string to be the name of the object mode and then call ObjectInit. See Word and Excel scripts for examples.

ScriptObject

The object created by ObjectInit, the scripting automation COM object for the object model for the application. Use automation objects for scripting complex applications like Word, Excel or IE.

CaretX, CaretY

Returns the position of the caret obtained from MSAA in pixels. This is generally the position of the flashing caret in text areas, and is not the same as the screen cursor (mouse pointer) or the Thunder reading cursor.

GotCaretChange

If true then MSAA detected a caret change - the user typed something or cursored around a text field.

GotMenu

If true then MSAA detected a menu opening/closing/changing.

GotMSAAchange

If true then MSAA has detected a change in focus or another MSAA event.

DealtWith

Use this to tell Thunder that the script has dealt with what needs to be spoken, and Thunder should not do any of its own speaking.

Functions for Scripts

ObjectInit

Sets ScriptObject to the automation scripting object indicated by ScriptObjectName. Set ScriptObjectName to the string for the automation interface (e.g. "Word.Application" for Microsoft Word) then call ObjectInit, and ScriptObject should now be the Word automation Application object. You must call this function before doing anything with ScriptObject, and call it in every function - you cannot assume that ScriptObject will persist.

ObjectClose

Sets ScriptObject to Nothing.

ParentWindowFromPoint(x,y)

Returns the window handle (a long value) for the top-level application window indicated by x, y.

MSAATop

Returns the top coordinate of the current MSAA object window.

MSAALeft

Returns the left coordinate of the current MSAA object window.

To return debug text

ScriptDebug(s as String)

Adds s to the Script Debugging List control in the Thunder debug window. Open the debug window by pressing "+" in Thunder.

To extract the current screen positions

CursorPos

Populates ScriptX and ScriptY with the position of the screen cursor (mouse pointer). Has the side effect of

ReadingPos

Populates ScriptX and ScriptY with the position of the Thunder reading pointer.

To set the current screen positions

SetCursorPosition(x, y)

Sets the position of screen cursor (mouse pointer).

SetReadingCursor(x, y)

Sets the position of the reading cursor and also the screen cursor (mouse pointer). Does not validate x and y values, just applies them. Use MoveReadingCursorAbsolute, it's safer.

SetReadingCursorQuiet(x, y)

Sets the position of the reading cursor but does not move the screen cursor (mouse pointer). Does not validate x and y values, just applies them.

MoveReadingCursorRelative(x, y)

As SetReadingCursor, but the change of position is relative to current position of the reading cursor. The screen cursor (mouse pointer) is moved to the same place as the reading cursor. x and y are clipped to the screen.

MoveReadingCursorAbsolute(x, y)

As SetReadingCursorQuiet but the x and y values are clipped to the screen.

Other

GetNextSpellingError

Moves along spelling in Word to the next error.

StopAutoRead

Has something to do with stopping automatic reading in response to key events (not understood).

ForegroundClassIs(s)

Returns (as a string, strangely) whether s is the same as the ClassName of the current window.

Load_Script(s)

Load VBScript script with path s (not name s, I think.) Fires the InitialiseScipt event.

LoadConfig(s)

Load configuration of hot keys, speed etc., for configuration file with name s (not path s, I think)

TimerEnable

Turns on the script timer. The EventTimer event will now fire every TimerInterval milliseconds until TimerDisable is called.

TimerDisable

Turns off the script timer. The EventTimer event will no longer fire.

TimerInterval(i)

Set the speed (in ms) of the script timer, that is, the period with which EventTimer will fire. The default is 100ms.

ScriptShell(s)

Runs the program whose path is specified in string s.

DoInputBox(prompt, title)

Get input from user. This displays an input box with the appropriate strings as prompt and title, and returns the value provided by the user.

ShowCheck

Displays Thunder's spell checking Window for MS Word.

TidyWindow

Moves the foreground window to the top-left-hand corner of the screen and, if possible, maximises it

Say(s)

Speak string s.

SayMore(s)

Add string s to the speech buffer, but don't cancel previous messages.

Mute

Shut up the synthesiser.

GetWindowRectangle(x, y)

Sets RectLeft, RectTop, RectBottom and RectRight with the application top-level window rectangle (the one with the parent of Desktop) that contains the window corresponding to x and y. Has the side effect of setting the Thunder ReadingRectangle to the top-level window rectangle.

GetPaneRectangle(x,y)

Uses WindowFromPoint to get the Windows window containing x,y and sets RectLeft, RectTop, RectBottom and RectRight to its values. Has the side effect of setting the Thunder ReadingRectangle to the same Windows window.

GetObjectInfo(x, y)

Returns a string for the MSAA object at point x, y. This is formatted and suitable for presentation to the end-user. For example, an input button with the caption "Cancel" will return "Cancel button".

GetLastText(x,y)

Returns the MSAA accName value for the MSAA object at x, y - but only the last line of it.

GetLineInfo(x,y)

Sets ReadingRectangle to the Windows window containing x, y, but does not change RectLeft, RectTop, RectBottom or RectRight.

GetObjectText(x,y)

Returns the MSAA accName value, or if an empty string the accValue value, for the MSAA object at x, y.

GetObjectValue(x,y)

Returns the MSAA accValue value for the MSAA object at x, y.

GetForegroundRectangle

Sets RectLeft, RectRight, RectTop and RectBottom with the co-ordinates of the current foreground window. Has the side-effect of setting the Thunder ReadingRectangle to the current foreground window.

GetWindowTitle

Returns string containing the window title of the current foreground window (using GetWindowText API call)

LeftClick

Clicks the left mouse button

RightClick

Clicks the right mouse button

LeftDown

Presses the left mouse button down

LeftUp

Lifts the left mouse button up

SpeakSlower

Reduces the synthesizer voice speed by 1.

SpeakFaster

Increases the synthesizer voice speed by 1.

Spell(s)

Return string s as string with characters separated by spaces

SpellSlow(s)

As Spell, but speaks with larger pauses between characters.

RepeatSpell

Repeat last speech message and spell it out.

Phonetic(s)

Return string s as string with characters spelled out phonetically.

RepeatPhonetic

Repeat last speech message phonetically

SetMarker (i, x, y)

The marker i, which must be an integer between 1 and 255 inclusive, now has the values x and y.

MarkerX(i)

Returns the x coordinate for the marker indicated by i.

MarkerY(i)

Returns the y coordinate for the marker indicated by i.

VoiceOff

Turns synthesizer off until VoiceOn is called or until user presses hot key.

VoiceOn

Turn voice back on after a VoiceOff command.

ScriptSendKeys(s)

Send the keystrokes specified by the string s to the current application. (Format is VB SendKeys codes)

ClipBoardText

Returns the text in the clipboard

DoTheEvents

Calls DoEvents, which lets the operating system handle other events in the queue. Useful if things are getting hung up, but can cause terrible confusion with the sequence of functions and events, so use with caution.

GetItem(i)

Returns the ith item from ScriptList. Not populated, do not use.

ItemCount

Returns the number of items in the ScriptList. Not populated, do not use.

There are three functions that deal with the Thunder instruction queue. This is a queue of instructions that you can add to. Instructions are excecuted every 20th of a second and then deleted. It can be useful for timing operations like ScriptSendKeys or mouse movements and clicks.

AddToQ(s)

Adds instruction string s to the queue. An instruction string is a VBScript command.

QSize

Returns how many instructions are currently in the queue.

QClear

Clears the queue.

Events for Scripts

EventLoaded()

This event is fired when the script is first loaded.

EventUnload()

This event is fired when the current script is about to be unloaded.

EventFilterKey(scancode, shift)

This event is fired when the user presses keys - it gives you the scancode and shift states. (Good example - see calculator script.)

EventFilterChar(ch)

This event fires on printable characters being typed. The character is passed in ch. (Good example - see calculator script.)

EventHotKey(i)

This event is fired when the user pressed one of the 10 script hot key combinations. The integer i indicates which one, from 1 to 10.

EventNewWindow()

This event is fired when a new foreground window appears for the current application.

EventTimer()

This event fires on the event timer. (See TimerEnable, TimerDisabled and TimerInterval above)

EventScriptString(s)

This event is fired when the user types a script string. The text is passed in s.

EventIdleTimer()

This event is fired repeatedly when the system is otherwise idle. This is how you access the MSAA and UI events in which you're interested, like the user tabbing around to a new control. When this is fired, check the values of GotCaretChange, GotMenu and GotMSAAchange. Note that these are not mutually exclusive.

EventHelp()

This event is fired when the user presses the Thunder Help key (should be CAPS-Shift-F1)

2 AccessScripting

AccessScripting is a component that gives you more scripting power in Thunder by providing extra functions. It has been included in Thunder installers since 2009. However, since it is a COM component (e.g. a DLL) it is only available for installed versions of Thunder. Thunder on a USB memory stick will not be able to use AccessScripting functions.

AccessScripting allows you to call the Windows API for MSAA and other accessiblity information from VBScript. You can also include it as a reference in VB6 programs to provide a convenient way to call these functions. This document will assume you're using VBScript (i.e. that you're scripting the Thunder screenreader.)

The functions are all the standard Microsoft functions, so their purpose and operation is not detailed here. Look at MSDN. Some of them are amended for operation from VB Script.

There are two VB Script files in this distribution: check those out for examples of how to use the DLL. They are CurrentWindowTitle.vbs and WhatIsAtPosition.vbs.

Installation of AccessScripting

You must register AccessScripting.dll using regsvr32 or use Windows installer to make the appropriate registry entries. If you’ve installed Thunder then you will have AccessScripting installed.

Usage

 

Dim acc

Set acc = CreateObject("AccessScripting.AccessObj")

You can then use the AccessObj functions detailed below. Most wrap the usual Windows API function with the same name, like GetForegroundWindow: it returns the window handle using the GetForegroundWindow API call and returns you the value. However, because VBScript is not strongly typed, any function that takes arguments, like AccessibleObjectFromWindow, can't use the usual declaration. For these functions I have provided a "VBS" version, which will work slightly differently from the API norm.

Complete list of functions

Some of these work fine from VB Script as-is. The exceptions have VBScript versions, see below.

AccessibleObjectFromPoint

AccessibleObjectFromWindow

FindWindowEx

GetClassName

GetDesktopWindow

GetFocus

GetForegroundWindow

GetRoleText

GetWindowText

PostMessage

SendMessage

SetFocus

GetWindow

CreateWindowEx

IsWindowVisible

CloseWindow

DestroyWindow

ShowWindow

GetParent

VBScript versions of functions

Where a VBScript version exists, it has the same name as the normal API function with the three letters VBS appended to it. Some of the arguments are different, however.

AccessibleObjectFromPointVBS (x,y)

Returns the IAccessible object (if available) from the point provided in x and y. There is no way to get the child variant at present.

AccessibleObjectFromWindowVBS (hWnd)

Returns the IAccessible object (if available) from the window provided in hWnd. There is no way to get the child variant at present.

FindWindowExVBS (hwndParent, hwndChildAfter, lpszClass, lpszWindow)

As normal.

GetClassNameVBS (hWnd)

Returns the ClassName (e.g. "Notepad" for notepad.exe) specified by the window handle.

PostMessageVBS (hWnd, wMsg, wParam, lParam)

As normal.

SendMessageVBS (hWnd, wMsg, wParam, lParam)

As normal.

Debugging

There is one non-Windows function to help with debugging:

DebugPrint (s)

Writes string s to a text file on your desktop called accessscript.log. Creates if necessary, appends otherwise.