WHEN AND HOW TO USE FRAMES IN JAWS FOR WINDOWS

By Kenneth A. Gould


Preface

The Microsoft Word 8 version of this manual has been set up so that you are able to jump directly to any section shown in the Table of Contents.  To do this you must click on the page number to the right of each entry with the mouse pointer or JAWS cursor.  One way to accomplish this with the keyboard is as follows:

Find the section of interest in the Table of Contents by moving there with the PC cursor.
Route the JAWS cursor to the PC cursor.
Press the End key to move the JAWS cursor to the end of the line where the page number is.
Click the left mouse button by pressing the / key on the numeric keypad.  You will then jump automatically to the page of interest.
In some versions of JAWS, it may be necessary to move the JAWS cursor a few pixels to the right by pressing ALT+SHIFT+RIGHT ARROW before clicking on the page number.  You should try this if nothing happens when you click on the page number.

This manual also contains hyperlinked cross-references to chapters that are in the form See Chapter XX, where XX is the hyperlinked chapter number and to appendices that are in the form Appendix Y, where Y is the letter of the appendix.  You can jump directly to the chapter or appendix by clicking on the chapter number or appendix reference with the JAWS cursor.  After reading the section you have jumped to, you can return to your original position in the Table of Contents or to your original cross-reference at any time by pressing ALT+LEFT Arrow.


Table of Contents

1	Introduction	4
1.1	What Are Frames?	4
1.2	Whats in This Manual?	5
2	What Are Frames, and How Are They Used?	6
2.1	What is a Frame?	6
2.2	What Can I Do With a Frame?	6
2.3	Couldn't a Frame That I Create for One Part of an Application Interfere With Another Part?	7
2.4	When Should Frames be Used?	8
3	Our First Frames	9
4	The Frame Manager	12
4.1	The Frame Manager Panes	12
4.2	The Menus	13
4.2.1	File Menu	13
4.2.2	Frame Menu	13
4.2.3	View Menu	13
4.2.4	Help Menu	14
4.3	Frame Manager File Types	14
4.4	The Frame Properties Dialog	15
4.4.1	General Tab	15
4.4.2	Position Tab	16
4.4.3	Action Tab	17
4.4.4	Real Window Tab	18
5	Creating and Working With Frames	21
5.1	Creating a Frame	21
5.2	Editing and Troubleshooting a Frame	22
6	Advanced Frame Features and Capabilities	26
6.1	The New Text Function	26
6.2	Using Frames in Scripts and Functions	31
7	Appendix A: Answers to Homework Assignments	33
7.1	Answer to Homework Assignment #1	33
7.2	Answer to Homework Assignment #2	33
7.3	Answer to Homework Assignment #3	34
7.4	Answer to Homework Assignment #4	35
7.5	Answer to Homework Assignment #5	36
8	Appendix B: List of Frame-Related, JAWS Script Functions	38


1	Introduction

1.1	What Are Frames?

Its often very important to have the capability to read, quickly and easily, information that an application has written to the screen or to have that information read to you automatically when it first appears.  Of course, JAWS will frequently read this new information without any user intervention because it has very detailed scripts written for it that attempt to decide when some new information that has just appeared on the screen should be spoken.  Obviously, however, no screen reader can correctly decide, 100 percent of the time, when new text should be read.  Furthermore, you might also wish to read or reread some information that has been present on the screen for a while, and, obviously, JAWS is not going to know you want to do that.  Then there are occasional situations when JAWS does read some information that we would rather not hear, and in this case it would be very useful to be able to silence that unwanted verbiage.  Finally, sometimes we would like JAWS to be able to perform some activity automatically at particular points in an applications execution or when certain information appears on the screen.  Of course, these sorts of needs can usually be accommodated by writing customized scripts for the application of interest, but what we often need and want is a simple way to accomplish the tasks described above without the necessity of resorting to script writing.  That capability does, in fact, exist in JAWS, and the tool that can be used to do these things is known as a frame.

So, what is a frame?  As its name implies, a frame is a square or rectangular area of the computer screen that is defined by an upper left and a lower right corner.  These two coordinates completely define the boundaries of the frame since all of the sides of a frame are either vertical or horizontal.  You could think of a frame on your computer screen as being similar to a framed picture on a wall.  The four sides of the picture frame define an area that is distinct from the rest of the wall (that is, they contain the picture), and the four sides of a frame on your computer screen define an area containing some text or other information that we have decided is to be paid particular attention or treated differently from the rest of the screen.  The user can place a frame at any location on the screen and can make the frame as large or small as desired.  Then, as part of the definition procedure, the user can set up the frame to (1) speak all newly-written text that appears within its borders, (2) read only highlighted text that appears within its borders, (3) ignore all newly-written information that appears within its borders, (4) speak all information within its borders only when told to do so with a hot key, or (5) perform some specific action if any text or specific text appears on the screen or within the frame.  These capabilities, especially when combined with other features that will be described later, make frames in JAWS a very powerful tool that any user can employ to make applications much more speech friendly and informative.

This is a good time to mention that the term frame as used in JAWS for Windows is a very different beast from the type of  frame frequently encountered on an internet  web page.  While an internet frame serves to block off a particular portion of the web page for a particular purpose of the web page designer, this frame is predefined by that designer and has nothing whatsoever to do with JAWS screen reading functions.  So while the names are the same, there is absolutely no similarity between the two different kinds of frames.

1.2	Whats in This Manual?

We will cover the following topics in the remainder of this manual:

Chapter 2 - "What Are Frames and How Are They Used?" provides an introduction to the concept of frames and how they can be used to enhance screen reading.

Chapter 3 - "Our First Frames" shows how to create two simple frames so the reader can become familiar with the process and learn how easy frame creation can be.

Chapter 4 - "The Frame Manager" gives a detailed description of this utility and how it can be used to create, edit, and keep track of an application's frames.

Chapter 5 - "Creating and Working With Frames" describes in detail the procedures for creating and editing frames and how to troubleshoot frames that are not performing as expected.

Chapter 6 - "Advanced Frame Features and Capabilities" explains how to create custom JAWS script functions that can be triggered by frames and how to write scripts that use frame-related functions.

2	What Are Frames, and How Are They Used?

2.1	What is a Frame?

As we described briefly in the introduction, a frame is a rectangular area of the screen that we have defined by a top, left coordinate and a bottom, right coordinate, where coordinates are given as pixel locations.  For example, we might have a frame whose top, left corner is (50, 100) and whose bottom, right corner is (150, 250).  This means that the upper, left corner of the frame is 50 pixels from the left side of the screen and 100 pixels from the top, while the lower, right corner is 150 pixels from the left side of the screen and 250 pixels from the top.  So how about the upper, right and lower, left corners?  Well, since all frame sides are either horizontal or vertical, this means that the top, right corner is forced to be at (150, 100), and the bottom, left corner is forced to be at (50, 250).  This gives us a frame that is 100 pixels wide and 150 pixels high.  A pixel, by the way, is a small dot used to display information on the computer screen.  If, for example, you are running your computer at a resolution of 800 by 600, you have 800 pixels of resolution across the screen and 600 pixels of resolution from top to bottom.  Thus, the 100 by 150 pixel frame we just described represents a small rectangle within the larger 800 by 600 rectangle of an entire screen set for this resolution.

Frames can be used to enclose areas of the screen to which we wish to pay particular attention, and the user can place as many frames on the screen as necessary.  A frame can be as large as the entire screen or as small as one pixel by one pixel.  While it generally doesnt make much sense to make a frame smaller than one character in width and height, one can do so if desired.  You may need several frames to take care of the needs of a particular application, and these frames may overlap with no adverse consequences.  The techniques for defining a frame will be discussed later.  (See Chapter 5.)

2.2	What Can I Do With a Frame?

Frames are used for five specific purposes.  These are as follows:

To define an area of an applicationn's window within which all newly-written text will be spoken automatically.

To define an area of an application's window within which only highlighted, newly-written text will be spoken automatically.

To define an area of an application's window within which newly-written text will be ignored and not spoken.

To define an area of an application's window that can be read at any time with a hot key.

To define an area of an application's window that can be used to trigger a predefined, script function to run automatically when any text or certain text appears on the screen or within the frame.  This script function must be written in advance by the user and can be used to perform any activity that can be accomplished with the JAWS script language.

These options give us a tremendous amount of control over the reading of information at various locations on the screen.  We all know that we can control the screen echo for the entire application screen by toggling screen echo from none to highlighted to all either by using the accelerator key INSERT+S or by using the accelerator key INSERT+V, S.  However, this changes the screen echo for the entire screen.  Frames allow us to control the screen echo for a small area of an application's window and to have different echo levels for different parts of the screen, all at the same time.  Thus, if we choose the first option mentioned above, the echo level within the frame, which we will call the "Frame Echo", will be all, irrespective of the general setting for screen echo at that time.  This means that anything written within that frame will be spoken as soon as it appears.  If we choose the second option, frame echo will be set to highlighted, and only highlighted text will be announced automatically within the frame.  The third choice will set frame echo to none, and nothing written to the screen within that frame will be read automatically.  If we choose the fourth option, the frame echo level will not differ from what the echo level is for the entire screen, but we can read the contents of that frame at any time by using a hot key that we assign at the time we create the frame.  Any of the first three types of frames can be used in conjunction with option 5, the capability of having a frame trigger a user-defined script function to cause JAWS to do specific tasks.  This is considered an advanced frame feature and will be covered later.  (See Chapter 6.1.)

2.3	Couldn't a Frame That I Create for One Part of an Application Interfere With Another Part?

Let's say you create a frame somewhere in the middle of your application's window, and that frame is set to speak all newly-written text.  Then, suppose you decide to drop down one of the application's menus, and that menu happens to pass right through the middle of your echo all frame.  One might naively expect this to cause a problem for the normal reading of the menu because one would presume that the frame would cause all newly-written text to be spoken as the user employed the cursor movement keys to navigate through the menu.  This would mean that both the newly-highlighted menu option and the one being unhighlighted would be spoken since both items must be rewritten to the screen for them to show up in their new colors.  Such a situation would cause confusion since the user would not be certain which menu option was currently highlighted.  Fortunately, JAWS is smart enough not to cause these kinds of problems.  As will be discussed later, JAWS assigns each frame to a particular window when it is created, and only text written to that exact window will be read or ignored by that frame.  (See Chapter 4.4.4.)  Since we did not create our hypothetical echo all frame while we were in the menus, the frame will pay no attention to text written to the menu window, and the menus will read correctly.  This principle is used for all frames, so a particular frame will only influence the speaking of text for the window with which it is associated.

2.4	When Should Frames be Used?

According to the discussion above, frames can be used to monitor a screen area for text to be read, cause text in an area to be ignored, or monitor the screen for activity that is to trigger a JAWS script function.  These are the most common applications of frames and can be used for reading such things as status lines, informational dialogs, and changing status messages or for ignoring repetitive text such as clocks or flashing text.  Many of these tasks can also be done with scripts, so how does one decide whether to use a script or a frame for a particular reading job?  Obviously, if the user has little or no knowledge of the JAWS scripting language, then frames will be the only choice.  However, if the user can write scripts, a choice of which method to use will have to be made.  In general, the job of simply reading a particular, small area of an application's window can easily be done with either method, so if one is writing some simple configurations for personal use, either technique is satisfactory.  Automatic monitoring of a particular screen area to read or ignore text automatically can also be done either with frames or scripts, but the script approach is rather tricky and complicated.  So, for this task, frames would appear to be the method of choice.  Finally, the use of monitoring frames to invoke JAWS script functions is the trickiest technique to simulate with scripts, so this type of job is probably always best left to a well-designed frame.

There is one very real limitation to the use of frames of which users should be aware.  Since a user defines a frame while using a particular screen resolution and window size, the frame that is created may only work for other users if they are working at the same resolution and window size.  While some frames can sometimes tolerate modest changes in window size and still continue to function, it is best to assume that a frame will fail to perform properly at other resolutions and window sizes.  Therefore, if a user is creating configurations for general use and not just for use on one computer, there are some precautions that should be taken.  Whenever possible, scripts that are insensitive to resolution or window state should be used to perform simple, manual reading functions.  Monitoring that cannot be conveniently done without frames can still be accomplished by using frames, but the person creating the configurations should provide application notes telling the other users what resolution they should be using and whether their application window should be maximized or restored.  Additionally, providing instructions on how to create replacement frames for use at other resolutions would also be an excellent idea.

3	Our First Frames

To give you an idea how simple it is to create frames and how useful they can be, let's go through the generation of a couple of very useful ones so you can become acquainted with the process.  For the moment, just follow the steps as they are outlined below.  We'll go through the meaning of what you're doing in more detail later when we discuss the Frame Properties Dialog and show you how to edit the frames to make them even more powerful.  (See Chapters 4.3 and 5.)

For the first example, we'll create a frame that tells you what line you're on if you're running the JAWS Script Manager editor.  The steps are as follows:

Press CONTROL+SHIFT+0 (on the numeric row, not the keypad) to open the Script Manager and load the default script file, Default.JSS.  You should find yourself in an edit window of the Script Manager with the default script file loaded as the document.  You can verify this by pressing INSERT+T to hear the title of your current window.

Turn on the JAWS cursor and route it to the PC cursor by pressing INSERT+NUMPAD Minus.  Then press PAGE DOWN followed by HOME to take you to the beginning of the last line of the window.  Performing a SayLine by pressing INSERT+NUMPAD 8 should say "For help, press F1 Line: 1 Total Lines: xxxx", where xxxx is the total number of lines in your particular copy of the default script file.

Move the JAWS cursor to the right until it is on the L of Line.  Then press CONTROL+SHIFT+LEFT BRACKET.  (The left bracket key is just to the right of the letter P.)  You should hear the words, "Setting frame top, left corner".  This means that JAWS is setting the location of the letter L as the top, left corner of the frame.

Now move the JAWS cursor to the right until it is on the first letter T of Total.  Then move it back to the left by one space.  Then press the key combination, CONTROL+SHIFT+RIGHT BRACKET.  (The right bracket key is just to the right of the left bracket key.)  You should hear the words, "Setting frame bottom, right corner".  Thus, the bottom, right corner of the frame will be just before the letter T and should include all line numbers.

Immediately after the last message, you will hear the words, "Frame Manager, JSCRIPT Dialog, General Page, Frame Name, Edit".  What has happened is that, after entering the frame's bottom, right corner, a new program called the Frame Manager has opened automatically and placed you in the first field of a dialog used to enter information about your frame.  This first field of the dialog is where you enter the name of your frame.  Let's call it LineNumber.  Type this name into the field using a capital L and a capital N so JAWS will pronounce it properly.  Do not put any spaces in the name since frame names may not contain spaces.  You must enter a name in this field before you can tab to other fields in this dialog.

Press TAB to move to the Synopsis field.  We need to enter a brief description of what our frame does, so type in "Speaks line number".

Press TAB to move to the description field and type in "Announces line number of current script file".  This is a more detailed description of what the frame does.

Press the TAB key, and you will hear the words "Echo, JFW Screen Echo, radio button checked, four of four".  This is the echo level we want, so no entry is needed here.

Press the TAB key again, and you will hear "Save in frame file, JSCRIPT, radio button checked, 1 of 2".  This setting is also correct as is.

Press the TAB key again, and you will hear "Assign to".  This is where you tell JAWS what key will speak the frame for you.  Press CONTROL+1 on the numeric row to assign the frame to that key combination.

Press the TAB key three times until you hear the words, "General Tab".  You are now in the tab heading of a multipage dialog.  Press the RIGHT ARROW key three times until you hear "Real Window Tab".  Then press the TAB key one more time until you hear "Name, Edit, JAWS Script Manager - [Default.JSS]".  You are now in an edit field that contains the name of the window in which this frame is to be active.  Delete everything after the word "Manager".

Press the TAB key repeatedly until you hear "OK".  Then, press the ENTER key to accept all the frame information you have entered.  You will return automatically to the Script Manager edit window you were in before you started the frame creation process.  If you press CONTROL+1, you should hear JAWS speak the line number you are positioned on.  Press DOWN ARROW a few times, and then try CONTROL+1 again.  You should hear the new line number you've moved to.  How about that!  Now you can read the line number any time you want without having to poke around on the screen to find it.

For our second frame, let's try something a little more advanced.  What we're going to do is create a frame in WordPad around the text window and attach that frame to the CONTROL+1 key combination.  If we do this correctly, we should hear the new page of information spoken to us automatically when we use this key combination.  We will be able to read our document page by page, without the necessity of moving any of our cursors.  Follow the steps as shown below:

Open the WordPad application.

Route your JAWS cursor to the PC cursor using INSERT+NUMPAD MINUS.  This should place the JAWS cursor at the top, left corner of the edit window.

Press CONTROL+SHIFT+LEFT BRACKET twice, as quickly as you can.  This special key press tells the Frame Manager that you want the boundaries of the frame to coincide with your current window.  Since the JAWS cursor is positioned in the edit window, the upper, left corner of the frame will be at the upper, left corner of the edit window, and the bottom, right corner of the frame will be at the bottom, right corner of the edit window.  This will create a frame that surrounds all of the text in the edit window.  JAWS will immediately take you into the Frame Manager without the necessity of pressing CONTROL+SHIFT+RIGHT BRACKET.

You will now be in the Frame Name edit field.  Type in "TextWindow" without any spaces, capitalizing the T and the W.

Tab over to the Synopsis field, and type "Surrounds text area".

Tab to the Description field, and type "Speaks the new screen of document text".

Tab over until you reach the Assign To field, and press CONTROL+1.

Press the TAB key three times until you hear the words, "General Tab".  You are now in the tab heading of a multipage dialog.  Press the RIGHT ARROW key three times until you hear "Real Window Tab".  Then press the TAB key one more time until you hear "Name, Edit, Document - WordPad".  You are now in an edit field that contains the name of the window for which this frame is to be active.  If there is any text before the word WordPad, delete it.

Press the TAB key repeatedly until you hear "OK".  Then, press the ENTER key to accept all of the information you have entered.

You will now be returned to the edit window of WordPad.  Load any convenient document, and then press CONTROL+1.  You should hear all of your document's text that is currently on the screen, without the necessity of having to move any of your cursors.  Press the PAGE Down key to bring up a new screen of text, and then try CONTROL+1 again.  You should hear the new screen of information read to you.

You should now be getting a pretty good idea of how simple it is to create frames and how useful they can be.  In our next chapter, we'll go over the Frame Manager so you can learn about all of its features and capabilities.  After that, you will have a thorough understanding of what this utility can do and how it can help you create, edit, and manage your frame files.

4	The Frame Manager

The Frame Manager is a utility that allows you quick and easy access to your frame files and the frames they contain.  From here you can review the frames present in each frame file and edit any of those frames, if desired.  There are three ways to open the Frame Manager:

From the JAWS window by selecting Frame Manager from the Utilities menu

From within any application by Pressing the key combination, INSERT+9 on the numeric row

From within any application by pressing the key combination, INSERT+F2 followed by F and ENTER

Below is a description of the various parts of the Frame Manager and how they are used to manage your frame files.  You can follow along with these descriptions by using one of the above methods to open the Frame Manager now.

4.1	The Frame Manager Panes

The main Frame Manager window consists of two areas or panes arranged side by side on your screen.

The left pane is a list view that contains an alphabetically-arranged list of all of your frame files.  The names are taken from the actual application names of the programs with which they are associated.  You can arrow up and down through the list or start typing the name of the frame file to have the highlight move directly to that file.  Once you have located the file of interest, press the TAB key to move to the right pane.  You can move back to the left pane by pressing the TAB key again.

The right pane consists of a list view of the frames contained within the frame file you highlighted in the left pane.  This ListView consists of three columns for each row.  The titles of these columns and what they contain are described below:

Frame Name - This column contains the name of the frame that was entered when the frame was created.

Window or Screen - This column indicates whether the frame is being referenced to a particular window or the entire screen.  For a complete description of referencing frames to a window or the screen, see Chapter 4.4.2.

Frame Echo - This column lists the echo level of the frame, either Silent, Highlighted, All, or JFW Screen Echo.  For a complete description of frame echo levels, see Chapter 4.4.1.

You can move through the list of frames with the up and down arrow keys or by starting to type the name of the frame.  The Frame Manager will then jump to the first frame whose name begins with the first letter you type and will highlight the name of the frame you want as soon as you have entered enough letters to identify it.

4.2	The Menus

Here is a brief description of the selections available under the various pull-down menus of the menu bar of the Frame Manager.  Some of the items discussed have accelerator keys that are listed in the menus and that you will probably want to learn.

4.2.1	File Menu

Delete: Deletes the currently-highlighted frame file.
Open Default File: Moves the highlight in the left pane to Default, the default frame file.
Change Working Directory: Opens a dialog that allows the user to browse for other directories containing frame files and to make another such directory the active directory.  One could use this to examine frame files on, for example, a floppy disk or in a different JFW directory from the currently-active JFW directory.
exit: Exits the Frame Manager

4.2.2	Frame Menu

Delete: Deletes the frame currently highlighted in the right pane of the Frame Manager.
Details: Opens the Frame Properties Dialog.  This dialog is fully described below.  (See Chapter 4.3.)
Rename: Allows the user to rename the currently-highlighted frame.
Options: This menu item opens the Options Dialog.  From here one can check or uncheck two options.  The first provides for a warning message to be spoken any time the user is about to modify a frame in the Frame Properties Dialog, and the second turns on or off the listing of the complete path to the currently-active frame directory in the Frame Manager's title bar.

4.2.3	View Menu

Status Bar: Checking this option displays a status bar at the bottom of the window.  This status bar contains a description of the currently-highlighted frame if the focus is in the right pane.  This synopsis is taken from the Synopsis field of the Frame Properties Dialog.  If the Frame Manager window is in its restored state, one can read the status bar synopsis by pressing the key combination INSERT+PAGE DOWN.  This allows the user to review the purpose of the frame without having to open the Frame Properties Dialog.  If no synopsis was entered when the frame was created, no information will appear in the status bar.

4.2.4	Help Menu

Help Topics: Invokes Windows help topics about the Frame Manager.

About: Displays information about the Frame Manager program.

4.3	Frame Manager File Types

When you create frames with the Frame Manager, the information you enter is stored in two files.  These files have the same main name as the application you are in when you create the frames, but they have two extensions that identify them as containing information about frames.  The two extensions are listed below, along with the types of information their files contain:

JFF - This is the JAWS Frame File and contains all of the information entered in the Frame Properties Dialog, with the exception of the Synopsis and Description data.  This file is in text format and can be edited with a text editor such as Notepad, if desired.

JFD - This is the JAWS Frame Documentation file and contains the information entered in the Synopsis and Description fields during frame creation.  This file is in text format and can be edited with a text editor such as Notepad, if desired.

Thus, an application named MyApp.EXE would have two frame files called MyApp.JFF and MyApp.JFD.  When you load or set focus to an application, JAWS will check whether there are any .JFF and .JFD files with that application name and will load them automatically, if they exist.

It is important to understand how JAWS manages frame files.  In addition to the frame files that exist for each application, there may also be a default frame file set, Default.JFF and Default.JFD.  These frame files are loaded automatically when JAWS first loads and remain active at all times, irrespective of what application is currently running.  Any frames that the user wishes to have available in all applications such as a frame to surround and read the clock on the Task Bar should be stored in the default file set so it will always be active.  Frames stored in application frame files will be swapped in and out of memory as you switch from application to application.  These application frame file sets are available only as long as their particular is the active application.

4.4	The Frame Properties Dialog

As has been mentioned previously, the Frame Properties Dialog is used to create and, subsequently, edit frames.  This dialog is invoked automatically when a user uses the CONTROL+SHIFT+LEFT BRACKET and CONTROL+SHIFT+RIGHT BRACKET keys to mark a new frame's boundaries, but it can also be invoked from within the Frame Manager by using the menus or simply by pressing the ENTER key when any frame name is highlighted.  There are four pages to this multipage dialog, and the contents of each is described in the following sections.

4.4.1	General Tab

The General Tab contains miscellaneous information about the frame.  The entries in this tab are as follows:

Frame Name - This is where you enter the name of your frame.  Try to use a name descriptive of what the frame surrounds or reads.  If you use several words concatenated together, start each word with a capital letter so JAWS can pronounce it properly.  Spaces are not allowed in a frame name.  If you choose a name that has already been used, JAWS will warn you and give you an opportunity to change the name.  You must fill in the name field before you can see the rest of the fields in this dialog.

Synopsis - This is where you enter a brief description of what the frame surrounds or is supposed to read.  The information you enter is used in both the status bar of the main Frame Manager window and to provide a help message for any hot key assigned to this frame when JAWS is in Keyboard Help mode, so try to make the synopsis meaningful and clear.

Description - This is where you enter a more detailed description of the purpose and use of this frame.  The information you enter is used to provide a detailed help message for any hot key assigned to this frame when JAWS is in Keyboard Help mode, so try to make the description meaningful and clear.

Echo - This control is a group of four radio buttons that allows the user to specify the echo level for the frame.  The choices are (1) Silent, to suppress the reading of all information written within the borders of the frame, (2) Highlighted, to cause only highlighted text within the borders of the frame to be read, (3) All, to cause all text written within the borders of the frame to be spoken, and (4) JFW Screen Echo, to have the information within the frame behave exactly the same as that on the rest of the screen.  The user can arrow up and down to select the desired echo level.  The default for each new frame is JFW Screen Echo.

Save in Frame File - This control is a set of two radio buttons that allows the user to choose whether the frame should be saved in the default frame file or the application frame file.  This control is only accessible when a frame is first created.  It is not available when editing a previously-defined frame.

Assign To - If the user wishes to be able to read a frame manually, a hot key can be entered here by pressing and then releasing the desired key combination.  A hot key can be assigned to any frame, irrespective of the echo level that was chosen.  The hot key will read the frame's contents, even for a frame with a silent echo level.  If the user attempts to select a key combination already assigned to another frame or JAWS function, a warning message will be given, and the user can then either select a different key assignment or proceed with the original one.  Proceeding with the original choice will eliminate the prior assignment.

4.4.2	Position Tab

The Position Tab contains size and location data for the frame.  The following are the options available from this tab.  All of these fields are filled in automatically when a new frame is created, but the user may wish to alter the information to make a frame larger or smaller or change its position on the screen.

Distance From Left or Right Side - The first part of this control is a pair of radio buttons that allows the user to decide if the frame is to be referenced to the left side of the window or screen or to the right side of the window or screen.  Generally, it is better to reference the frame to the side of the window or screen to which it is closest.  See the paragraph at the end of the section on the Position Tab for an explanation of why this is so.  The Frame Manager will always pick the left side by default when a frame is created, but the user is free to choose a different side by arrowing through the two radio button choices.  After choosing the side, the user arrows to an edit field that contains the number of pixels from the side chosen to the beginning of the frame.  This number will change automatically when the user changes whether the frame is referenced to the left or right side.  The number can be edited manually by the user to shift the position of the frame to the right or left.

Width - This is an edit field containing the width of the frame in pixels.  The user can decrease the number to make the frame narrower or increase it to make the frame wider.

Distance From Top or Bottom Edge - The first part of this control is a pair of radio buttons that allows the user to decide if the frame is to be referenced to the top edge of the window or screen or to the bottom edge of the window or screen.  Generally, it is better to reference the frame to the edge of the window or screen to which it is closest.  See the paragraph at the end of the section on the Position Tab for an explanation of why this is so.  The Frame Manager will always pick the top edge by default when a frame is created, but the user is free to choose a different edge by arrowing through the two radio button choices.  After choosing the edge, the user arrows to an edit field that contains the number of pixels from the edge chosen to the beginning of the frame.  This number will change automatically when the user changes whether the frame is referenced to the top or bottom edge.  The number can be edited manually by the user to shift the frame up or down.

Height - This is an edit field containing the height of the frame in pixels.  The user can decrease the number to make the frame shorter or increase it to make the frame taller.

Relative To - The final control in this tab is a pair of radio buttons that allows the user to choose whether the frame is to be referenced to the window that contains it or to the entire screen.  The choice made in this control will determine whether the other controls in this tab announce themselves in relation to the window or screen.  For example, if you change from the default choice of window to the screen, the first control in this tab will change its name to reflect distances from the left or right side of the screen instead of the window.  The numbers that give the distances from the boundaries of the window will also change automatically to give the correct distances from the boundaries of the screen.  When we speak of a frame as being referenced to a window, we mean the real window that contains it.  A real window is defined as a window that has a title.  So a frame would not be referenced to such things as a status bar or menu bar, even though these are technically, windows.  In general, almost all frames should be referenced to the window rather than the screen for a couple of very good reasons.  First of all, frames referenced to a window are somewhat more portable when transferring frame files to users with different screen resolutions.  Second, frames normally limit their functioning to the window for which they were created, as discussed below in the section on the Real Window Tab.  This prevents frames from functioning outside of the window for which they were designed.  Changing the frame to be relative to the screen will defeat this feature of frame performance.  Nevertheless, occasionally, for reasons that will be discussed in the section below on the Real Window Tab, a frame simply will not function if referenced to a window.  If that happens, the user can experiment with relating the frame to the screen to see if it can be made to perform that way.

It is worth taking a moment to discuss the benefits of referencing the frame to the edges of the window to which it is most closely located.  To explain this, let's use as an example a frame created around a status bar located at the bottom of a window.  Let's say you create the frame while the window containing the status bar is restored and, further, that the distance of the frame from the top edge of the window turns out to be 200 pixels.  This will be the number automatically inserted into the Position Tab when the frame is created because, as mentioned above, the Frame Manager always defaults to referencing the frame to the top edge and left side of a window.  Now, when the sate of the window containing the status bar is changed from restored to maximized, the distance of the status bar from the top edge of the window will increase greatly, say to 350 pixels.  When one tries to read the frame, one will find that the status bar is no longer present at the original 200 pixel location and, thus, will not be read. On the other hand, the status bar is always zero or just a few pixels from the bottom edge of the window irrespective of whether the window is restored or maximized because the status bar is always at the bottom edge of the window.  Therefore, if one had changed the referenced edge of the frame to the bottom of the window, it would have been much more likely to be read properly after the window state was changed.  Thus, referencing a frame to the closest side and edge of a window make its utility much more general when used with different window states or screen resolutions.

4.4.3	Action Tab

The Action Tab is used to determine the speaking priority that JAWS uses when reacting to text written to more than one frame simultaneously and whether or not to have special text processing for your frame.  There are two controls on the Action page, as described below:

Processing Priority - This control is where the user enters numbers to prioritize the speaking of multiple frames.  It is possible to have more than one frame active for an application at a given time.  If text is written to more than one of these frames simultaneously, this control gives the user a way to determine which frame will be spoken first.  Priorities must be between 1 and 10 with 1 being the highest priority.  A frame with a processing priority of 1 will be processed before a frame with a priority of 2.  If your frames are not speaking in the desired order, try lowering the priority number of the frame you wish spoken earlier or raising the number of the frame you wish spoken later.

New Text Function - This control provides the user an opportunity to perform special processing of the text written to the frame.  When new text is written to the screen, the decision of whether to speak this text is usually handle by a JAWS script function called the NewTextEvent function.  This function analyzes the current echo level of the screen, whether the text is highlighted, and whether the text is associated with a frame and, if so, the echo level of that frame.  By creating a special function and entering the name of that function in this field, the user can choose to have the frame's text handled by this alternative function.  This is an immensely powerful tool because it allows the user to bring into play any of the capabilities of the JAWS scripting language when new text or specific new text is written to a specific area of an application's window.  Obviously, using this capability requires a thorough knowledge of the JAWS scripting language.  (You can learn more about the JAWS scripting language in the manual, Everything You Always Wanted to Know About Writing JFW Scripts But Didn't Know Whom to Ask by Kenneth Gould.  This manual can be downloaded at the Henter-Joyce web site or by clicking on the address, http://www.hj.com.)  Because this topic is very advanced and requires a more lengthy discussion, it is covered in much more detail below.  (See Chapter 6.1.)

4.4.4	Real Window Tab

The Real Window Tab contains information about window names and classes associated with the frame and about text that you may wish to have present on the screen or in the frame to have the frame active.  The controls available in this tab are described below:

Name - This field contains the name of the real window that contained the JAWS cursor or invisible cursor at the time either one was being used to define the boundaries of the frame.  Recall that a real window is a window that has a title.  Thus, for example, if you are reading this document in Microsoft Word and use the key combination INSERT+T to hear the window title, the phrase you will hear is "Microsoft Word - FrameManual.doc".  If you create a frame in this window and then look at the Name field of the Real Window Tab, this is what you will find was entered automatically.  You should always check this field during frame creation to make sure the entry is correct.  If you find that a frame is not reading properly, check this field to make sure the name corresponds to the real window containing the frame.  If you cannot find any other explanation for a frame's failure to perform properly, try deleting the name in this field to see if that solves the problem.  In any case, you should always shorten the name to remove any document names from the field.  Thus, for example, the above title should be shortened to "Microsoft Word".  Please take careful note of this advice because it is extremely important.  If you do not remove a document name from a name in this field, the frame will only work when that particular document is loaded.  Removing the document name will allow the frame to work irrespective of what document is active.  Also, the term document is used here quite generically to include all specific information added to a real window title to describe what the window currently contains.  For example, an FTP client's real window title might include the name of the site it is currently connected to, and an e-mail program might contain the name of the current mailbox.  These types of information must be deleted from the name field if the frame is to work under all circumstances.

Class - This field contains class information about the window containing the frame.  This information is extracted automatically during frame creation by JAWS and entered in this field.  This data, along with that in the Name field, allows the frame to operate only in the correct window.  There are some situations, however, when this information may have to be modified by the user for correct frame performance.  Some window class data extracted by JAWS, notably certain Visual Basic window class data, consists of long lists of numbers that can change partially every time a program is used.  This has the result of causing a perfectly-configured frame to fail to operate correctly when an application is used subsequent to the session when the frame was created.  This can be quite confusing since the frame worked properly when it was first created.  If this situation occurs, check the class field to see if it consists of a long string of numbers.  If so, try creating a test frame in the same window, and check the class data for the new frame.  If it is similar to the previous frame but differs in the last few digits, remove these ending digits from the first frame's class, and try using the frame again.  This may restore the frame's proper functioning.  The goal is to remove all of the digits that are not the same each time the application is used.

Window Must Contain Text - If you wish the frame to operate only when certain text is present in the window, you can enter the text string in this field.  The string you enter will prevent the frame from automatically speaking or muting all text when the particular string is not present within the window.  You might, for example, create a frame around the status line of a program but only want the frame to announce the contents when a particular operation is finished.  To do this, choose the text that appears in the window when the operation is complete.  Text entered in this field does not prevent a user-defined hot key from speaking the frame contents, even if the text is not present in the window.

Frame Must Contain Text - This control is exactly like the previous one, except that the entered text must be within the confines of the frame for the frame to perform its automatic functions.  This feature is very powerful because it requires the presence of a particular string at a particular location for the frame to perform.  One could, for example, construct a frame around one word and then place that word in this field.  By then creating a customized New Text function and placing that function's name in the New Text Function field of the Action Tab, one could create a situation wherein JAWS would perform a particular scripted function when a certain word appeared at a specified location on the screen.  For more information on such procedures, see Chapter 6.1.

5	Creating and Working With Frames

Now that we have learned about the various dialogs and menus in the Frame Manager and what they do, it's time to learn the procedures for creating and editing frames.  These topics are covered in the following two sections of this chapter.

5.1	Creating a Frame

The following steps outline the procedure normally used to create a frame in your application:

Identify and Locate the Area to be Framed - If you wish to place a frame around an area of an application's window, the first step is to find that area.  To do this, switch either to the JAWS cursor by pressing NUMPAD MINUS or to the Invisible cursor by pressing that key twice quickly.  Once you have activated either of these cursors, you should route it to the current location of the PC cursor by pressing INSERT+NUMPAD MINUS.  Then you can can move around on the screen in the usual way to locate the area to be framed.

Mark the frame Boundaries - Once you have found the area to be framed, you can use either the JAWS cursor or Invisible cursor to mark the top, left and bottom, right corners of the frame.  First, place either cursor on the location for the top, left corner and press the key combination, CONTROL+SHIFT+LEFT BRACKET.  (The left bracket key is located directly to the right of the letter P.)  You will hear JAWS speak the phrase, "Setting frame top, left corner."  Second, move the JAWS or Invisible cursor to the position you wish to mark as the bottom, right corner, and press the key combination, CONTROL+SHIFT+RIGHT BRACKET.  (The right bracket is located directly to the right of the left bracket key.)  You will hear JAWS speak the phrase, "Setting frame bottom, right corner".  Immediately after that, JAWS will open the Frame Manager and place you in the Frame Properties Dialog so that you can enter the characteristics for your new frame.  If you decide you do not want to proceed with frame creation at this time, simply press ESCAPE, and you will be returned to your application.  There is a little trick you can use if you know in advance that you want the frame you're creating to cover an entire window.  If you wish to create a frame that surrounds the entire window that currently contains the JAWS or Invisible cursor, press the CONTROL+SHIFT+LEFT BRACKET key combination twice quickly instead of just pressing it once.  Instead of waiting for you to press the CONTROL+SHIFT+RIGHT BRACKET keys to set the bottom, right corner, JAWS will immediately open the Frame Manager and place you in the Frame Properties Dialog.  The top, left and bottom, right corners of the frame will have been set to the top, left and bottom, right corners of the window.

Complete the Entries in the Frame Properties Dialog - Fill out all of the fields as required and change any of the default entries that JAWS has made that you believe are not set as you would like them.  For more information on filling out the fields of this dialog, see Chapter 4.4.

It sometimes happens that an application contains a status line that displays information about a particular menu or control when the JAWS cursor (mouse pointer) is located on that menu or control.  You might wish to create a frame around that status line so you could read it with a hot key or have it announced automatically every time it changes.  The problem here is that, if you move the JAWS cursor to the status line so you can create the frame, the status line text will disappear as soon as you move the JAWS cursor off of the item that generates the status message.  To cope with this situation, use the Invisible cursor instead of the JAWS cursor to create the frame boundaries.  Since you are not moving the JAWS cursor, the status message will remain unchanged.

Now that we've covered frame creation and documentation in detail, it's time to practice some of this information.  We'll have a number of homework assignments throughout the remainder of this manual that will help you do just that.  Here's the first one.

Homework Assignment #1

This problem will help you get more comfortable with the technique for creating frames.  Open the WordPad application and maximize it.  Then press ALT+F to drop down the file menu.  The four entries near  the bottom of this menu, which are labeled 1 through 4, represent the last four files that have been opened in WordPad.  (If you have never opened any files in WordPad, please open four different ones now so you will have these entries in your file menu.)  Create a frame around these entries named RecentFiles that will speak them when you use the hot key CONTROL+1.  Make sure you choose an echo level that doesn't interfere with the normal speaking of the menu items when you arrow through them.  Hint - The longest filename currently present may not be the longest one that will ever appear, and the longest name may not be on the last or fourth line.  The answer can be found in Appendix A.  (See Chapter 7.1.)

Homework Assignment #2

Now let's tackle an automatic reading problem.  When you want to find a particular file in Windows Explorer, you can invoke the search dialog with the accelerator key combination, CONTROL+F.  After you type in the file name you wish to locate and press ENTER, Explorer searches your system and places the names of the files it finds in a list box.  It also places the number of files it has located on the status line at the bottom of the window.  The message it displays is "x file(s) found", where x is the number of files located.  If no files fitting the specification are located, the phrase "0 file(s) found" is displayed.  In either case, however, the word, found, is displayed on the status line.  Your task is to create a frame around this status line that will automatically announce the result when the search is over.  The frame should not speak any intermediate information while the search is progressing, it should only announce the result when the search is done.  The answer can be found in Appendix A.  (See Chapter 7.2.)

5.2	Editing and Troubleshooting a Frame

Once a frame has been created by the above techniques, it can be edited at any time if it is not working as expected or if the user decides the frame should operate differently.  One can edit a frame by opening the Frame Manager from within the application by any of the techniques described earlier, tabbing to the right pane of the screen, highlighting the desired frame, and pressing the Enter key to open the Frame Properties Dialog.

Sometimes the new frame you have just created will work perfectly and need no editing.  However, there are times when the frame may not perform exactly as expected or may not work at all.  It can also happen that a frame may work for a while but then, at some later time cease to perform as it did when it was first created.  There are usually simple explanations for these problems, and the questions and answers that follow will explain how you can figure out the problem and correct it quickly.  All of the suggested edits are to be made from within the Frame Properties Dialog.

QUESTION: My frame sort of works, but it doesn't seem to read all of the line.  The ends of phrases are being cut off.  Why is this happening?

ANSWER: Your frame probably isn't wide enough.  It may be that you didn't put the cursor far enough to the right when you placed the bottom, right corner, or it may be that some of the text you are trying to read is wider than the text that was present when you first created the frame.  Go to the Position Tab, and locate the Width edit field.  Gradually make this number larger until all of the text is spoken.  By the way, if your frame is reading extra text that you don't want to hear, try making the width number smaller.

QUESTION: My frame sort of works, but it isn't reading the whole message.  Only the first part is spoken.  Why is this?

ANSWER: Your frame probably isn't high enough.  It may be that you didn't put the cursor far enough down when you placed the bottom, right corner, or it may be that some of the text you are trying to read is lower down than the text that was present when you first created the frame.  Go to the Position Tab, and locate the Height edit field.  Gradually make this number larger until all of the text is spoken.  By the way, if your frame is reading extra text at the bottom that you don't want to hear, try making the height number smaller.

QUESTION: My frame worked perfectly when I first created it, but now I've opened a different document, and the frame has stopped working completely.  Is my frame possessed by demons?

ANSWER: The problem may be that your document name has changed.  In the context meant here, a document can be a word processor or spreadsheet file, but it can also be a mailbox in your E-mail program, an FTP site on the web, or any other property that adds its name to the title bar of the real window containing the frame.  For example, if you press INSERT+T while reading this manual, you will not only hear the name of the word processor you are using, you will also hear the name of this document as part of the title.  The Frame Manager grabs the window title during frame creation and incorporates it as part of the name of the frame in the Real Window Tab of the Frame Properties Dialog.  When you change documents, the title is no longer valid, and the frame will not work.  Go to the Name field of the Real Window Tab, and delete any document references before or after the window name.  This should restore your frame's proper operation.  In some rare circumstances, it may be necessary to remove all text from the Name field to get the frame to work.  For example, the author has found that, when frames are created for the desktop, JAWS will place the word Desktop in the Name field.  This must be removed completely for the desktop frame to work.  If all else fails, try completely removing the text in the Name field, but note it down before deleting it so you can put it back if this turns out not to be the problem.

QUESTION: My frame worked perfectly when I created it last time I used this application, but now it reads nothing or it reads some nonsense that has nothing to do with its purpose.  I already checked the name in the Real Window Tab, and that's not the problem.  What could be causing this?

ANSWER: It's possible that you have changed the window state since the last time you used the application.  If the application or document windows were maximized or restored when you first created the frame, they will often have to be in the same state to ensure proper frame operation.  If you want the frame to function in all window states, you will have to create duplicate frames for each state.

QUESTION: Sometimes the frame works, and sometimes it doesn't.  I checked the Real Window Tab and window states, and they're not the problem.  Are there any other possibilities?

ANSWER: You may have accidentally or deliberately placed a text string in the "Window Must Contain Text" or "Frame Must Contain Text" fields of the Real Window Tab.  If this text is no longer present, the frame will not work.  Try removing any entries in these fields to see if proper frame performance is restored.

QUESTION: The frame I created for this one application is driving me crazy!  Every time I use the application I have to redo the frame.  It works perfectly for that session, but next time it has stopped working, and I have to create it all over again.  I've checked the name in the Real Window Tab, the window state, and the Frame Must Contain Text and Window Must Contain Text fields.  None of these is the source of the problem.  What am I doing wrong?

ANSWER: Some applications provide long strings of numbers for JAWS to use as part of the Class entry of the Real Window Tab, and sometimes these applications change those numbers every time the application is run.  This means that no matter what entry JAWS places in that Class field, it will be wrong the next time the application is run, and the frame won't operate.  In these cases, it will be necessary to delete part or all of the data in the Class field.  If possible, delete only those few numbers at the end of the string that change every time the application is run.  You can determine this by opening the application several times, starting the frame creation process, and examining the data string in the Class field.  All numbers that remain constant from one session to another can be left, but all that change should be removed.  You can abort the frame creation process by pressing ESCAPE after examining the Class field data so you don't end up creating multiple, test frames.

Homework Assignment #3

Your job for this assignment is to modify the frame you created in the first assignment.  Change the frame so that it only reads the first or most-recently-opened file.  Do this by editing the frame you already created, not by creating a new one.  The answer can be found in Appendix A.  (See Chapter 7.3.)

6	Advanced Frame Features and Capabilities

This chapter is intended for those who wish to go beyond the use of frames to monitor and read text.  JAWS frames have some very powerful extensions in that they can be used to cause a user-defined function in the JAWS script language to execute and in that JAWS scripts and functions can use frames to read text in predefined areas of the screen.  These two complementary capabilities allow the user to create frames that can initiate very sophisticated JAWS activities and to create scripts and functions that use frames to read parts of the screen with much more facility than would otherwise be possible without their use.  The following two sections cover these topics, but it is suggested that the reader be thoroughly comfortable with the topics covered earlier in this manual and have at least a modest familiarity with writing JAWS scripts and user-defined functions before proceeding.

6.1	The New Text Function

As we discussed earlier, the Frame Properties Dialog of the Frame Manager contains an Action Tab within which one can enter a New Text Function to be called in lieu of the standard NewTextEvent function whenever new text is written within the boundaries of the frame.  (See Chapter 4.4.3.)  What does this mean?  The JAWS default script file, Default.JSS, contains a special function that is activated automatically whenever new text is written to the screen.  This function is called the NewTextEvent function, and it handles the processing of the newly-written text.  For example, the NewTextEvent function mentioned above has a line in it that reads SayNonHighlightedText ().  If the NewTextEvent function has analyzed the new text written to the screen and decided that it is properly handled by the SayNonHighlightedText function, it will pass off the job to that function by calling it and then let it speak the text for you.  On the other hand, if the NewTextEvent function decides that the screen information is highlighted text, then it will call a different function named SayHighlightedText instead, and it will let that function do the speaking for you.  The NewTextEvent function also contains logic that determines whether the newly-written text is associated with a frame and, if so, whether the text should be spoken based upon the echo level of the frame.

By entering a function name in the New Text Function field of the Action Tab, you are telling JAWS that, when text is written within this particular frame, the text should be handled by this alternative function instead of the usual NewTextEvent function.  You can make this function do anything you like, from simply handling the text in a slightly different manner from the standard one all the way to performing advanced script functions that have nothing whatsoever to do with actually reading the text.  These advanced functions can even be protocols that instruct JAWS to do particular actions or that command the application to do something at the particular time that text appears in a particular location.  If you think about this for a while, you'll begin to see how powerful this tool can be.

The NewTextEvent function, which can be studied in its original form in the script file, Default.JSS, which resides in THE \SETTINGS\ENU folder of your JFW directory, is shown below.

Void Function NewTextEvent (handle hwnd, string buffer, int nAttributes, int nTextColor, int nBackgroundColor, int nEcho, string sFrameName)
; Handles all newly written text.  If the text is contained in a
; frame, then the frame name is passed as a parameter
if (ProcessSelectText(nAttributes, buffer)) then
return
endIf
if (sFrameName == "") then
; this text is not associated with a frame
if (nAttributes& ATTRIB_HIGHLIGHT) then
SayHighlightedText(hwnd, buffer)
else
SayNonHighlightedText(hwnd, buffer)
endIf
else
; this text is associated with a frame
if (nEcho == ECHO_NONE) then
return; frame is being silenced
endIf
if (nEcho  == ECHO_ALL ||
(nAttributes & ATTRIB_HIGHLIGHT)) then
; if Frame echo is set to all or the text being written is highlighted
SayString(buffer)
endIf
endIf
EndFunction

This event function contains seven parameters.  (For a discussion of the use of parameters within a function, see the JFW Script Manual that is available for download at http://www.hj.com.)  The custom New Text function you create must contain these same seven parameters.  The following describes each of the parameters.

Handle hwnd is the window handle of the window getting the text.
String buffer is the actual text being written to the window.
Int nAttributes is the attribute of the text being written.
Int nTextColor is the color of the text being written.
Int nBackgroundColor is the background color of the text being written.
Int nEcho is the level of echo set for the frame, if any, that is getting the text.
String sFrameName is the name of the frame, if any, that is getting the text.

As we said earlier, this function is called automatically every time new text is written to the screen.  JAWS automatically passes the values of these seven parameters to the function when it is called.  By using logic and performing comparisons on this data, the function can determine what type of text has been written, whether or not it is associated with a frame, and what, if anything, JAWS should say.

When you create your custom function, you must create it in the same form as the NewTextEvent function in that you must include these seven parameters in the first line of the function.  (for a discussion of creating functions with parameters, see the JFW Script Manual.)  You do not actually have to use these parameters for anything within the body of the function if you don't wish to, but they must appear as part of the function's definition.  This is because you are substituting your custom function for the NewTextEvent function, and JAWS expects this function to follow a certain format.  You should place your function in the APPLICATION.JSS file if the frame appears in the application's frame file.  If your frame is in the default frame file, then place the custom function in the Default.JSS script file.

So what kinds of things could you do with this custom New Text function?  You might, for example, wish to have JAWS speak a customized prompt when text appears at a particular location rather than actually reading the text to you.  A function that would do this would look like the following:

Void Function MyTextEvent (handle hwnd, string buffer, int nAttributes, int nTextColor, int nBackgroundColor, int nEcho, string sFrameName)
SayString ("Some new text just appeared in your frame.")
EndFunction

In this case, we have a function that says a custom message.  If the name of this function is placed in the New Text function field of the Action page of the frame's documentation, then the function will be called whenever text is written within the frame.  Thus, the custom message, "Some new text just appeared in your frame." would be spoken.  It is important to understand that, since you are substituting your special function for the NewTextEvent function, only the activities you specify in your function will occur when text that is written to the screen occurs within the calling frame.  All other normal speaking activities will be suppressed.  If you wish also to have the normal speaking activities occur, you must call the NewTextEvent function within your special function.  If you do this, then in addition to hearing this message, you might also hear the text that was written to the frame, but this would depend on the echo level setting for the frame.  As usual, Echo All would cause all text written within the frame to be spoken, and Echo Highlighted would cause only highlighted text to be spoken.  This is a good time to point out that, if you wish to use a New Text Function and have it triggered by your frame, you must choose either to have the frame echo level set to silent, highlighted, or all.  If a frame is set to JFW Screen Echo, it will not trigger a New Text Function.  If your New Text Function does not seem to be operating properly, one of the first things you should check is that you didn't leave the echo level set to the default, JFW Screen Echo.

You are not, of course, limited to the speaking of custom messages within your function.  Any legitimate JAWS scripting statements can be used, and you can even employ statements that affect the application or play sound files.  This is a very powerful tool, and you are only limited by your imagination.

Well, you might be saying, what if I want my function to operate only when some particular text appears in the frame or in the window?  What if I don't want my function to operate when all new text appears, just when specific text appears.  If that's the case, you can place the specific text of interest in the "Window Must Contain Text" or "Frame Must Contain Text" fields of the Real Window Tab.  This would limit the triggering of the frame and, thus, the custom New Text function, to those instances where the particular text of interest was present in the window or frame.  You could even make your frame the size of one character and place that character in the "Frame Must Contain Text" field.  That would limit the triggering of the custom function to the appearance of a particular character at a precise location on the screen.  If you think about this setup for a while, you'll begin to realize how powerful a tool this really is.

Here's an example of how this feature can be used to accomplish an unusual task.  You may have noted that, every once in a while, closing an application causes Windows to lose focus.  This leaves JAWS not able to tell you an application title when INSERT+T is used, and one must press the INSERT+F6 key combination to minimize all windows and return focus to the desktop.  The author wished to find a way to minimize the number of these instances of loss of focus.  Some means of monitoring Windows was required, and some means of automatically refocusing was also needed when the loss of focus situation was detected.  This was accomplished with a frame and a custom New Text function, as described below.

The monitoring capability was added by creating a frame around the text name of one of the icons on the desktop and placing this frame definition in the default frame file.  (The default file is used because one wishes this monitoring frame to be active at all times, not just when a particular application is active.)  When one closes a program but focus does not move to another program, the desktop and all of its icons are normally visible.  This means that the names of the desktop icons appear on the screen when the previous application is closed and focus does not move to a different application.  When this happens, the frame one has created around one of the icons will be triggered because of the icon's text name appearing within the frame's borders.

After the frame was created using the standard techniques described above, the author edited the frame by making the following changes:

The echo level of the frame was set to highlighted.  As mentioned above, a level other than JFW Screen Echo must be chosen for the New Text Function to be called.  Highlighted was chosen since, if one were to use the arrow keys to move among the icons on the Desktop, one would only wish JAWS to speak the name of the icon surrounded by our frame if that icon were highlighted.  Choosing a different echo level would interfere with proper speaking of the icon's name.

The name of our New Text Function, which we will call DefaultFocusEvent, was added to the Action Tab of the Frame Documentation Dialog.

The word, Desktop, was removed from the Name field of the Real Window Tab.  It was observed that failing to do this prevented the frame from operating.

The text name of the icon was placed in the Frame Must Contain Text field of the Real Window Tab.  This was done to provide extra assurance that the frame would only trigger when the precise text of the desktop icon's name appeared within its borders.  This step was probably not strictly necessary since the frame, being associated with the desktop's class, Progman, shouldn't trigger unless the newly-written text were associated with the Progman class and, thus, be part of the desktop.  Placing the icon's name in the Frame Must Contain Text field, however, provided some added assurance that false triggering of the frame wouldn't occur when other, random, text appeared within the frame's borders.

Thus, we have the monitoring setup required to tell JAWS when the desktop is on the screen.  Now we need the capability of automatically refocusing on the desktop when focus is actually lost.  This was done by creating the custom function called DefaultFocusEvent alluded to above and placing its name in the New Text Function field of the Action Tab.  That function is shown below:

Void Function DefaultFocusEvent (handle hwnd, string Buffer, int nAttributes, int nTextColor, int nBackgroundColor, int nEcho, string sFrameName)
Var
Int TheControlID,
Handle TheHandle
Pause () ;Allow the system time to stabilize
Delay (5) ;Allow the system time to stabilize
Let TheControlID = GetCurrentControlID ()
Let TheHandle = GetCurrentWindow ()
If (TheControlID == 1) && (TheHandle == 0) Then ;conditions indicative of focus loss
MinimizeAllApps () ;refocus on Desktop
EndIf
;Now call the standard NewTextEvent function to allow normal text processing.
NewTextEvent (hwnd, buffer, nAttributes, nTextColor, nBackgroundColor, nEcho, sFrameName)
EndFunction

Although the precise nature of the operation of this function is not relevant to our discussion of how to implement the calling of New Text Functions with frames, comments have been added to allow the reader to understand what is happening.  The point is that if the frame surrounding the icon on the Desktop is activated, the above function will be called.  The function will then determine if focus has been lost and, if so, reset the focus on the Desktop by use of the MinimizeAllApps function call.  A call to the standard NewTextEvent function was also added at the end to allow JAWS to process text normally for all situations where refocusing is not the task.  Without this call, one might not hear normal speaking in some situations on the Desktop.  If the purpose of this function had been to change text processing rather than activate a refocusing on the Desktop, one would probably not include a call of the NewTextEvent function.  Once again, the precise construction of the New Text Function will be determined by the nature of the task to be performed, and the user can learn how to construct these functions by studying the JFW Script Manual.

The result of all of this is that a frame has been used to monitor system activities and trigger an adjustment to that system.  Although we normally tend to think of frames as convenient ways to read the screen, this example presents a capability that has nothing to do with screen reading per se.  The conclusion is that frames can be used to perform many advanced activities that are limited only by the availability of an appropriate JAWS script function and the user's imagination.

Homework Assignment #4

In the second homework assignment, a frame was to be created that read out the results of a Windows Explorer search after the search was complete.  Let's make some modifications to that frame.  Instead of having a frame with its echo set to "All", change the echo to "Silent" so that nothing will be spoken when the search is complete.  Then have the frame call a New Text Function named AnnounceSearchResults that speaks the message, "Your Windows Explorer search is complete".  In addition, have the function read the bottom, status line of the search window that contains the search results so you will know what was found.  The answer can be found in Appendix A.  (See Chapter 7.4.)

6.2	Using Frames in Scripts and Functions

In the previous section, we talked about the use of frames to invoke JAWS script functions.  The opposite of this is also possible.  One can use JAWS scripts and functions to perform frame-related activities such as reading the contents of a frame or even much more advanced tasks.  For example, lets say there are three frames on the screen, and you want to read all three of them with one keystroke.  Since a keystroke can only be assigned to one frame at a time, there is no direct way to do this without the use of JAWS scripts.  A script, however, can be written to read as many frames as one might wish.

Here is an example of a script that could be used to read, consecutively, two frames named AreaOne and AreaTwo.

Script ReadBothFrames ()
SayFrame ("AreaOne")
SayFrame ("AreaTwo")
EndScript

First, this script will read the frame named AreaOne, and then it will read the frame called AreaTwo.  Whatever keystroke is assigned to this script will, therefore, read the contents of both frames.  There are many, more complicated types of frame processing one could use that would be much more sophisticated than the above example.  One could, for instance, use If-Then logic to read one frame under certain conditions or read a different frame under other conditions.  The possibilities are limited only by the user's imagination and the existence of the appropriate functions within the JAWS script language.

For the reader's convenience, a listing of all of the frame-related JAWS script functions that existed at the time of this manual's writing has been included.  Additional functions may have been added subsequently.  (See Appendix B.)

Homework Assignment #5

Let's say we want to create a frame in the JAWS script Manager that reads the four recently-opened files from the file list, just as we did in WordPad.  At first, this seems like a simple task, but there's a bit of a problem.  The length of the file list and, therefore, the location of the four files of interest, depends upon whether there are any script files open in the Script Manager.  To see what we mean, open the Script Manager by going to the JFW main window, dropping the Utilities menu, and then choosing the Script Manager option.  You will be placed in the Script Manager with no files open.  If you drop down the File menu, you will find that the first of the most-recently-opened files is the sixth menu option down from the top.  Now, open any file, and then check the File menu again.  You will now see that the first of the recently-opened files is the thirteenth entry down in the file menu.  This means that the names of the four files we want to read change their locations on the screen, depending on whether there are any files open in the Script Manager.  Obviously, we aren't going to be able to use a single hot key, tied to just one frame, to read the file list.  Your assignment is to create to frames, one around each of the two possible locations for the file list, and then to create a script called RecentlyOpenedFiles that will read whichever frame currently contains the file list.  In other words, create one frame called "RecentFilesClosed" that surrounds the position of the four files when no files are open, and create another frame called "RecentFilesOpen" that surrounds the position of the four files when there is at least one file open.  Do not create a script that always reads both frames, but design the script so it can decide which frame is the proper one and then read it.  Hint - The first character of the line containing the first recently-opened file will always be a 1.  The data for the two frames and one possible script to do the reading are shown in Appendix A.  (See Chapter 7.5.)

7	Appendix A

Answers to Homework Assignments

7.1	Answer to Homework Assignment #1

The following information should appear in the various fields of the Frame Documentation Dialog.  Obviously, your data may vary slightly, but this is representative of a frame that works correctly for the stated purpose.

General Tab:

Frame Name = RecentFiles
Synopsis = list of recent files
Description = reads out list of four most recently opened files
Echo = JFW Screen Echo
Assign to Hot Key = CONTROL+1

Position Tab:

Distance From Left Side of Window = 3
Width = 232
Distance From Top of Window = 141
Height = 63
Relative to Window

Action Tab:

Processing Priority = 5 (default)
New Text Function = (none)

Real Window Tab:

Name = (none)
Class = #32768
Window Must Contain Text = (none)
Frame Must Contain Text = (none)

7.2	Answer to Homework Assignment #2

The following information should appear in the various fields of the Frame Documentation Dialog.  Obviously, your data may vary slightly, but this is representative of a frame that works correctly for the stated purpose.  This problem was borrowed from the JAWS for Windows training tapes.

General Tab:

Frame Name = FindFileStatusFound
Synopsis = Speaks the number of files found when search is complete
Description = The user is informed of the end of the search and its results
Echo = All
Assign to Hot Key = (none)

Position Tab:

Distance From Left Side of Window = 7
Width = 197
Distance From Top of Window = 20
Height = 14
Relative to Window

Action Tab:

Processing Priority = 5 (default)
New Text Function = (none)

Real Window Tab:

Name = Find: Files named
Class = #32770
Window Must Contain Text = (none)
Frame Must Contain Text = found

The reader should note that it is the word, found, placed in the Frame Must Contain Text field, that limits speaking until the search is complete.  Since this word only appears at the end of the search, the frame is forced to be silent until that time.

7.3	Answer to Homework Assignment #3

The desired modification can be obtained by changing the height of the frame in the Position Tab, using the Frame Properties Dialog of the Frame Manager.  The correctly-modified data of this page of the dialog is shown below:

Position Tab:

Distance From Left Side of Window = 3
Width = 232
Distance From Top of Window = 141
Height = 16
Relative to Window

7.4	Answer to Homework Assignment #4

The following information should appear in the various fields of the Frame Documentation Dialog.  Obviously, your data may vary slightly, but this is representative of a frame that works correctly for the stated purpose.

General Tab:

Frame Name = FindFileStatusFound
Synopsis = Speaks an announcement and the number of files found when search is complete
Description = The user is automatically informed of the end of the search and its results
Echo = Silent
Assign to Hot Key = (none)

Position Tab:

Distance From Left Side of Window = 7
Width = 197
Distance From Top of Window = 20
Height = 14
Relative to Window

Action Tab:

Processing Priority = 5 (default)
New Text Function = AnnounceSearchResults

Real Window Tab:

Name = Find: Files named
Class = #32770
Window Must Contain Text = (none)
Frame Must Contain Text = found

The function to be called is shown below.  It should be placed in the script file for the file find application which is SHELL32.JSS.

Void Function AnnounceSearchResults (handle hwnd, string Buffer, int nAttributes, int nTextColor, int nBackgroundColor, int nEcho, string sFrameName)
SayString ("Your Windows Explorer search is complete")
PerformScript SayBottomLineOfWindow()
EndFunction

7.5	Answer to Homework Assignment #5

The following information should appear in the various fields of the Frame Documentation Dialog for the two frames.  Obviously, your data may vary slightly, but this is representative of frames that work correctly for the stated purpose.

RecentFilesClosed Frame

General Tab:

Frame Name = RecentFilesClosed
Synopsis = list of recent files when no files are open
Description = reads out list of four most recently opened files when no files are open
Echo = JFW Screen Echo
Assign to Hot Key = (none)

Position Tab:

Distance From Left Side of Window = 19
Width = 145
Distance From Top of Window = 107
Height = 63
Relative to Window

Action Tab:

Processing Priority = 5 (default)
New Text Function = (none)

Real Window Tab:

Name = (none)
Class = #32768
Window Must Contain Text = (none)
Frame Must Contain Text = (none)

RecentFilesOpen Frame

General Tab:

Frame Name = RecentFilesOpen
Synopsis = list of recent files when at least one file is open
Description = reads out list of four most recently opened files when at least one file is open
Echo = JFW Screen Echo
Assign to Hot Key = (none)

Position Tab:

Distance From Left Side of Window = 19
Width = 165
Distance From Top of Window = 226
Height = 63
Relative to Window

Action Tab:

Processing Priority = 5 (default)
New Text Function = (none)

Real Window Tab:

Name = (none)
Class = #32768
Window Must Contain Text = (none)
Frame Must Contain Text = (none)

Script to Read the Proper Frame

Script RecentlyOpenedFiles ()
SaveCursor ()
InvisibleCursor ()
RouteInvisibleToPc ()
Pause ()
NextLine () 
NextLine () 
NextLine () 
NextLine () 
NextLine ()
Pause ()
If (GetCharacter () == "1") Then
SayFrame ("RecentFilesClosed")
Else
SayFrame ("RecentFilesOpen")
EndIf
RestoreCursor ()
EndScript

8	Appendix B

List of Frame-Related, JAWS Script Functions

GetFrameDescription - Retrieves the description of a specified frame.

GetFrameNameAtCursor - Retrieves the name of the frame that surrounds the current cursor's location.

GetFrameSynopsis - Retrieves the synopsis of a specified frame.

MoveToFrame - Moves the active cursor to the top left corner of the specified Frame.  If the PC cursor is active when this function is used, then the JAWS cursor is activated and it is moved to the new position, otherwise the active cursor is moved.

SayFrame - Speaks the contents of the specified frame.

SayFrameAtCursor - All text within the boundaries of the frame that contains the active cursor is spoken.

