A filtered list of all controls in a window, including subwindows
harneit
If you have ever tried to make your functions aware of subwindows, you might have missed a function that returns a list of all controls in a window, regardless of whether they are in the main window or in a subwindow. The function given below is highly configurable (you can filter by match strings and/or control types, recurse through child windows...), please consult the comments in the snippet.
print ControlList("graph0#p1","button","m:*_tab0;r:children")
returns a list of all button
s in the subwindow graph0#p1
or its subwindows (=children), but only if their names end in _tab0
-- a sample output would be graph0#p1 button0_tab0;graph0#p1 button1_tab0;graph0#p1#p0 button0_tab0;
.Here's the full snippet...
strconstant ksCtrlTypes = "Button;CheckBox;PopupMenu;ValDisplay;SetVariable;Chart;"
ksCtrlTypes += "Slider;TabControl;GroupBox;TitleBox;ListBox;CustomControl"
// function/S ControlList(hostNameStr, typeStr, optionsStr)
// returns a complete list of controls in a window or subwindow, selected by type and other options.
//
// hostNameStr can be a window name like "graph0" or a subwindow spec like "graph0#P0"
//
// typeStr can be either a literal like "button", "checkbox" etc.
// or a number (as string) like "33" that follows a Bit Parameter logic:
// button = 1 = 2^0, checkbox = 2 = 2^1, ... chart = 32 = 2^5, etc. (see ksCtrlTypes)
// bitwise combinations match more than one type, e.g. 33 = button or chart
// the number 4095 = 2^12 - 1 matches any type
//
// optionsStr = "M:pop*_tab0" matches all controls that start with "pop" and end with "_tab0"
// optionsStr = "R:children" returns all controls starting from hostNameStr
// optionsStr = "R:full" forces full recursion from the top host
// (e.g. from graph0 when called with hostNameStr = "graph0#P0")
// you can combine different options by putting them in a list like "M:pop*;R:full"
//
// the output format is chosen to be convenient for appending each list item to "ControlInfo/W="
// you might want to change this - look for "OUTPUT FORMAT"
//
function/S ControlList(hostNameStr, typeStr, optionsStr)
string hostNameStr, typeStr, optionsStr
// 1. convert typeStr to type, quit if that does not work
variable type = str2num(typeStr) // if a number is specified, bit-logic is assumed
if( numType(type) == numType(NaN) ) // if not a number, typeStr must be literal like "chart"
type = 2^WhichListItem(typeStr, ksCtrlTypes, ";", 0, 0) // case-insensitive
if( type < 1 ) // WhichListItem returned -1? Then we dont know about this type
return ""
endif
endif
// 2. build a list of subwindows to search through
string recurseStr = StringByKey("R", optionsStr), swList
if( !cmpstr(recurseStr, "full") ) // case insensitive
swList = SubWindowList( StringFromList(0, hostNameStr, "#") )
elseif( !cmpstr(recurseStr, "children") )
swList = SubWindowList( hostNameStr )
else
swList = hostNameStr
endif
// 3. get the ControlNameList for each subwindow, filter for types
string matchStr = StringByKey("M", optionsStr)
string outputList = "", ctrlList, subwin, ctrl
variable k, n
for( k = 0; k < ItemsInList(swList); k += 1 )
subwin = StringFromList(k, swList)
if( WinType(subwin) != 1 && WinType(subwin) != 7 ) // graphs and panels only
continue // bypass rest of for(k...) loop
endif
ctrlList = ControlNameList(subwin, ";", matchStr) // filter by match string
for( n = 0; n < ItemsInList(ctrlList); n += 1 )
ctrl = StringFromList(n, ctrlList)
if( type & GetControlType(subwin, ctrl) ) // filter by type
outputList += subwin + " " + ctrl + ";" // OUTPUT FORMAT for ControlInfo/W=...
endif
endfor
endfor
return outputList // RemoveEnding(outputList) if you prefer
end
// return the type of a control in bit parameter logic (see ControlList above)
// if the control is not found, a "1/2" will be returned
function GetControlType(winNameStr, ctrlNameStr)
string winNameStr, ctrlNameStr
ControlInfo/W=$winNameStr $ctrlNameStr
return 2^( abs(V_flag) - 1 )
end
// return a (recursive) list of all child windows with full host specs
function/S SubWindowList(hostNameStr)
string hostNameStr
string childList = ChildWindowList(hostNameStr), swList = hostNameStr + ";"
variable n
for( n = 0; n < ItemsInList(childList); n += 1 )
swList += SubWindowList(hostNameStr+"#"+StringFromList(n, childList)) + ";"
endfor
return RemoveEnding(swList) // necessary to avoid empty items
end
ksCtrlTypes += "Slider;TabControl;GroupBox;TitleBox;ListBox;CustomControl"
// function/S ControlList(hostNameStr, typeStr, optionsStr)
// returns a complete list of controls in a window or subwindow, selected by type and other options.
//
// hostNameStr can be a window name like "graph0" or a subwindow spec like "graph0#P0"
//
// typeStr can be either a literal like "button", "checkbox" etc.
// or a number (as string) like "33" that follows a Bit Parameter logic:
// button = 1 = 2^0, checkbox = 2 = 2^1, ... chart = 32 = 2^5, etc. (see ksCtrlTypes)
// bitwise combinations match more than one type, e.g. 33 = button or chart
// the number 4095 = 2^12 - 1 matches any type
//
// optionsStr = "M:pop*_tab0" matches all controls that start with "pop" and end with "_tab0"
// optionsStr = "R:children" returns all controls starting from hostNameStr
// optionsStr = "R:full" forces full recursion from the top host
// (e.g. from graph0 when called with hostNameStr = "graph0#P0")
// you can combine different options by putting them in a list like "M:pop*;R:full"
//
// the output format is chosen to be convenient for appending each list item to "ControlInfo/W="
// you might want to change this - look for "OUTPUT FORMAT"
//
function/S ControlList(hostNameStr, typeStr, optionsStr)
string hostNameStr, typeStr, optionsStr
// 1. convert typeStr to type, quit if that does not work
variable type = str2num(typeStr) // if a number is specified, bit-logic is assumed
if( numType(type) == numType(NaN) ) // if not a number, typeStr must be literal like "chart"
type = 2^WhichListItem(typeStr, ksCtrlTypes, ";", 0, 0) // case-insensitive
if( type < 1 ) // WhichListItem returned -1? Then we dont know about this type
return ""
endif
endif
// 2. build a list of subwindows to search through
string recurseStr = StringByKey("R", optionsStr), swList
if( !cmpstr(recurseStr, "full") ) // case insensitive
swList = SubWindowList( StringFromList(0, hostNameStr, "#") )
elseif( !cmpstr(recurseStr, "children") )
swList = SubWindowList( hostNameStr )
else
swList = hostNameStr
endif
// 3. get the ControlNameList for each subwindow, filter for types
string matchStr = StringByKey("M", optionsStr)
string outputList = "", ctrlList, subwin, ctrl
variable k, n
for( k = 0; k < ItemsInList(swList); k += 1 )
subwin = StringFromList(k, swList)
if( WinType(subwin) != 1 && WinType(subwin) != 7 ) // graphs and panels only
continue // bypass rest of for(k...) loop
endif
ctrlList = ControlNameList(subwin, ";", matchStr) // filter by match string
for( n = 0; n < ItemsInList(ctrlList); n += 1 )
ctrl = StringFromList(n, ctrlList)
if( type & GetControlType(subwin, ctrl) ) // filter by type
outputList += subwin + " " + ctrl + ";" // OUTPUT FORMAT for ControlInfo/W=...
endif
endfor
endfor
return outputList // RemoveEnding(outputList) if you prefer
end
// return the type of a control in bit parameter logic (see ControlList above)
// if the control is not found, a "1/2" will be returned
function GetControlType(winNameStr, ctrlNameStr)
string winNameStr, ctrlNameStr
ControlInfo/W=$winNameStr $ctrlNameStr
return 2^( abs(V_flag) - 1 )
end
// return a (recursive) list of all child windows with full host specs
function/S SubWindowList(hostNameStr)
string hostNameStr
string childList = ChildWindowList(hostNameStr), swList = hostNameStr + ";"
variable n
for( n = 0; n < ItemsInList(childList); n += 1 )
swList += SubWindowList(hostNameStr+"#"+StringFromList(n, childList)) + ";"
endfor
return RemoveEnding(swList) // necessary to avoid empty items
end
Forum
Support
Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More