The GW-Scripting list is a discussion list for information regarding the development and use of Window-Eyes scripts. Any subscriber of the GW-Scripting list has the ability to post on-topic messages.
From:
Allison and Chip OrangeSubject:
draft of examples for today's scripting classDate:
Sun, Jul 3, 2011 12:48:42 pmtoday's class is going to cover the use of MSAA, and so here are a couple of
examples so far; there will be more talk and fewer examples on this subject
than is usual.
' Draft Scripting class 18 (7/3/2011)
MSAA over-view from:
http://en.wikipedia.org/wiki/Microsoft_Active_Accessibility
MSAA communicates information by sending small chunks of information about
elements
of a program to the assistive technology object (AT). The four critical
pieces of
information on which the AT relies to help users interact with applications
are an
element's role, name, value, and state:
Role: Conveys to users via AT what type of object a control is, such as a
button
or a table.
Name: Provides a label for an element, such as Next on a button that moves
users
to the next page, or First Name for an edit box.
Value: Provides the value of the specified object such as the value on a
slider bar, or
the information in an editable text box. Not all objects have a value.
State: Identifies the current condition of the control, such as checked for
a checkbox.
State advises whether a control can be selected, focused, and/or other types
of changeable
functionality.
' example 1
' shows how to block info from WE for a particular event, using MSAA
' (based on code from the MS Access app from GW)
' in this situation, WE is speaking incorrect information when some
control(s) get focus in MS Access.
' this app blocks the focus event from WE, and then uses the focus event to
cause it to speak the proper information instead.
' since the window onFocus event doesn't allow you to return some special
value to prevent WE from handling the focus event,
' we have to prevent WE from seeing the MSAA focus event at all.
' get a COM automation link to the running copy of MS Access
dim msAccessObj
On Error Resume Next
Set msAccessObj = GetObject(, "Access.Application")
On Error Goto 0
Dim myMSAAEventSource
Set myMSAAEventSource = MSAAEventSource ' make a copy of the object so we
can modify it's properties
myMSAAEventSource.Process = ClientInformation.ApplicationProcess
' Block focus so we can handle it ourselves
Dim blockedFocusEvent
Set blockedFocusEvent = myMSAAEventSource.BlockEvent(event_OBJECT_FOCUS,
clientInformation.ApplicationProcess)
' now, none of the window onFocus or onChildFocus events for this process
will be spoken by WE
' but the events for the window objects will still fire for this app.
Dim msaaEventHandle
' now handle all focus events
msaaEventHandle = ConnectEvent(myMSAAEventSource, "OnObjectFocus",
OnObjectFocus")
' end of main body
Sub MSAA_OnObjectFocus(accObj)
' event handler for MSAA focus events
' it tries to get the current control name and type info to be spoken from
the MSAA event,
' and if not there, then from the COM link with MS Access.
' if it can't be found in either place, then it passes the focus event to
WE, to allow WE to speak what it can.
If Not accObj Is Nothing Then
Dim handledEvent : handledEvent = False
Dim accCopy : Set accCopy = accObj
If Not accCopy Is Nothing Then
Dim accWin : Set accWin = accCopy.EventWindow ' this
is the window which had the focus event
If Not accWin Is Nothing Then
' see if we have an active COM automation link to MS Access
If Not msAccessObj Is Nothing Then
' have a COM automation link to MS Access, so it's possible to get info from
it about the current control
SpeakIt ActiveControlName(accCopy), accCopy.Value,
ActiveControlType(accCopy)
handledEvent = True
End If
End If
End If
If Not handledEvent Then
' have no COM link with MS Access, so let WE speak this focus event by
passing it on to WE
accObj.SimulateEvent event_OBJECT_FOCUS, apAll
End If
End If
End Sub ' MSAA_OnObjectFocus(accObj)
Function ActiveControlName(accObj)
' if MSAA didn't supply the control name, then get it from the COM
automation link with MS Access
ActiveControlName = ""
If Not accObj Is Nothing Then
ActiveControlName = accObj.Name
Exit Function
End If
Dim screenObj, activeObj
If Not msAccessObj Is Nothing Then
On Error Resume Next
Set screenObj = msAccessObj.Screen
If Not screenObj.ActiveControl Is Nothing Then
Set activeObj = screenObj.ActiveControl
ActiveControlName = activeObj.Name
Exit Function
End If
On Error Goto 0
End If
End Function ' ActiveControlName(accObj)
Function ActiveControlType(accObj)
' if MSAA didn't supply the control type, then get it from the COM
automation link with MS Access
ActiveControlType = ""
If Not accObj Is Nothing Then
Dim accRole : Set accRole = accObj.Role
If Not accRole Is Nothing Then
ActiveControlType = accRole.Text
End If
End If
On Error Resume Next
Dim screenObj, activeObj
If Not msAccessObj Is Nothing Then
Set screenObj = msAccessObj.Screen
If Not screenObj Is Nothing Then
Set activeObj = screenObj.ActiveControl
If Not activeObj Is Nothing Then
ActiveControlType ControlTypeToText(activeObj.ControlType)
End If
End If
End If
On Error Goto 0
End Function ' ActiveControlType(accObj)
' end of example 1
' example 2:
' mentioned in last week's examples, I used this in the MS Office app to
help me read a listbox which never got focus, and so was never read.
' (it also doesn't supply all the standard properties or MSAA information,
such as which item was just selected).
' here is shown some of the code which uses MSAA to tell me when an item in
the listbox of interest has been selected,
' then, if it's the first time, I can go look at the listbox and get the
selection background color.
' (this isn't normally anything you would have to do, it just shows some of
the creative things you may have to do in order to get something to speak
properly).
'* in main body of app prepare for use of MSAA with:
Set myMSAAEvents = msaaEventSource ' allows us to customize which MSAA
events to watch
' hook the MSAA onObjectSelection events
MSAAConnection3 = ConnectEvent(myMSAAEvents, "onObjectSelection",
"MSAA_onObjectSelection")
' limit MSAA to the VBA process:
myMSAAEvents.Process = VBAWindow.Process ' filters MSAA events for only this
process
Sub MSAA_OnObjectSelection(access)
' event handler
' called when MSAA signals some text is selected.
' note that almost all MSAA event handlers get just one parameter, an object
whose type is "accessible".
Dim accObj
Dim oWindow
If access Is Nothing Then Exit Sub
Set accObj = access ' make a copy of the object, because it sometimes
"disappears" on you
' don't do anything if this isn't for a list item
On Error Resume Next
If accObj.role Is Nothing Then Exit Sub
If accObj.role.Value role_SYSTEM_LISTITEM Then Exit Sub
If Err.Number 0 Then Exit Sub ' sometimes get an error referencing the
value property
On Error GoTo 0
' this is a list item MSAA event
On Error Resume Next
If Not accObj.State.selected Then Exit Sub
' text was selected in this list item
Set oWindow = accObj.EventWindow ' this is the window which generated the
MSAA event
If Err.Number 0 Then Exit Sub
On Error GoTo 0
If oWindow Is Nothing Then exit sub
' don't do anything if this is not a listbox window
If oWindow.Type wtListBox Then Exit Sub
' THIS IS a listbox control
' test to make sure it's the window we think it is
If StrComp(UCase(oWindow.parent.className), "NAMELISTWNDCLASS",
vbTextCompare) 0 Then Exit Sub
' and this is the correct listbox of the correct intellisense window of MS
Office
SpeakingIntelliSense = True
If sHighlightColor = "" Then
' and we don't yet know the highlight color
' note: at this point the msaa_onobjectShow has already identified the
listbox window, and has suppressed
' the speech resulting from the up/down arrows (because WE would otherwise
just read the current line of code each time
' an arrow key is pressed when an intellisense list is open).
sHighlightColor = highlightColorString(oWindow)
queue "sayHighlightedItem"
End If ' sHighlightColor = ""
End Sub
' end of example 2
examples so far; there will be more talk and fewer examples on this subject
than is usual.
' Draft Scripting class 18 (7/3/2011)
MSAA over-view from:
http://en.wikipedia.org/wiki/Microsoft_Active_Accessibility
MSAA communicates information by sending small chunks of information about
elements
of a program to the assistive technology object (AT). The four critical
pieces of
information on which the AT relies to help users interact with applications
are an
element's role, name, value, and state:
Role: Conveys to users via AT what type of object a control is, such as a
button
or a table.
Name: Provides a label for an element, such as Next on a button that moves
users
to the next page, or First Name for an edit box.
Value: Provides the value of the specified object such as the value on a
slider bar, or
the information in an editable text box. Not all objects have a value.
State: Identifies the current condition of the control, such as checked for
a checkbox.
State advises whether a control can be selected, focused, and/or other types
of changeable
functionality.
' example 1
' shows how to block info from WE for a particular event, using MSAA
' (based on code from the MS Access app from GW)
' in this situation, WE is speaking incorrect information when some
control(s) get focus in MS Access.
' this app blocks the focus event from WE, and then uses the focus event to
cause it to speak the proper information instead.
' since the window onFocus event doesn't allow you to return some special
value to prevent WE from handling the focus event,
' we have to prevent WE from seeing the MSAA focus event at all.
' get a COM automation link to the running copy of MS Access
dim msAccessObj
On Error Resume Next
Set msAccessObj = GetObject(, "Access.Application")
On Error Goto 0
Dim myMSAAEventSource
Set myMSAAEventSource = MSAAEventSource ' make a copy of the object so we
can modify it's properties
myMSAAEventSource.Process = ClientInformation.ApplicationProcess
' Block focus so we can handle it ourselves
Dim blockedFocusEvent
Set blockedFocusEvent = myMSAAEventSource.BlockEvent(event_OBJECT_FOCUS,
clientInformation.ApplicationProcess)
' now, none of the window onFocus or onChildFocus events for this process
will be spoken by WE
' but the events for the window objects will still fire for this app.
Dim msaaEventHandle
' now handle all focus events
msaaEventHandle = ConnectEvent(myMSAAEventSource, "OnObjectFocus",
OnObjectFocus")
' end of main body
Sub MSAA_OnObjectFocus(accObj)
' event handler for MSAA focus events
' it tries to get the current control name and type info to be spoken from
the MSAA event,
' and if not there, then from the COM link with MS Access.
' if it can't be found in either place, then it passes the focus event to
WE, to allow WE to speak what it can.
If Not accObj Is Nothing Then
Dim handledEvent : handledEvent = False
Dim accCopy : Set accCopy = accObj
If Not accCopy Is Nothing Then
Dim accWin : Set accWin = accCopy.EventWindow ' this
is the window which had the focus event
If Not accWin Is Nothing Then
' see if we have an active COM automation link to MS Access
If Not msAccessObj Is Nothing Then
' have a COM automation link to MS Access, so it's possible to get info from
it about the current control
SpeakIt ActiveControlName(accCopy), accCopy.Value,
ActiveControlType(accCopy)
handledEvent = True
End If
End If
End If
If Not handledEvent Then
' have no COM link with MS Access, so let WE speak this focus event by
passing it on to WE
accObj.SimulateEvent event_OBJECT_FOCUS, apAll
End If
End If
End Sub ' MSAA_OnObjectFocus(accObj)
Function ActiveControlName(accObj)
' if MSAA didn't supply the control name, then get it from the COM
automation link with MS Access
ActiveControlName = ""
If Not accObj Is Nothing Then
ActiveControlName = accObj.Name
Exit Function
End If
Dim screenObj, activeObj
If Not msAccessObj Is Nothing Then
On Error Resume Next
Set screenObj = msAccessObj.Screen
If Not screenObj.ActiveControl Is Nothing Then
Set activeObj = screenObj.ActiveControl
ActiveControlName = activeObj.Name
Exit Function
End If
On Error Goto 0
End If
End Function ' ActiveControlName(accObj)
Function ActiveControlType(accObj)
' if MSAA didn't supply the control type, then get it from the COM
automation link with MS Access
ActiveControlType = ""
If Not accObj Is Nothing Then
Dim accRole : Set accRole = accObj.Role
If Not accRole Is Nothing Then
ActiveControlType = accRole.Text
End If
End If
On Error Resume Next
Dim screenObj, activeObj
If Not msAccessObj Is Nothing Then
Set screenObj = msAccessObj.Screen
If Not screenObj Is Nothing Then
Set activeObj = screenObj.ActiveControl
If Not activeObj Is Nothing Then
ActiveControlType ControlTypeToText(activeObj.ControlType)
End If
End If
End If
On Error Goto 0
End Function ' ActiveControlType(accObj)
' end of example 1
' example 2:
' mentioned in last week's examples, I used this in the MS Office app to
help me read a listbox which never got focus, and so was never read.
' (it also doesn't supply all the standard properties or MSAA information,
such as which item was just selected).
' here is shown some of the code which uses MSAA to tell me when an item in
the listbox of interest has been selected,
' then, if it's the first time, I can go look at the listbox and get the
selection background color.
' (this isn't normally anything you would have to do, it just shows some of
the creative things you may have to do in order to get something to speak
properly).
'* in main body of app prepare for use of MSAA with:
Set myMSAAEvents = msaaEventSource ' allows us to customize which MSAA
events to watch
' hook the MSAA onObjectSelection events
MSAAConnection3 = ConnectEvent(myMSAAEvents, "onObjectSelection",
"MSAA_onObjectSelection")
' limit MSAA to the VBA process:
myMSAAEvents.Process = VBAWindow.Process ' filters MSAA events for only this
process
Sub MSAA_OnObjectSelection(access)
' event handler
' called when MSAA signals some text is selected.
' note that almost all MSAA event handlers get just one parameter, an object
whose type is "accessible".
Dim accObj
Dim oWindow
If access Is Nothing Then Exit Sub
Set accObj = access ' make a copy of the object, because it sometimes
"disappears" on you
' don't do anything if this isn't for a list item
On Error Resume Next
If accObj.role Is Nothing Then Exit Sub
If accObj.role.Value role_SYSTEM_LISTITEM Then Exit Sub
If Err.Number 0 Then Exit Sub ' sometimes get an error referencing the
value property
On Error GoTo 0
' this is a list item MSAA event
On Error Resume Next
If Not accObj.State.selected Then Exit Sub
' text was selected in this list item
Set oWindow = accObj.EventWindow ' this is the window which generated the
MSAA event
If Err.Number 0 Then Exit Sub
On Error GoTo 0
If oWindow Is Nothing Then exit sub
' don't do anything if this is not a listbox window
If oWindow.Type wtListBox Then Exit Sub
' THIS IS a listbox control
' test to make sure it's the window we think it is
If StrComp(UCase(oWindow.parent.className), "NAMELISTWNDCLASS",
vbTextCompare) 0 Then Exit Sub
' and this is the correct listbox of the correct intellisense window of MS
Office
SpeakingIntelliSense = True
If sHighlightColor = "" Then
' and we don't yet know the highlight color
' note: at this point the msaa_onobjectShow has already identified the
listbox window, and has suppressed
' the speech resulting from the up/down arrows (because WE would otherwise
just read the current line of code each time
' an arrow key is pressed when an intellisense list is open).
sHighlightColor = highlightColorString(oWindow)
queue "sayHighlightedItem"
End If ' sHighlightColor = ""
End Sub
' end of example 2


