This looks good. I am finding that outside of the Visual Studio environment there are allot of companies who don't use MSAA to describe objects. Even in VS I have found dialogs and stuff where there is no MSAA information for an object. So, using other event and object analysis techniques is a must. I have never looked at anything other than the MSAA OnFocus Event since it worked for what I needed at the time. Now I am ready, thanks to your class, to tackle some other methods of a quick analysis tool to add to the MSAA tool I am playing with. Perhaps a second hot key to pick up an object under the cursor, some Child Objects like your example or something else to do If I click the hot key for the MsAA information and hear there is no MSAA Information for the object in question.
The class is starting to get fun!
Later Chip and see you tomorrow evening in class.
Rick USA
----- Original Message ----- From: "Chip Orange" <[email protected]>
To: <[email protected]>
Sent: Saturday, April 09, 2011 3:53 PM
Subject: early draft of scripting class examples for 4/10


*** warning: below contains the answer to the homework assignment; don't
read if you're still trying to work this out yourself.




' Early Draft of class #8 examples:  (4/10/2011)


' example 1
' using an event handler to watch newly opened windows.
' and another event handler to watch closing windows.
' (this is a modified version of a script from last week)

option explicit
' this is a fully working script, which you could load on your system by:

dim  n1, n2
dim NP
set NP = createObject("scripting.dictionary") ' this dictionary will hold
the titles of all NotePad windows




' now use the window object's onChildCreate event, and do it on the desktop
window itself, to look for new windows
' (remember the desktopWindow is a "root level" object because it's a
property of the application object, which is always available).

n1 = connectEvent ( desktopWindow , "onChildCreate", "myNewWindowHandler")

' now look at windows which close, and take them out of the dictionary to
prevent false reports.

n2 = connectEvent (desktopWindow, "onChildClose", "myCloseWindowHandler")


' end of main body


sub myNewWindowHandler(win)
' this is the event handler for the onChildCreate event of the desktop
window

' since we may say something, and we also need to pause slightly to allow
the application to have time enough to set the window title, we have to use
the queue method
queue "checkWin", win

end sub

sub checkWin(win)

sleep 500 ' give application half a second to initialize window

' below tests to see if we have a top level window (we haven't covered this
yet, just take my word)
if win.style.overlapped or win.style.MDIChild then
' it is an application top-level window
 if win.className = "Notepad" then
' it's a notepad document window
   if NP.exists(win.title) then
' found this window title in the dictionary
     silence
sleep 1000 ' pause one second after going quiet
     speak "Warning! " & win.title & " is opened more than once!"
   else
' first time opening, just add it (with it's handle) to the dictionary
     NP.add win.title, win.handle
   end if '  NP.exists(win.title)
 end if '  win.className = "Notepad"
end if '  win.style.overlapped or win.style.MDIChild

end sub



sub myCloseWindowHandler(handle)
' this is a onChildClose handler which gets called for all windows
' (it doesn't do anything time consuming, so we don't need to use a queue
command)

dim curTitle

' search our dictionary for this handle, and if it's found, remove this
entry
for each curTitle in NP.keys
' note the use of .exists below; without it, we'd create an NP entry just by
looking for it
 if NP.exists(curTitle) then
   if NP(curTitle) = handle then
     NP.remove(curTitle) ' remove this dictionary entry
   end if
 end if
next

end sub

' end of example 1




' example 2
' using an event handler to watch newly opened windows.
' and another event handler to watch when the opened window closes.
' (this is a modified version of the script above; it handles windows
closing in a different way)

option explicit
' this is a fully working script, which you could load on your system by:

dim  n
dim NP
set NP = createObject("scripting.dictionary") ' this dictionary will hold
the titles of all NotePad windows

' now use the window object's onChildCreate event, and do it on the desktop
window itself, to look for new windows
' (remember the desktopWindow is a "root level" object because it's a
property of the application object, which is always available).

n = connectEvent ( desktopWindow , "onChildCreate", "myNewWindowHandler")


' end of main body


sub myNewWindowHandler(win)
' this is the event handler for the onChildCreate event of the desktop
window

' since we may say something, and we also need to pause slightly to allow
the application to have time enough to set the window title, we have to use
the queue method
queue "checkWin", win

end sub

sub checkWin(win)

sleep 500 ' give application half a second to initialize window

' below tests to see if we have a top level window (we haven't covered this
yet, just take my word)
if win.style.overlapped or win.style.MDIChild then
' it is an application top-level window
 if win.className = "Notepad" then
' it's a notepad document window
   if NP.exists(win.title) then
' found this window title in the dictionary
     silence
sleep 1000 ' pause one second after going quiet
     speak "Warning! " & win.title & " is opened more than once!"
   else
' first time opening, just add it (with it's handle) to the dictionary
     NP.add win.title, win.handle
' now set things up so the window closing event is only called for a
dictionary window, and not all windows
' (the window we use to connect to it's event is the window which just
opened, not the desktopWindow as before)
connectEvent win, "onClose", "myCloseWindowHandler" ' this connects to
a different event from example 1
' (this event only tells us when this specific window closes, not when all
children windows closed as did example 1).
   end if '  NP.exists(win.title)
 end if '  win.className = "Notepad"
end if '  win.style.overlapped or win.style.MDIChild

end sub

sub myCloseWindowHandler(handle)
' this is an onClose event handler; it gets called for only windows in our
NP dictionary, and so a lot less often than example 1

dim curTitle

' search our dictionary for this handle, and if it's found, remove this
entry
for each curTitle in NP.keys
' note the use of .exists below; without it, we'd create an NP entry just by
looking for it
 if NP.exists(curTitle) then
   if NP(curTitle) = handle then
     NP.remove(curTitle) ' remove this dictionary entry
   end if
 end if
next

end sub

' end of example 2


' note that these examples still have a problem: if the user opens the same
file 3 times or more, then closes down two of the files, and then with one
still open opens a second occurance, it will not give a warning message!
' (welcome to the world of real scripting debugging!)



' example 3
' this is a modified version of the script above; it handles Notepad windows
in a different way;
'  instead of using a dictionary, it uses a method of the "windows"
collection (a property of the application object, and so a "root level"
object).
' the method it uses (filterByTitle) examines all the currently open windows
which have a given title.
' this technique solves the problem mentioned at the end of example 2 with
having more than two windows open with the same title, and allows us not to
have to use a dictionary at all.

option explicit
' this is a fully working script, which you could load on your system by:

dim  n

' now use the window object's onChildCreate event, and do it on the desktop
window itself, to look for new windows
n = connectEvent ( desktopWindow , "onChildCreate", "myNewWindowHandler")


' end of main body


sub myNewWindowHandler(win)
' this is the event handler for the onChildCreate event of the desktop
window

' since we may say something, and we also need to pause slightly to allow
the application to have time enough to set the window title, we have to use
the queue method
queue "checkWin", win

end sub

sub checkWin(win)

dim objWins , objCurWin

sleep 500 ' give application half a second to initialize window
' below tests to see if we have a top level window (we haven't covered this
yet, just take my word)
if win.style.overlapped or win.style.MDIChild then
' it is an application top-level window
 if win.className = "Notepad" then
' it's a notepad document window
 set objWins = windows.filterByTitle(win.title) ' returns a collection of
currently open windows with a given title
 for each objCurWin in objWins
     if objCurWin.handle <> win.handle then
' this isn't the window being opened at the moment
       if objCurWin.className = "Notepad" then
' it's a notepad document window
         silence
         sleep 1000 ' pause one second after going quiet
         speak "Warning! " & win.title & " is opened more than once!"
       end if '  objCurWin.className =  = "Notepad"
     end if ' objCurWin.handle <> win.handle
   next
 end if '  win.className = "Notepad"
end if '  win.style.overlapped or win.style.MDIChild

end sub

' end of example 3



Below are select properties, methods, and events of the application object,
which you are most likely to use.
All of the properties and methods are "root level", and so can be access
without having to use the application. as part of their names.


Properties:
ActiveMDIChild
ActiveWindow
ClientInformation
DesktopWindow
FocusedWindow
INIFile
Keyboard
Mouse
MSAAEventSource
Screen
SharedObjects
Speech
Text
Utilities
Windows

Methods:
Dialog
ExecuteHotkey
Menu
PlaySound
ScreenPoint
ScreenRectangle
Strings

Events:
OnCursorKey
OnHotkey
OnQuit

Below are select properties, methods, and events of the window object, which
you are most likely to use.

Properties:
Accessible
AlwaysOnTop
Children
ClassName
DirectChildren
Enabled
FieldName
Handle
IsValid
ModuleName
Name
NativeObjectModel
OnScreenVisibility
OriginalClassName
OriginalType
Overlap
Parent
Process
Status
Style
Title
Type
Visible

Methods:
Activate
ClientPoint
ClientRectangle
Clips
Close
Control
Focus
WindowPoint
WindowRectangle

Events:
OnAfterChildSelect
OnAfterSelect
OnBeforeChildSelect
OnBeforeSelect
OnChildFieldData
OnChildFieldName
OnChildSelection
OnChildSummary
OnFieldData
OnFieldName
OnActivate
OnBlur
OnChildActivate
OnChildBlur
OnChildClipRendered
OnChildClose
OnChildCreate
OnChildDeactivate
OnChildFocus
OnClipRendered
OnClose
OnDeactivate
OnFocus
OnMDIActivate
OnMDIChildActivate
OnMDIChildDeactivate
OnMDIDeactivate
OnMenuOpened
OnMenuClosed
OnMenuSelection
OnSelection
OnSummary



Reply via email to