Hi Chip, OK, at least there are some examples and this is another class that used clips. I will search and see if I have something about them. Bruce
' Scripting class 24 (8/14/2011) ' Doing things with colors of text. ' example 1: ' this example is taken from a routine in a Word related app, which reads the status bar for Word XP/2003. ' the point of the example is in showing how to deal with elements on the display whose color, not their text, conveys the needed information. Function readStatusBar() ' replaces the WE read status bar functionality in a Word document Dim sbWin Dim w Dim winList Dim strLine Dim i Dim j Dim c readStatusBar = False ' find the status bar window If Not ActiveWindow.overlap Is Nothing Then Set winList = ActiveWindow.overlap.children.FilterByName("_WwC") Set sbWin = Nothing For Each w In winList If Len(w.clips.ClipsText) > 0 Then ' looks like the status bar If sbWin Is Nothing Then Set sbWin = w End If End If ' Len(w.clips.ClipsText) > 0 Next If Not sbWin Is Nothing Then ' have a status bar to work with strLine = Trim(sbWin.clips.ClipsText) ' first speak the elements on the status bar whose text is the information ' code removed here which just breaks apart the status bar elements, and speaks each element with a descriptive label to make it more understandable ' remainder of the status bar is strings where the foreground color is significant, not the strings themselves ' (black indicates an option is on, gray indicates that it's off) ' (black is a color where all 3 color components (red, green, and blue) are 0) ' (white has all 3 components set to 255) ' (all other colors are some mix; I believe Word uses a gray made up of 3 values of 128) ' since a string variable doesn't hold any color information, we have to go to the clips collection which make up the status bar, and locate each clip for one of these "colored" elements For Each c In sbWin.clips If c.Type = ctText Then ' this is a text clip Select Case UCase(Trim(c.text)) Case "REC" ' this is one of the "colored" elements If c.ForegroundColor.Red = 0 Then ' this is black (on) Speak "recording a macro, " End If Case "EXT" ' this is one of the "colored" elements If c.ForegroundColor.Red = 0 Then ' this is black (on) Speak "extended selection mode, " End If Case "TRK" ' this is one of the "colored" elements If c.ForegroundColor.Red = 0 Then ' this is black (on) Speak "tracked changes is on, " End If Case "OVR" ' this is one of the "colored" elements If c.ForegroundColor.Red = 0 Then ' this is black (on) Speak "overtype mode." End If End Select End If ' C.Type = ctText Next readStatusBar = True End If ' Not sbWin Is Nothing End If ' Not ActiveWindow.overlap Is Nothing End Function ' end of example 1 ' example 2: ' showing how to manually find out if a clip is highlighted or not, and how to speak highlighted clips dim oCurClip dim oWindow dim sColorString dim oBackgrounds dim highlightColorString dim s ' first run through the clips of this window and determine which background color combination is used only one time (and so, likely to indicate something highlighted) ' background colors are stored as a string of 6 hex characters (2 for each color component), so they can easily be compared to one another Set oBackgrounds = CreateObject("scripting.dictionary") ' used to keep track of the number of clips for each background color For Each oCurClip In oWindow.clips(, False) If oCurClip.Type = ctText Or oCurClip.Type = ctFakeText Then sColorString = Hex(oCurClip.BackgroundColor.Red) & Hex(oCurClip.BackgroundColor.Green) & Hex(oCurClip.BackgroundColor.Blue) If oBackgrounds.Exists(sColorString) Then oBackgrounds(sColorString) = oBackgrounds(sColorString) + 1 Else oBackgrounds.Add sColorString, 1 End If End If Next ' now look for the one combo which only occurs once highlightColorString = "" For Each s In oBackgrounds.keys If oBackgrounds(s) = 1 Then ' this background color combo only appears once in the clips collection ' this is the highlight background highlightColorString = s Exit Function End If Next function speakClipIfHighlighted(clip) ' now determine if the current clip being evaluated is highlighted, and if so speak it dim sBackColor sBackColor = Hex(clip.BackgroundColor.Red) sBackColor = sBackColor & Hex(clip.BackgroundColor.Green) sBackColor = sBackColor & Hex(clip.BackgroundColor.Blue) if (sBackColor = sHighlightColor) then speak clip.text end function ' or, if you want the highlighted text of the window we were working with, you can just use this method: speak oWindow.clips.SearchText("", False, True).clipsText ' speaks highlighted text ' the above method searches the entire clips collection for the empty string, which matches all text, has false for the case match, and has true for the highlighted text only parameter. ' it returns a clips collection, and we speak the clipsText property. ' end of example 2 ' example 3: ' how to get a description of a color set of components speak ActiveColorDictionaries.Lookup(clip.ForegroundColor).Translation ' end of example 3 ' archives of these classes can be found at: ' https://www.gwmicro.com/App_Central/Developers/Interactive_Classes/ Sent: Friday, September 13, 2013 8:31 PM Subject: RE: text.nextline Thanks Bruce. However, it wasn't my scripting class I failed to backup, but for some reason the wiki articles which I wrote. I don't know why but I didn't backup any of them. Chip From: BX [mailto:bronx_...@fltg.net] Sent: Friday, September 13, 2013 8:23 PM To: gw-scripting@gwmicro.com Subject: Re: text.nextline Chip, Class 15 examples. below are draft examples for tomorrow's class: ' draft Scripting class 15 (6/12/2011) ' example 1: ' shows how to find the app manager window, find the listview control it is displaying, and find the name of the .vbs file ' currently highlighted. ' (these are all techniques which you may use in many of your apps) dim hk ' setup a hotkey to speak the currently highlighted app's .vbs file name set hk = keyboard.registerHotkey("alt-control-i", "sayIt") sub sayIt() Dim wins Dim kids Dim appman Dim lv ' first find the app manager window using it's title Set wins = windows.FilterByTitle("App Manager") If wins.Count = 1 Then ' found it Set appman = wins(1) ' now find the window of it's listview control, which is known to be named "List3" Set kids = appman.Children.FilterByName("List3") If kids.Count = 1 Then ' found it ' now use the control property of this window, which allows us access to all control properties Set lv = kids(1).Control ' note: if we needed to know the index number of the selected row, it can be found in lv.items.Selected(1).index speak "The selected app has a .vbs file named " & _ lv.text(, 3) ' 3rd column has the .vbs file name ' note: omitting the first argument to the .text method above causes it to use the currently selected row End If ' kids.Count = 1 End If ' wins.Count = 1 end sub ' end of example 1 ' example 2: ' this example shows you how to get the entire text of the statusbar window in Notepad ' (it could be used as an example of how to get the entire text of any window or one of it's child windows) dim objMainWindow dim objStatusBarWindow dim objResults set objMainWindow = activeWindow.overlap ' assumes Notepad is the active application ' below assumes you have used TreeView to find that the statusbar is in it's own window by the name of "msctls_statusbar32" set objResults = objMainWindow.children.filterByName("msctls_statusbar32") if not objResults is nothing then if objResults.count > 0 then ' found the window! set objStatusBarWindow = objResults(1) ' this gets the first window of the collection which was returned by the search ' now speak it's contents speak objStatusBarWindow.clips.clipstext ' the .clips property above holds all the text of a window, broken down into it's various clips. ' if you want *all* of the text in the window, you can get it from a property of the clips collection named clipsText, which holds it all in one big string end if end if ' end of example 2 ' Example 3: ' shows how to get the text of a specific line of an overlap window using the Text object. ' the text object is very versatile, allowing you to navigate through an overlap window going a character, word, sentence, or line at a time. ' Sometimes though the text you want to examine can best be specified by it's location ' on the screen; in particular, by it's location within the overlap window of the application. ' In this case, you may not want to use all the text in a window object, but just the ' text at a certain place on the display. The place is usually specified by screen ' point X and Y coordinants, or by 4 coordinants which define an enclosing rectangle ' (by defining the location of it's top, bottom, left, and right sides). This has the ' possibility to return to you text contained in multiple child windows, or in multiple ' clipps, which are physically adjacent to one another on the screen, but which may ' not be stored together in one easily accessed data structure. ' In this example, the WECursor object's position is used to retrieve a line of text, ' from whatever window object the WECursor object is positioned within. This line of ' text may be the result of text from more than one child window object, and/or more than ' one of it's clips. dim sText dim oMonitorPosition, oText dim lineClips Set oMonitorPosition = WECursor.Position ' property returns x and y screen coordinants Set oText = Text ' A copy of the Text root level object is made, into the oText variable. This is done ' because some of the methods of the Text object keep track of data (such as the last ' position you used as input to one of it's methods),so that they can then implement ' functionality such as "previous line". This requires the object to be able to modify ' itself to store these values, and in such cases, if you don't make a copy of the ' object (which your script then owns), the copy of the object owned by WE will not ' allow your script to modify it; therefore, functionality such as "previous line" ' will not function properly, as the previous position will not be saved. The MSAAEventSource ' is another such object which may require you to make a copy of it in order to use ' it fully. set lineClips = oText.Line(oMonitorPosition) ' the line method actually returns a clips object, and one property of the clips object ' is the clipsText string, which contains all of the text in all of the clips, concatenated ' together into one long string. sText = lineClips.ClipsText ' Points for the Example Above ' first, the position of the WE cursor is determined, and returned to the script as ' a screenPoint object. ' next, this position is passed into the line method of the text object, which returns ' a line of text (as represented by a clips collection), where the line is specified ' by the position passed in, and, the bounderies of the overlap window containing the screenPoint ' (this is not obvious from reading the script, but is explained in the documentation ' of the line method and the enclosingRectangle property of the text object). This prevents .line from giving you text ' which may have "bled over" from windows next to, or under, the one you are working ' with. ' end of example 3 Sent: Thursday, September 12, 2013 7:50 PM Subject: RE: text.nextline Jonathin, I think I had written a wiki article on the use of these methods and the "text" object to retrieve text; perhaps Aaron would post it here or in their KB as the wiki is gone and I didn't save copies of all the articles I had written, and I can't find any of them on the KB. I seem to recall it mentioned several documentation errors or omisions which were really helpful to know. I'm just going from memory here, but I don't think it's documented that you need to make your own copy of the text object to work with for these methods to work properly. Also, by default, the enclosing rectangle is that of the active window. It could be that these things are documented, just very hard to find. I believe I covered this article in class #15, as well as other methods for getting text from the display (some of them either more reliable or easier than using the text object). This is why the wiki was so important (if there was no other reason, it gave us a way to correct and update/ogment documentation deficiencies). Hth, Chip Chip From: Jonathan C. Cohn [mailto:jon.c.c...@gmail.com] Sent: Thursday, September 12, 2013 7:43 AM To: gw-scripting@gwmicro.com Subject: text.nextline I understand that text.nextline(aScreenPoint) will return a set of clips and that there is a bounding rectangle of some kind associated with the method. I do have two questions. 1. Is the aScreenPointer then updated to the new line of text so conseccutive calls would return new clips? How is the bounding rectangle specified? Thanks, Jonathan Cohn