How do I get a list of child windows without knowing host window names?
I would like to get a list of child windows without knowing in advance whether any child windows exist. Can this be done without otherwise having to iterate over all windows using WinList to see whether any one of them have a child?
Additionally, I would like to be able to get a list of all control bars without knowing in advance whether any exist. Do I also have to iterate over all graphs checking ControlInfo kwControlBar for non-zero sizes?
My interest is to update the LogBook package so that it is generally aware of cases where panels (and control bars) are attached to graphs. My own ImageTools package is an example. I can capture the image and histograms graph windows with the logbook windows functions. I cannot however capture the control panel or control bar without telling the LogBook panel code in advance that it should know this exception.
Before I start down a path to iterate over all graphs looking for attached sub-windows or control bars to each one, any insights are appreciated.
All those things that are part of an owning top-level window require asking the owning window if they exist. We don't have lists of owned objects separate from the owners.
September 19, 2024 at 05:13 pm - Permalink
OK. I will make my iteration list.
Perhaps IP 10 could include a "calling all children" option to return a list of children, with ways to select for panels and whatever else can be placed as children to a host. For example, either case below could be a way to return a string list of panels that are children to a host and return their full sub-window path syntax.
WinList("*",...,"WIN:64",1) <- new (optional) flag to designate children
OR
ChildWinList("*","WIN:64") <- new (optional) approach to search for all children that are panels
I still have to work out how to iterate to find snapshots of control bars on graphs, especially since they could be on any side of the graph. It seems I have to iterate not only on all graph windows but also on width or height, let alone L/R or T/B.
September 19, 2024 at 07:09 pm - Permalink
May I ask what is the problem with iterating over all windows? Is there a performance neck? Or is this more about having a convenient function to get a list of child windows?
September 20, 2024 at 04:35 am - Permalink
Yes, perhaps this is my stubborn desire to have an easy way out of a one-off case that I surely can program on my own. You’ve discovered the weakness in my case.
September 20, 2024 at 08:51 am - Permalink
Follow up question ... How do I get the title (not the name) of a child (sub window) panel? The GetWindow winname wtitle returns a blank in s_value for sub-windows. Am I to parse through the recreation macro for the window to find the string "NewPanel ... as "My Title"" string?
September 20, 2024 at 03:11 pm - Permalink
GetWindow; You can check the "wtitle" keyword.
but for the subwindow, return S_value is set to "".
September 20, 2024 at 08:15 pm - Permalink
Interesting that is does not seem to be easily possible to extract the title of a child window. I constructed the abomination below. See if that works for you:
string childWinTitle = ReplaceString("\"",StringFromList(1,StringFromList(2,WinRecreation(childWinPath,0),"\r")," as "),"")
September 21, 2024 at 03:42 am - Permalink
Clever. Here is my success with SplitString.
string tstr="", rstr="", rexp
rexp = "New.*HOST=#.* as \"(.*)\""
SplitString/E=(rexp) WinRecreation(subwinpath,0), tstr
rstr = StringFromList(0,tstr,"\"")
return rstr
end
I could not get the parsing to split off the excess string content after the second quote no matter how I framed the text after the (.*) capture segment. I could get the parsing to work as I needed in a REGEX test engine. If someone is so inclined to prove their prowess with REGEX within Igor Pro, I include the WinRecreation string as an attachment.
September 21, 2024 at 12:52 pm - Permalink
The one line function that is provide by @chozo should include a check to assure that the command DoWindow $fullwinpath title returns a string length of zero for s_value, thereby assuring that the window in question is an external sub-window.
Function f_isExtSubWindow(string fullwinpath)
variable rtnv
GetWindow $fullwinpath, title
rtnv = strlen(s_value) == 0 ? 1 : 0
return rtnv
end
// parse for window title for sub window
Static Function/S parse_forTitle(string fullwinpath)
string wrec, rstr
wrec = WinRecreation(fullwinpath,0)
rstr = ReplaceString("\"",StringFromList(1,StringFromList(2,wrec,"\r")," as "),"")
return rstr
end
September 21, 2024 at 06:46 pm - Permalink
I see. As for your regex example, my regex-fu is weak, but by fiddling around until it works and got this:
string tstr="", rexp = "New.*HOST=#.* as \"([^\"]*)"
SplitString/E=(rexp) WinRecreation(subwinpath,0), tstr
return tstr
end
... i.e., here the parsing looks for everything other than a ' " ' and then quits apparently.
September 22, 2024 at 03:18 am - Permalink
Again clever! Here now are three functions to administer external sub windows. The first is required because sub-windows (with empty wtitle strings) can also be internal rather than external. The second assures that the wtitle is pulled from the HOST=# external panel (with the presumption that all external panels have a wtitle even when they may not have a title). The third compiles a list of all external panels attached to a window (presumably a graph).
Function f_isExtSubWindow(string fullwinpath)
GetWindow $fullwinpath, exterior
return v_value
end
// parse for window title in an external sub window
Static Function/S parse_forTitle(string fullwinpath)
string rtstr="", rexp = "New.*HOST=#.* as \"([^\"]*)"
SplitString/E=(rexp) WinRecreation(fullwinpath,0), rtstr
return rtstr
end
// return list of names of external sub windows if they exist
Function/S f_LoExtSubWindows(string winpath)
variable ic
string rtstr = "", cwinList, theWin
cwinList = ChildWindowList(winpath)
if (strlen(cwinList) != 0)
for (ic=0;ic<ItemsInList(cwinList);ic+=1)
theWin = winpath + "#" + StringFromList(ic,cwinList)
GetWindow $theWin, exterior
if (v_value)
rtstr += theWin + ";"
endif
endfor
endif
return rtstr
end
With these three functions in the LogBook package, I am now able to capture external panels attached to images or graphs and store their images in the notebook. I attach examples from Spectra Tools (you) and Baselines (Tony). The latter is a sub-panel attached to (my own internal package) sub-panel attached to a graph.
Notice that one should check for GetWindow ... exterior rather than for empty s_value in GetWindow ... wtitle to determine if the window is exterior. This allows that WaveMetrics could change the behavior such that GetWindow ... wtitle returns the window title even with sub-windows.
September 22, 2024 at 10:04 am - Permalink