A filtered list of all controls in a window, including subwindows

This might be interesting for you if you are programming Igor Pro user interfaces.

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 buttons 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

Forum

Support

Gallery

Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More