13.1 Windows Hierarchy

The operating system does not randomly place the various windows that may be present on your screen at any one time. They are interrelated with a special hierarchy that allows the Windows operating system and the programmers who work within it to keep track of each window.

You can think of these inter-relationships as one of parents and children. The desktop is the parent of all application windows. Thus, the JAWS window, your word processor's window and the Internet browser's window are all children of the desktop. These windows are all one level down from the desktop, which makes them all children of the desktop at the same logical level. It also means that all of them are peers of each other. When you later encounter terms such as PriorWindow and NextWindow, the reference is to moving among peer windows at the same logical level.

The word processor window has several child windows, the text area, the menu bar, the toolbar and the status line. These are all children of the word processor window and are all children at the same logical level. When you press the keystroke to open a file in your word processor, the word processor displays a child window that prompts you for the file to open. This window is often referred to as a dialog box, but it is a child window to the word processor, its parent.

If you think of the Open File dialog box as a parent then you will find that the File Name edit box and all other controls are children of the open file dialog box. These are all children of the parent dialog and are at the same logical level. Each window is a child to the window one level up that spawned or generated it, and each window is a parent to the windows one level down from it.

You can find a good analogy of the parent-child relationship by using the file folder structure of your PC. On your disk drive, the C:\ drive is typically the parent of all other folders on your drive. All of the subfolders one level down from C:\ are children of that parent and are at the same logical level. Thus, if you have subfolders named Documents and Settings, Program Files and Windows on your system, they are all one level down from C:\. They are all children of C:\ and are all one logical level down. For the purposes of folder tree structure and window hierarchy, you can assume that being at the same logical level means that all windows were spawned or generated by the same parent.

When you open the Program Files subfolder, you should find subfolders such as Common Files, Freedom Scientific and Internet Explorer. These three subfolders are all one level down from Program Files, are children of Program Files, and are at the same logical level as each other, two levels down from C:\. This can continue until the lowest logical level of a particular branch is reached.

The parent/child structure of Windows works much the same way as a folder structure. Each application is a branch of the tree, and child windows are spawned from it. All windows one level down from the parent application are children at the same logical level. Each of these children can spawn children of their own, and these children are three levels down from the parent application.

Another example of a parent child relationship is the world we live in. Think of your house as being at the bottom end of a hierarchy. The parent of your house is the city you live in. All the other houses in your city are children of your city and are at the same logical level. For example, all the houses in St. Petersburg are at the same logical level. They all have the same parent which is the city of St. Petersburg. The parent of your city is the state you live in. Every city is at the same logical level and has the same parent. The parent of St. Petersburg is the state of Florida. All the cities in Florida are at the same logical level and have the same parent. The parent of each state is your country. Every state is at the same logical level and is a child of its country. The parent of Florida is the United States. All the states in the US are at the same logical level and have the same parent. You can think of the planet itself as being the parent of all the countries. As you can see, the hierarchy can contain many different levels.

Identifying Windows

An application programmer assigns a number of identifiers to each window. These identifiers allow the window to be referred to individually. Each window has a class, type, type code, window subtype code, and control ID. These window categories are important because JAWS behaves differently, depending on what category of window is active.

For example, if an edit field is active, JAWS tracks the insertion point. If you press DOWN ARROW, JAWS speaks the line of text to which the insertion point moves. When a list box or menu is active, JAWS tracks the highlight or lightbar as the arrow keys are used to move it up and down the list. JAWS knows to do these things because of the scripts that are associated with the up and down arrow keys in the default script file. These scripts contain logic that decides what to do based on the type of window that has the focus when one of these keys is used.

The Window Handle

The window handle is a unique number assigned by the operating system to each window when it is created during a given session. Window handles change each time the window is created. However, the handle value remains constant as long as the window exists.

As long as a window exists, you can use the handle to refer to and identify that window. But when a window is closed, it relinquishes its handle. If the window is created later, the operating system assigns a different handle.

You can retrieve the window handle using the built-in functions, GetCurrentWindow and GetFocus. There is a distinct difference between these two functions. The GetFocus function retrieves the handle of the window that contains the insertion point or system focus. The GetCurrentWindow function retrieves the handle of the window containing the active cursor. Many of the JAWS functions used to manipulate windows use the window handle as a parameter. You can use the GetFocus and GetCurrentWindow functions as parameters to other window related functions. An example of how the GetFocus function is used follows:

Example 1: Using the GetFocus Function

Script GetWindowFocus ()
var
handle hFocusWindow
let hFocusWindow = GetFocus ()
; the GetFocus statement could be replaced by the following line:
; let hFocusWindow = GetCurrentWindow ()
SayInteger (hFocusWindow); speak the value of the window handle
EndScript

Window Class

The window class is a string of text that denotes some information about a window and what it does. A window class can be an edit field, list box, or a button. It provides valuable information about the window. However, the window class does not always provide specific information. Checking the window class will return the same information for a button, radio button, and checkbox all of which have a Window Class of button. JAWS recognizes 30 different classes.

Many times, programmers use custom window classes that JAWS cannot recognize. In these cases, you must tell JAWS how to treat the unrecognized class. After you tell JAWS how to treat a custom window class, JAWS reacts to the window class just as if it were a recognized window class. You can retrieve the Window Class with the function, GetWindowClass. An example of how the window class is retrieved follows:

Example 2: Using the GetWindowClass Function

Script RetrieveWindowClass
var
string sTheClass
let sTheClass = GetWindowClass (GetFocus ())
If sTheClass == �Edit� Then ; the window class is an edit box
Say ("Focus is in an edit box." OT_MESSAGE)
Else
Say ("The focus is not in an edit box.", OT_MESSAGE) ;the window class is something other than Edit
EndIf
EndScript

Window Type

The window type is a string of text that describes the window. Occasionally, the window type reveals more specific information about certain windows. The window type and window class are the same if no more specific information is available. For example, the window class and window type of an edit box are exactly the same.

You can use the window type to differentiate between a checkbox and a radio button. You use the function GetWindowType to retrieve the Window Type. The GetWindowType function returns the string of "unknown window type" when the application programmer used a custom window class to define the window. The Window Type is always in English and is not very useful for those using JAWS in other languages. An example of how the GetWindowType function is used follows:

Example 3: Using the GetWindowType Function

Script RetrieveWindowType ()
Var
string sTheType
Let sTheType = GetWindowType (GetFocus ())
If sTheType == "Edit" Then ; the window type returned is an edit box
Say ("The focus is in an edit box", OT_MESSAGE)
Else
Say ("The focus is not in an edit box.", OT_MESSAGE) ; a window type other than edit was found
EndIf
EndScript

Window Type Code

The window type code is a numeric value instead of a string. This number is translated into a recognizable string by constant definitions found in the file, HJConst.jsh. For example, in this file you can find lines such as WT_BUTTON=1, WT_COMBOBOX=2, WT_EDIT=3, WT_LISTBOX=4, and WT_SCROLLBAR=5. The WT prefix of the constant indicates that this is a constant that refers to a window type code.

While the window type code does not provide any more information than the window type, it does have the advantage of being language independent. You retrieve the window type code with the function, GetWindowTypeCode. An example of how the GetWindowTypeCode function is used follows:

Example 4: Using the GetWindowTypeCode Function

Script RetrieveWindowTypeCode ()

Var

int iTheTypeCode

Let iTheTypeCode = GetWindowTypeCode (GetFocus ())

If iTheTypeCode == WT_Edit Then

; the window type code of 3 was found. The constant, WT_Edit

; is defined in HJConst.jsh and given a value of 3.

Say (�The focus is in an edit box.�, OT_MESSAGE)

Else

Say ("The focus is not in an edit box.", OT_MESSAGE)

; a window type code other than 3 was found, so focus is not in an edit box

EndIf

EndScript

Window Subtype Code

Like the window type code, the window subtype code is also a numeric value. However, the window subtype code may provide more detailed information. If no subtype code is available for the window, then the window type code and window subtype code are identical. You should use the window sub type code as it generally provides more specific information about a window than does the window type code. You can use the same constant definitions to refer to window subtype codes as you can for window type codes in your scripts and functions. For example, a radio button has a window type code of 1 (WT_Button) but a subtype code of 19 (WT_RadioButton). Window subtype codes are also language independent. You use the function, GetWindowSubTypeCode, to retrieve the window subtype code for a given window. An example of the use of the GetWindowSubTypeCode function follows:

Example 5: Using the GetWindowSubTypeCode Function

Script RetrieveWindowSubTypeCode ()

Var

int iTheSubTypeCode,

int iTheTypeCode

let iTheTypeCode = GetWindowTypeCode (GetFocus ())

let iTheSubTypeCode = GetWindowSubTypeCode (GetFocus ())

If iTheTypeCode == WT_Button Then

If iTheSubTypeCode == WT_RadioButton Then

; the window type code of 1 was retrieved. The constant, WT_Button, is defined in HJConst.jsh and

; given the value of 1.

; the next If-Then statement checks for a subtype code of 19. The constant, WT_radiobutton is

; given the value of 19 in the HJConst.jsh file.

Say ("The active window is a radio button." OT_MESSAGE)

Else

Say ("The active window is not a radio button." OT_MESSAGE)

EndIf

Else

Say ("The active window is not a button." OT_MESSAGE)

EndIf

EndScript

Window Control ID

The control ID is a number assigned by the programmer to each window during application development. The control ID, unlike the window class, has no special meaning, but you can use it to refer to a particular window.

One example where the use of control ID�s are extremely useful is in applications where the buttons are labeled with bit map images instead of text labels. Normally, JAWS speaks the text label of a button when you move to it. If the label is a drawing, there is no name to be spoken. By determining the control ID numbers of the various bit map buttons, you can write a script that speaks the name of the button when the focus moves to it.

In most cases, the control ID is defined during application development and can be relied upon to uniquely identify a specific window. However, you may find cases where control ID�s have not been assigned by the application developer. In these cases, you will find that each window in a given application has a control ID value of 0. You must then rely on other window identifiers along with the window�s hierarchical position to uniquely identify it.

You may also find that the control ID�s in a given application are dynamically assigned. This means that each time an application window or any of it�s child windows are created, the control ID�s are assigned and do not remain constant. In these cases, you will find that you need to use the other windows identifiers and the window hierarchical position to uniquely identify the window.

You can determine if control ID�s are dynamically assigned by running the application, noting the control ID values of some of it�s child windows, then restarting the application and looking at those same control ID values. If they have changed, then you will know that the ID�s are dynamically assigned. You use the function, GetControlID, to retrieve the control ID for a given window. An example of how the GetControlID function is used follows:

Example 6: Using the GetControlID Function

Script IdentifyWindow ()
Var
int iControlID
let iControlID = GetControlID (GetFocus ())
If iControlID == 1100 Then; look for a specific control ID
Say ("This is the file name edit box", OT_MESSAGE)
; the file name edit box has a control ID of 1100
Else
Say ("This is not the file name edit box.", OT_MESSAGE)
EndIf
EndScript

 

Back

Next