Understanding Functions

You can find three types of functions within the JAWS scripting language. The three types of functions include:

  • Built-in

  • User-defined

  • Event

Built-in functions are included with the JAWS scripting language and cannot be modified. User-defined functions are functions created for a specific task within a script file and can be modified. Event functions are part of JAWS and can be modified. A description of each type of function follows.

You can find complete descriptions of all built-in, user-defined and event functions that come with JAWS by reviewing the Freedom Scientific Developer Network function reference manual. You can download the manual from the following URL: https://support.freedomscientific.com/support/jawsdocumentation/FSDN

Built-in Functions

Freedom Scientific has provided >1,000 pre-defined functions within the JAWS scripting language. Each function performs a specific series of activities. You use these functions as the building blocks or instructions used to develop your scripts. For example, the RouteJAWSToPC() function checks the position of the JAWS Cursor and PC Cursor, makes the necessary calculations and moves the JAWS Cursor to the same point as the PC Cursor. All the activity is transparent to the JAWS user.

There are built-in functions that accomplish such tasks as: speaking messages, retrieving specific blocks of text, navigating the windows hierarchy and more. You can use the Insert Function dialog to insert any built-in function into the body of your scripts. You can also type the name of the function manually into the body of your script. If you choose to type the built-in function into your script manually, you must make sure you spell the name of the function correctly. You must also be sure the parameters the function requires are of the correct type and in the correct order.

User-Defined Functions

You can also use the script language to create or modify user-defined functions. The difference between a built-in function and a user-defined function is that you can modify user-defined functions while you cannot modify built-in functions.

A user-defined function is a self-contained module of scripting code that you develop to accomplish a specific task. A function is useful when you need to accomplish the same task from a variety of scripts and other user-defined functions. You can use the code of the function without having to write it multiple times. When you write the code once in a function, the time you need to maintain the code is reduced. Rather than modifying blocks of code in several different locations, you need only to make the changes in one place. After you have made the changes, re-compile any scripts or user-defined functions that call the newly modified function.

After you have created the function, you can call it from another script or function, and the task is performed. When the function completes processing, control is returned to the calling script or function where processing continues. You can find many examples of user-defined functions written by the script developers at Freedom Scientific in the default script file, Default.jss. To view the default script file in the Script Manager, do the following:

  • Press JAWSKEY + F2 to activate the Run JAWS Manager dialog.

  • Press S to select the Script Manager followed by ENTER to start the manager.

  • Press CONTROL + SHIFT + D to open the default script file.

Event Functions

The purpose of event functions is to cause JAWS to perform specific tasks automatically without waiting for you to initiate the action with a keystroke. Each event function is triggered by its corresponding windows event. For example, when an application writes new text to the screen, the new text event is triggered. This event causes JAWS to perform the NewTextEvent() function to determine what type of text was written to the screen. Event functions differ from user-defined functions in that you cannot create new event functions. However, you can modify the code in existing event functions.

All parameters for an event function are declared between the left and right parentheses in the function begin statement. When JAWS calls this event function, values are automatically passed for each of the parameters between the parentheses of the function call statement. You cannot add or remove parameters that an event function uses. However since values for each of these parameters are passed when the function is called, you can use the data provided by any of them when you need to customize the event function.

A list of some of the most important event functions follows:

  • AutoStartEvent()

  • FocusChangedEvent()

  • NewTextEvent()

JAWS performs the AutoStartEvent() Function when an application starts and any time the application becomes active. Any code that you do not place within a conditional statement is performed each time the function is called. You can use the AutoStartEvent() Function to initialize any global variables used by the application script file, speak an introductory message when the application starts or perform functions to initialize other settings used by the scripts and user-defined functions contained in the application-specific script file.

Using a global variable to determine if the AutoStartEvent() has occurred once is a useful technique. This technique is used when you want the AutoStartEvent() Function to perform a specific task the first time an application starts but not every time the application receives focus. :::

JAWS performs the FocusChangedEvent() function when focus moves between applications, dialogs, and dialog controls. Each time a focus change occurs, the FocusChangedEvent() compares the previous window with the current window and determines exactly what JAWS should speak.

For example, pressing TAB to move from control to control within a dialog box triggers the FocusChangedEvent(). In turn, JAWS performs the FocusChangedEvent() function to determine the type of change and what JAWS should speak. So when you move from an edit box to a combo box, JAWS speaks the associated prompt of the combo box, the text of "Combo box" and any value contained in the combo box.

JAWS performs the NewTextEvent() function when any new text is written to the screen. The function determines what type of text is written and what is spoken by JAWS. For example, pressing SHIFT + DOWN ARROW to select lines of text in your favorite text editor causes the NewTextEvent() to occur. JAWS in turn performs the NewTextEvent() function to speak the text as it is selected.

There are over 25 event functions JAWS calls automatically. You can review the code of each of these event functions by reviewing the default script file, Default.jss within the Script Manager.

  • Press JAWSKEY + F2 to activate the Run JAWS Manager dialog.

  • Press S to select the Script Manager followed by ENTER to start the manager.

  • Press CONTROL + SHIFT + D to open the default script file.

  • Press CONTROL + L to display the list of all scripts and functions contained within the file. Look for any function name that includes the word "event" in its name. When you find a function containing "event," press enter to move directly to that function.

Parameters and Returns

The simplest function does not receive or return any data to the calling script or function. A good example of a function that does not require any parameters or return any data is the SayLine built-in function. This function only speaks information and does not require any parameters or return any data to the calling script or function.

{#passing-parameters} ### Passing Parameters :::

A parameter is data you pass to a function. You pass a parameter at run time rather than include it as part of the code because the information may be different each time you call the function. A parameter can be any of the variable types used in the scripting language: handle, integer (int), object or string. You declare a parameter like a variable. Instead of declaring the parameter in the body of your function using the key word Var, you place the type and name of the parameter between the parentheses following the function name. When your function requires multiple parameters, you separate each parameter declaration with a comma. Some examples of function beginning lines containing parameter declarations follow:

Void Function SelectingText(Int nMode)
Void Function ProcessSelectText(Int nAttributes, String buffer)

You can also use the New Script dialog within the Script Manager to declare parameters. After you have entered all the general information about the new function, press CONTROL + TAB to move to the Parameters page of the New Script dialog. Press TAB to move to the New Parameter edit box and type the name of the parameter. You should follow the same rules for naming parameters as you would for naming variables. Press tab to move to the Description edit box and type in a description of the parameter. After you have entered a description for the new parameter, press tab until you reach the Available Types list box. Use your ARROW KEYS to select the type of data the parameter will contain. After you have chosen a parameter type, move to and activate the add button to add the parameter to your function.

You declare a function that requires a single string parameter as follows:

Void Function SayName (String sMyName)
SayFormattedMessage (OT_MESSAGE, sMyName)
End Function

In the above example, the SayName() function receives a string parameter, sMyName, from the calling script or function. The SayFormattedMessage() function uses the value in sMyName as its first parameter. You can call the SayName() function in one of the following ways:

::: {#example-1}

Example 1:

:::

Script SayMyName ()
SayName ("John")
End Script

Example 2:

Var
    String sMyName
Let sMyName = "John"
SayName (sMyName)
End Script

The data being passed in the sMyName parameter can either be enclosed in quotation marks as in the first example or declared as a variable in the calling script as in the second example. In either case, the function is expecting a string of data to be passed. When you insert the SayName() function into the above script using the Insert Function dialog, you are prompted to provide the data for the parameter just as if you were inserting one of the JAWS built-in functions.

::: {#returning-data}

Returning Data

:::

A return is data that is sent back from a function to the calling script or function after the function completes processing. You use the keyword, return, to return the data to the calling script or function. The calling script or function uses this returned data for further processing.

A function can return any of the following:

  • Void

  • Handle

  • Integer

  • Object

  • String

When you create a function, the return type is placed in front of the key word, Function, in the beginning line of the user-defined function. You select the return type from the New Script dialog within the Script Manager at the same time you create the user-defined function.

A function that requires no parameters and does not return any data to the calling script or function is declared as follows:

Void Function SpeakTheName ()
Var
    String sMyName
InputBox ("Enter the name:", "EnterName", sMyName) ; prompt the user For their name
If sMyName != cscNull Then ; determine If a value was entered in the input box
    SayFormattedMessage (OT_MESSAGE, sMyName)
Else
    SayFormattedMessage (OT_ERROR, "No name entered.")
EndIf
EndFunction

In the above example, the Void keyword precedes the Function keyword. The void keyword indicates that the function does not return any data to the calling script or function.

A function that requires no parameters and returns a string value is declared as follows:

String Function ReturnTheName ()
Var
    String sMyName
InputBox ("Enter the name:", "EnterName", sMyName) ; prompt the user For their name
Return sMyName ; Return the name To the calling Script or Function
EndFunction

In the above example, the String keyword precedes the Function key word. The String keyword indicates that the function returns a string value to the calling script or function.

Understanding Functions Exercises

The following exercises will give you practice in creating varying types of user-defined functions. Each exercise creates a user-defined function and a corresponding script to call the function. Each exercise will indicate the script file that should be used.

Basic User-Defined Function

The purpose of this exercise is to create a function that speaks a message and then types a string of text into an Notepad document. If you don't already have Notepad open, start Notepad and activate the script Manager from within Notepad. This should open the Notepad.jss script file that contains scripts from the previous exercises in this manual. If you run Script Manager from within Notepad and a blank file is opened, type the following lines at the top of the file:

; Script file For Notepad
; JAWS version 12.0
Include "hjconst.jsh"
Include "common.jsm"

First, create the function that speaks a message and then types a string of text into Notepad. Use the SayFormattedMessage function to speak the message and the TypeString function to type the text. SpeakGreeting Function Documentation:

  1. Script Name: SpeakGreeting

  2. Can be Attached to Key: not checked

  3. Synopsis: Speaks a message and types a string of text.

  4. Description: Speaks a message and types a string of text into an open Notepad text document.

  5. Category: none

  6. Function Returns: void

  7. Return Description: none

Void Function SpeakGreeting ()
    SayFormattedMessage (OT_MESSAGE, "Hello world, it's a great day For writing scripts.")
    TypeString ("Hello world, it's a great day For writing scripts.")
EndFunction

Once you have successfully compiled your function, you will need to create the script to call it. Use the InsertFunction dialog to insert the SpeakMessage function into the body of your script. This is the only statement that goes into the body of your script as the function performs the desired task. TypeAndSpeakGreeting Script Documentation:

  1. Script Name: TypeAndSpeakGreeting

  2. Can be Attached to Key: checked

  3. Synopsis: Calls the SpeakGreeting function to speak a message and type text.

  4. Description: Calls the SpeakGreeting function to speak a message and type text in Notepad.

  5. Category: none

  6. Assign to: CONTROL + SHIFT + G

Script TypeAndSpeakGreeting ()
SpeakGreeting ()
EndScript

Additional Practice: Refactor the greeting into a parameterized function (for example, pass time of day and audience), and create small test scripts to exercise variations. How would you structure reusable utilities shared across scripts?

User-Defined Function with a Single Parameter

The purpose of this exercise is to create a user-defined function that speaks a message using a string of text passed to it as a parameter. If you don't already have Notepad open, start Notepad and activate the script Manager from within Notepad. Before you create your user-defined function and related script, you need to create the message used by your function in the Notepad.jsm message file. You can open the file within the Script Manager and add your message. If you already have a Notepad.jsm message file, do the following to open the file in the Script Manager:

  1. Press CONTROL + O to display the Open File dialog.

  2. Type Notepad.jsm in the File Name edit box and press ENTER.

  3. If you have not previously created the Notepad message file, perform the following:

    1. Press CONTROL + N to display the New File dialog.

    2. The active control is a list of file types. Press M. to select Messages followed by ENTER. This will open an untitled message file in the Script Manager.

    3. Type the following text in the file:

      ; Message file For Notepad
      Messages
      EndMessages
      
  4. Press CONTROL + S to

    save the file. JAWS prompts you for the filename. Type Notepad in the File Name Edit box followed by ENTER.

Now you are ready to insert the individual message in the Notepad.jsm message file. To add the individual message, perform the following:

  1. Press UP ARROW until you reach the line entitled "Messages."

  2. Press END. to move to the end of the line.

  3. Press ENTER twice to create two blank lines.

  4. Type the following messages:

    @MsgName
    Hello world, my name is %1.
    @@
    ; message For missing or no name
    @MsgNoName
    You did Not ENTER a name.
    @@
    
  5. Press CONTROL + S to save the file.

  6. Press CONTROL + TAB to move back to the Notepad.jss script source file.

    After you have moved back to the Notepad.jss script file, be sure to include the Notepad.jsm file if you haven't done so already. Failure to do so will result in errors at the time of compilation.

Now you are ready to create the function that will speak your message and the script that calls the function. Your function should accept a single string parameter: the name passed to it from the calling script. Before the function speaks the message, check to make sure the parameter actually contains some text using an If statement. If there is no text in the parameter, speak an error message and use the return statement to exit the function. Use the FormatString function to combine the passed string parameter and the MsgName message you created above into one message. Next, call the SayFormattedMessage function to speak the message after it has been formatted.

SpeakTheName Function Documentation:

  1. Script Name: SpeakTheName

  2. Can be Attached to Key: not checked

  3. Synopsis: Speaks a message that includes a name.

  4. Description: Speaks a Hello World message using a string parameter passed to the function containing a name.

  5. Category: none

  6. Function Returns: void

  7. Return Description: none

After you have entered the information shown above into the General page of the New Script dialog, press CONTROL + TAB to move to the Parameters page. You will use this page to tell JAWS the name and type of the parameter the function needs to perform its task. When you reach this page, press TAB to move to the New Parameter edit box and add the following information:

  1. New Parameter: sName

  2. By Reference: not checked

  3. Description: String containing the name to be combined with the message and spoken.

  4. Available Types: string

After you have entered the information shown above, press ALT + A to activate the Add button and add your new parameter. Next, press TAB until you reach the Ok button. Press SPACEBAR to activate the button and close the New Script dialog.

Void Function SpeakTheName (String sName)
Var
    String sMessage
If sName == "" Then; check To make sure text was actually passed in the sName parameter
    SayFormattedMessage (OT_ERROR, MsgNoName); speak an error message
    Return; exit the Function
EndIf
Let sMessage = FormatString (MsgName, sName); format the message using the passed parameter
SayFormattedMessage (OT_MESSAGE, sMessage)
EndFunction

Once you have successfully compiled the SpeakTheName function, you will be ready to create the script that calls the function. Your script should assign a value to a variable called sName. Use the InsertFunction dialog to insert the SpeakTheName function. The variable sName will be the parameter to the SpeakTheName function.

SayName Script Documentation:

  1. Script Name: SayName

  2. Can be Attached to Key: checked

  3. Synopsis: Prompts you for a name to be spoken by JAWS.

  4. Description: Displays a dialog box that allows you to ENTER your name. JAWS then speaks a message containing the name you entered.

  5. Category: none

  6. Assign to: CONTROL + SHIFT + N

Script SayName ()
Var
    String sName
Let sName = "John"
SpeakTheName (sName)
EndScript

Additional Practice: Enhance the function to normalize/capitalize names, trim whitespace, and optionally speak phonetic hints. What input validation patterns will you adopt to keep callers simple?

User-Defined Function with Multiple Parameters

In the previous exercise, you created a function that accepted a string parameter containing your name. This parameter could hold only your first name or the combination of your first and last names. In this exercise, modify the SpeakTheName function to accept two string parameters. The original parameter of the function, sName, will be used to hold the first name. The second parameter created for this exercise, will hold the last name. Before you modify the function, you will need to change the content of the MsgName message contained in the Notepad message file. Press CONTROL + TAB to move from the Notepad.jss file to the Notepad.jsm file. In the Notepad.jsm message file, change the MsgName message to look like the following:

@MsgName
Hello world, my name is %1 %2.
@@

Press CONTROL + S to save your changes followed by CONTROL + TAB to move back to the Notepad script file. Now you are ready to modify the existing SpeakTheName function. To add an additional parameter to the function, perform the following:

  1. Move to the body of the SpeakTheName function.

  2. Press CONTROL + D to display the script Documentation multi-page dialog.

  3. Press CONTROL + TAB to move to the Parameters page. When you move to this page, the focus is placed in the Existing Parameters list box.

  4. Press TAB to move to the New Parameter edit box.

  5. Add the following information for your new parameter:

    1. New Parameter: sLastName

    2. By Reference: not checked

    3. Description: String containing the last name.

    4. Available Types: string

After you have added all the necessary information for the new parameter, press ALT + A to activate the Add button. This moves the focus back to the New Parameter edit box. Press TAB until you reach the Ok button. Press SPACEBAR to activate the button and close the Script Documentation multipage dialog. Move the Insertion point to the beginning line of the SpeakTheName function. It should now look like the following:

Void Function SpeakTheName (String sName, String sLastName)

You are now ready to modify the function to use the second parameter. First, you should add a second If statement to check if anything was passed in the sLastName parameter. Move your Insertion point to the line containing the EndIf statement. Press END. to move to the end of the line followed by ENTER to create a new blank line. Add the following statements to the function:

If sLastName == "" Then
SayFormattedMessage (OT_ERROR, MsgNoName); speak an error message
Return; exit the Function
EndIf

Second, you will need to add a third parameter to the call to the FormatString function. Move your Insertion point to the line containing the FormatString function and change it to look like the following: Let sMessage = FormatString (MsgName, sName, sLastName) ; format the message using the passed parameters After you modify the function to use the new parameter, compile the script file. Once you have compiled the file successfully, you will be ready to modify the script.

You can alter the messages used to speak the error messages when nothing is contained in either the first or last name parameters. To do this, you would add a second message to the Notepad.jsm message file for the last name and alter the contents of the message for the first name. Then you could use each message appropriately to speak the correct error message.

To modify the script you will need to add a second variable to hold the last name. Use a Let statement to assign a value to the variable and pass it as the second parameter into the SpeakTheName function. Modify the SayName script to look like the following:

Script SayName ()
Var
    String sLastName,
    String sName
Let sName = "John"
Let sLastName = "Doe"
SpeakTheName (sName, sLastName)
EndScript

Additional Practice: Extend the function to support an optional middle name and title, with robust handling when some parts are missing. How would you design the signature and defaults to remain clear?

User-Defined Function with a Return Value

The purpose of this exercise is to create a function that returns a value to the calling script. In the previous 2 exercises, you created a script and function that used 2 parameters to speak a message. The script used the Let statement to assign values to variables which were then passed into the function to speak the message. In this exercise, you will create a function that uses the InputBox function to prompt you for your first and last names. The function will then format the message to be spoken using the FormatString function. The FormatString function uses the MsgName message from the previous exercise along with the values for the first and last names entered using the InputBox function. Finally, the function returns the message as a string to the calling script. The InputBox function is a built-in function that displays a dialog box with an edit field for entering text. Using the parameters of the function, you pass strings of text to be used as the title of the dialog box and the prompt for the edit field. The third parameter should be a variable name that will contain the text entered when the OK button is activated in the dialog box. An example of the InputBox function follows:

InputBox ("Name entry", "Please enter your first name", \$sName)

In the example above, the title of the dialog box will be "Name entry." The text "Please enter your first name" will be the prompt for the edit box. sName will contain the text entered by the user. If no text is entered, sName will be empty.

  1. Script Name: RetrieveTheName

  2. Can be Attached to Key: not checked

  3. Synopsis: Prompts you for your first and last names.

  4. Description: Uses the InputBox function to prompt you for your first and last names.

  5. Category: none

  6. Function Returns: string

  7. Return Description: String of text containing the formatted message to be used by any of the Say functions.

String Function RetrieveTheName ()
Var
    String sFirstName,
    String sLastName,
    String sMessage,
    String sPrompt,
    String sTitle
Let sTitle = "Name Entry"
; retrieve the first name
Let sPrompt = "Enter your first name:"
InputBox (sPrompt, sTitle, sFirstName)
; retrieve the last name
Let sPrompt = "Enter your last name:"
InputBox (sPrompt, sTitle, sLastName)
; format the message
Let sMessage = FormatString (MsgName, sFirstName, sLastName)
; Return the formatted message
Return sMessage
EndFunction

Once you have compiled the function successfully, you will be ready to create the script that calls it. You will need to declare a single string variable to hold the message that is returned from the function. Your script should then call the function and store the returned message in the local variable. Finally, your script will use the SayFormattedMessage function to speak the message.

SpeakFormattedMessage Script Documentation:

  1. Script Name: SpeakFormattedMessage

  2. Can be Attached to Key: checked

  3. Synopsis: Speaks a message containing first and last names.

  4. Description: Speaks a message returned from the RetrieveTheName function.

  5. Category: none

  6. Assign to: CONTROL + SHIFT + M

SpeakFormattedMessage Script:

Script SpeakFormattedMessage ()
Var
    String sMessage
Let sMessage = RetrieveTheName (); call the Function To retrieve and format the message
SayFormattedMessage (OT_MESSAGE, sMessage); speak the message
EndScript

Additional Practice: Have the function return different messages based on runtime conditions (for example, verbosity or active application). How could you cache results or avoid recomputation if called frequently?