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:
updated draft of today's scripting class examplesDate:
Sun, Jun 19, 2011 4:49:23 pmI added example 3
' Draft scripting class 16 (6/19/2011)
' another way of getting information you need in order to make a program
accessible, when the information isn't available on the display, is to use
COM automation to interact with the program.
' this class will discuss COM automation, and how you can use it to get
additional information regarding the current program the user is interacting
with, or
' alternatively, how you can use COM automation to completely replace an
inaccessible user interface, by creating one of your own using WE XML
dialogs, and performing all the needed interaction using COM automation.
' example 1:
' this example is designed to run as an application-specific app, associated
with MS Word.
' when Word executes, it runs, and it ties into the current user's Word
session via COM automation,
' so that it can get some information from Word which isn't made obvious on
the display.
' (for this example, the additional information is to notify the user
whenever the line spacing has changed to double spacing)
on error resume next
set wordApp = nothing
set wordApp = getObject(, "word.application") ' note the importance of
omitting the first argument, and just placing a comma
' getObject is used above, instead of createObject(), so that a link to the
currently open Word instance can be established, instead of starting a new
(and independent) instance of Word.
on error goto 0
if not wordApp is nothing then
loadClassInformation wordApp ' loads associated constant declarations
Set wordProc = clientInformation.ApplicationProcess ' used to filter
keystrokes
cursorKeyConn = ConnectEvent(application, "oncursorkey", "oncursorkey")
' only available with 7.1 or later
end if
Function OnCursorKey(cursorKey, isBeforeAction, defaultActionAborted)
' event handler for the onCursorKey event.
Dim useIt: useIt = False
OnCursorKey = false
if not isBeforeAction then
' test to see if this cursor key belongs to Word
On Error Resume Next
If ActiveWindow.Process.ProcessID = wordProc.ProcessID Then useIt = True
on error goto 0
If useIt Then
' this was meant for Word
' this cursor key has just had some effect on Word, so use Word's object
model to get the information we need for our app;
' this could be any information we need when the position of the insertion
point moves around in a document
queue "checkWordInfo"
' if we returned a "true" value for this function, this would prevent
Window-Eyes from seeing this keystroke, so we could handle it in our app
instead
' if we return false, then we just allow WE to handle it as usual, and
perhaps add some additional speech from our app
end if
end if ' not isBeforeAction
end function
sub checkWordInfo()
' here we use our link to Word to see what's happened
If wordApp.selection.ParagraphFormat.LineSpacingRule=wdLineSpaceDouble Then
Speak "double spaced"
' in a real app, this would be enclosed in a "IF", which would test to see
if the current line had changed, since we shouldn't report the line spacing
when the user is just moving along the line
end sub
' end of example 1
' example 2
' shows how you can open a graphical application (MS MapPoint in this
case)using COM automation,
' and then assuming you've defined needed XML dialogs,
' you can then let the user interact with your dialogs, and pass the
interaction in via COM automation, and report the results through your
dialogs.
' the user never has to interact directly with the inaccessible application
because you can completely replace it's inaccessible interface.
'-- Open the Map Point application and get an object reference to it.
Set goMPApp = Nothing
On Error Resume Next
Set goMPApp = CreateObject("MapPoint.Application")
On Error GoTo 0
If Not (goMPApp Is Nothing) Then
loadClassInformation goMPApp
' minimize MapPoint
goMPApp.WindowState = geoWindowStateMinimize ' 1
' hide it's window
goMPApp.Visible = False
goMPApp.UserControl = False
Set goMap = goMPApp.ActiveMap
'turn off optional rendering to increase performance
goMap.BasicRenderingOnly
goMap.Altitude = 1 ' make the active map zoom into a small scale view
goMap.MapStyle = 0 ' road map
Set goCurRoute = goMap.ActiveRoute
goCurRoute.Clear
' now get from the user a destination address, and provide him with the
directions needed to get there from his current location
strDestination = inputBox("Enter your destination address")
Set loFR = goMap.FindResults(pcAddress)
set destinationLoc = loFR(1)
' assume we have another routine (not shown here for brevity) which puts our
current GPS coordinants into a location variable named goCurLoc
goCurRoute.Waypoints.Add goCurLoc, "Me"
goCurRoute.Waypoints.Add destinationLoc, strDestination
On Error Resume Next
goCurRoute.Calculate
On Error GoTo 0
If Not goCurRoute.IsCalculated Then
speakAlertMsg "Unable to calculate a route from here to " & strDestination
Set goCurRoute = Nothing
else
s = ""
for each dir in goCurRoute.directions
s = s & dir.instruction & vbcr
next
msgBox s, vbOKOnly, "Directions"
End If
end If ' Not (goMPApp Is Nothing)
' end of example 2
' example 3
' another example showing how to get additional info from a running program
using COM automation, but this time without knowing which program's object
model to use
' therefore, in some cases, you can use a property of the window of the
program, which returns a COM object model which is a "standard" type for
that window.
' the property is somewhat equivalent to use of getObject(), except you do
not need to specify the object model name.
' the window property which may hold this COM automation object is
..nativeObjectModel
' in this example, taken from the app "Relative Position", it finds a
focused window whose type is "rich edit" IN ORDER TO PROVIDE ROW AND COLUMN
INFO FOR THE CURSOR.
'it does this by relying on a standard object model named "The MicrosoftR
Text Object Model (TOM) ".
' a site which provides documentation for this object model is
http://en.wikipedia.org/wiki/Text_Object_Model
' first it gets the COM interface for the currently focused window, which it
has already determined to be a rich edit control
' (which is one of the window types known to use this object model)
Const tomForward73741823
on error resume next
Set oFocusedDocument = oFocusedWindow.NativeObjectModel
On Error GoTo 0
If oFocusedDocument Is Nothing Then Exit Function
sText = oFocusedDocument.Range(0, tomForward).Text
iPosition = oFocusedDocument.Selection.End
SayDocumentPosition sText, iPosition
Function SayDocumentPosition(sText, iPosition)
Dim i, iCount, iLine, iColumn, iPercent
Dim s
s = Left(sText, iPosition + 1)
i = Len(s)
iLine = i - Len(Replace(s, vbCr, "")) + 1
iColumn = i - InStrRev(s, vbCr)
If Right(sText, 1) = vbCr Then
sText = Left(sText, Len(sText) - 1)
Else
iColumn = iColumn + 1
End If
Speak "Line " & iLine
Speak "Column " & iColumn
SayPercent Len(sText), iPosition + 1
End Function
' end of example 3
' Draft scripting class 16 (6/19/2011)
' another way of getting information you need in order to make a program
accessible, when the information isn't available on the display, is to use
COM automation to interact with the program.
' this class will discuss COM automation, and how you can use it to get
additional information regarding the current program the user is interacting
with, or
' alternatively, how you can use COM automation to completely replace an
inaccessible user interface, by creating one of your own using WE XML
dialogs, and performing all the needed interaction using COM automation.
' example 1:
' this example is designed to run as an application-specific app, associated
with MS Word.
' when Word executes, it runs, and it ties into the current user's Word
session via COM automation,
' so that it can get some information from Word which isn't made obvious on
the display.
' (for this example, the additional information is to notify the user
whenever the line spacing has changed to double spacing)
on error resume next
set wordApp = nothing
set wordApp = getObject(, "word.application") ' note the importance of
omitting the first argument, and just placing a comma
' getObject is used above, instead of createObject(), so that a link to the
currently open Word instance can be established, instead of starting a new
(and independent) instance of Word.
on error goto 0
if not wordApp is nothing then
loadClassInformation wordApp ' loads associated constant declarations
Set wordProc = clientInformation.ApplicationProcess ' used to filter
keystrokes
cursorKeyConn = ConnectEvent(application, "oncursorkey", "oncursorkey")
' only available with 7.1 or later
end if
Function OnCursorKey(cursorKey, isBeforeAction, defaultActionAborted)
' event handler for the onCursorKey event.
Dim useIt: useIt = False
OnCursorKey = false
if not isBeforeAction then
' test to see if this cursor key belongs to Word
On Error Resume Next
If ActiveWindow.Process.ProcessID = wordProc.ProcessID Then useIt = True
on error goto 0
If useIt Then
' this was meant for Word
' this cursor key has just had some effect on Word, so use Word's object
model to get the information we need for our app;
' this could be any information we need when the position of the insertion
point moves around in a document
queue "checkWordInfo"
' if we returned a "true" value for this function, this would prevent
Window-Eyes from seeing this keystroke, so we could handle it in our app
instead
' if we return false, then we just allow WE to handle it as usual, and
perhaps add some additional speech from our app
end if
end if ' not isBeforeAction
end function
sub checkWordInfo()
' here we use our link to Word to see what's happened
If wordApp.selection.ParagraphFormat.LineSpacingRule=wdLineSpaceDouble Then
Speak "double spaced"
' in a real app, this would be enclosed in a "IF", which would test to see
if the current line had changed, since we shouldn't report the line spacing
when the user is just moving along the line
end sub
' end of example 1
' example 2
' shows how you can open a graphical application (MS MapPoint in this
case)using COM automation,
' and then assuming you've defined needed XML dialogs,
' you can then let the user interact with your dialogs, and pass the
interaction in via COM automation, and report the results through your
dialogs.
' the user never has to interact directly with the inaccessible application
because you can completely replace it's inaccessible interface.
'-- Open the Map Point application and get an object reference to it.
Set goMPApp = Nothing
On Error Resume Next
Set goMPApp = CreateObject("MapPoint.Application")
On Error GoTo 0
If Not (goMPApp Is Nothing) Then
loadClassInformation goMPApp
' minimize MapPoint
goMPApp.WindowState = geoWindowStateMinimize ' 1
' hide it's window
goMPApp.Visible = False
goMPApp.UserControl = False
Set goMap = goMPApp.ActiveMap
'turn off optional rendering to increase performance
goMap.BasicRenderingOnly
goMap.Altitude = 1 ' make the active map zoom into a small scale view
goMap.MapStyle = 0 ' road map
Set goCurRoute = goMap.ActiveRoute
goCurRoute.Clear
' now get from the user a destination address, and provide him with the
directions needed to get there from his current location
strDestination = inputBox("Enter your destination address")
Set loFR = goMap.FindResults(pcAddress)
set destinationLoc = loFR(1)
' assume we have another routine (not shown here for brevity) which puts our
current GPS coordinants into a location variable named goCurLoc
goCurRoute.Waypoints.Add goCurLoc, "Me"
goCurRoute.Waypoints.Add destinationLoc, strDestination
On Error Resume Next
goCurRoute.Calculate
On Error GoTo 0
If Not goCurRoute.IsCalculated Then
speakAlertMsg "Unable to calculate a route from here to " & strDestination
Set goCurRoute = Nothing
else
s = ""
for each dir in goCurRoute.directions
s = s & dir.instruction & vbcr
next
msgBox s, vbOKOnly, "Directions"
End If
end If ' Not (goMPApp Is Nothing)
' end of example 2
' example 3
' another example showing how to get additional info from a running program
using COM automation, but this time without knowing which program's object
model to use
' therefore, in some cases, you can use a property of the window of the
program, which returns a COM object model which is a "standard" type for
that window.
' the property is somewhat equivalent to use of getObject(), except you do
not need to specify the object model name.
' the window property which may hold this COM automation object is
..nativeObjectModel
' in this example, taken from the app "Relative Position", it finds a
focused window whose type is "rich edit" IN ORDER TO PROVIDE ROW AND COLUMN
INFO FOR THE CURSOR.
'it does this by relying on a standard object model named "The MicrosoftR
Text Object Model (TOM) ".
' a site which provides documentation for this object model is
http://en.wikipedia.org/wiki/Text_Object_Model
' first it gets the COM interface for the currently focused window, which it
has already determined to be a rich edit control
' (which is one of the window types known to use this object model)
Const tomForward73741823
on error resume next
Set oFocusedDocument = oFocusedWindow.NativeObjectModel
On Error GoTo 0
If oFocusedDocument Is Nothing Then Exit Function
sText = oFocusedDocument.Range(0, tomForward).Text
iPosition = oFocusedDocument.Selection.End
SayDocumentPosition sText, iPosition
Function SayDocumentPosition(sText, iPosition)
Dim i, iCount, iLine, iColumn, iPercent
Dim s
s = Left(sText, iPosition + 1)
i = Len(s)
iLine = i - Len(Replace(s, vbCr, "")) + 1
iColumn = i - InStrRev(s, vbCr)
If Right(sText, 1) = vbCr Then
sText = Left(sText, Len(sText) - 1)
Else
iColumn = iColumn + 1
End If
Speak "Line " & iLine
Speak "Column " & iColumn
SayPercent Len(sText), iPosition + 1
End Function
' end of example 3




