I'm needing to detect a partial window name where I know the beginning and ending of the window name, but not the middle. Using standard wildcard string matching, here's what I'm after:
"ABC*XYZ"
where the * is an unknown number of undetermined characters.
Is there anyway to do this with a partial window name?
From the Consolidated WIL Help file:
Exact Match
Those WIL functions which take a partial windowname as a parameter can be directed to accept only an exact match by ending the window name with a tilde (~).
A tilde (~) used as the last character of the window name indicates that the name must match the window title through to the end of the title. For example, WinShow("Note~") would only match a window whose title was "Note"; it would not match "Notepad".
Match Any Window
A tilde (~) used as the first character of the window name, will match any window containing the specified string anywhere in its title. For example, WinShow("~Notepad") will match a window title of "(Untitled) - Notepad" and a window title of "My Notepad Application", as well as a window title of "Notepad - (Untitled)".
Window Name Ends With…
A tilde (~) used as the first and last character of the window name, will match any window containing the specified string anywhere in its title, except at the beginning. For example, WinShow("~Notepad~") will match a window title of "Notepad" and a window title of "(Untitled) -Notepad", but will not match a window title of "Notepad - (Untitled)".
Note: All functions that accept a partial window name also accept a Windows ID.
So the short answer is no.
However, you could implement your own find window by perhaps using the WinItemize function to obtain a fill list of window names and then using either the COM Automation "vbscript.regexp" object or dotNet"System.Text.RegularExpressions.Regex"class to search the list.
Thanks, td. I did look at the documentation before posting.
I can run with the WinItemize suggestion, thank you!
Untested, but I think this will do the job for me:
#DefineFunction WinExistWild(WildString)
allwins = WinItemize()
result = @FALSE
n = ItemCount(allwins, @TAB)
For i = 1 to n
eachwin = ItemExtract(i, allwins, @TAB)
If StrIndexWild(eachwin, WildString, 1) > 0 Then
result = @TRUE
Break
Endif
Next n
Return result
#EndFunction
A regular expression example that may or may not be faster when a lot of windows are open:
Run("NotePad.exe","")
lWinNames = WinItemize()
strWinName = ''
objRegEx = CreateObject("vbscript.regexp")
objRegEx.Global = @True
objRegEx.IgnoreCase = @True
objRegEx.Pattern = "no[a-zA-Z_0-9]*ad"
colRegEx = objRegEx.Execute(lWinNames)
For i = 0 To colRegEx.Count - 1
strWinName = colRegEx.Item(i).value ;.SubMatches(0)
break
Next
Message("Found Window Names", strWinName)
if strWinName != '' then WinClose('~':strWinName)
exit
More fun with regular expressions:
Run("NotePad.exe","")
strWinName = ''
ObjectClrOption("useany", "System")
objRegEx = objectClrNew("System.Text.RegularExpressions.Regex")
; Patter matches from begining of an item list item up to but not including the next @tab
; In this case it matches the no...ad of Notepad.
strPattern = '(([A-Za-z0-9\- ]*)no([A-Za-z0-9\- ]+)ad([A-Za-z0-9\- ]*))'
lWinNames = WinItemize()
; (System.Text.RegularExpressions.RegexOptions:1 means ignore case.)
objMatches = objRegEx.Matches(lWinNames , strPattern, System.Text.RegularExpressions.RegexOptions:1)
x = 0
foreach objMatch in objMatches
strWinName := objMatch.Groups.Item(1).Value
if strWinName != '' then WinClose(strWinName)
break ; Assume one match but can be easily modifited to handle multiple matches.
next
Message("Found Window Names", strWinName)
exit