Admin Production ni-theme
Current Publication

Programming with Tree Controls

LabWindows/CVI

Programming with Tree Controls

This topic describes how to complete the following tasks programmatically.

Creating a Tree Control in the User Interface Editor

  1. Select Create»Lists & Tables»Tree.
  2. Double-click the tree control to open the Edit Tree dialog box.
  3. Click the Add Item button to add items to the tree.
  4. Click Add Child Item to include child items.
  5. To insert a column, click the Edit Columns/Cells button and then click the Insert Column After button.

Creating a Tree Control Programmatically

Use NewCtrl to create a tree control. The tree control is initially empty. To add items, call InsertTreeItem. The following example adds four items and two child items.

int treeCtrl;

treeCtrl = NewCtrl (panelHandle, CTRL_TREE_LS, "Tree Control", 25, 25);
InsertTreeItem (panelHandle, treeCtrl, VAL_SIBLING, 0, VAL_FIRST, "First Item", NULL, NULL, 0);
InsertTreeItem (panelHandle, treeCtrl, VAL_SIBLING, 0, VAL_NEXT, "Second Item", NULL, NULL, 1);
InsertTreeItem (panelHandle, treeCtrl, VAL_SIBLING, 1, VAL_NEXT, "Third Item", NULL, NULL, 2);
InsertTreeItem (panelHandle, treeCtrl, VAL_CHILD, 2, VAL_FIRST, "First Child Item", NULL, NULL, 3);
InsertTreeItem (panelHandle, treeCtrl, VAL_SIBLING, 3, VAL_NEXT, "Second Child Item", NULL, NULL, 4);
InsertTreeItem (panelHandle, treeCtrl, VAL_SIBLING, 2, VAL_NEXT, "Fourth Item", NULL, NULL, 5);

Associating the Data Type of the Tree Control with Values

The data type for a tree control determines the type of data you can use for the value of tree items. You must match the values you pass to some of the functions with the data type of the control. The pointers you pass to functions that return values must also be compatible with the current data type of the control.

To set the data type, use the ATTR_DATA_TYPE attribute.

SetCtrlAttribute (panelHandle, treeCtrl, ATTR_DATA_TYPE, VAL_STRING);

In this instance, because the data type of the values in the tree control is a character array, you must make sure the values you pass to the tree control and pointers to obtain values from the tree control are also string values.

InsertTreeItem (panelHandle, treeCtrl, VAL_SIBLING, 2, VAL_NEXT, "Fourth Item", NULL, NULL, "Value of fourth item");

Customizing the Behavior of the Tree Control

You can customize the behavior of the tree control using SetCtrlAttribute and the tree attributes.

SetCtrlAttribute (panelHandle, treeCtrl, ATTR_MARK_REFLECT, 1);
SetCtrlAttribute (panelHandle, treeCtrl, ATTR_SELECTION_MODE, VAL_SELECTION_SINGLE);
SetCtrlAttribute (panelHandle, treeCtrl, ATTR_ENABLE_DRAG_DROP, 0);

Interacting with Default Tree Items and Tree Cells

The tree control has a default item, which is not visible. New tree items inherit attributes from the default item.

...
InsertTreeItem (panelHandle, treeCtrl, VAL_SIBLING, 1, VAL_NEXT, "Third Item", NULL, NULL, 2);
// Set the value of the attributes of the default item
SetTreeItemAttribute (panelHandle, treeCtrl, VAL_DFLT_FOR_NEW_OBJECTS, ATTR_LABEL_COLOR, VAL_BLUE);
InsertTreeItem (panelHandle, treeCtrl, VAL_CHILD, 2, VAL_FIRST, "First Child Item", NULL, NULL, 3);
...

Each column has a default cell, which is not visible. Cell attributes of new items are inherited from the default cell of each column. The attribute values of new columns are initialized from the values of the attributes of the first column. The default cell of the new column is initialized from the default cell of the first column.

SetTreeCellAttribute (panelHandle, PANEL_TREE, VAL_DFLT_FOR_NEW_OBJECTS, 2, ATTR_CELL_TYPE, VAL_CELL_CHECK_BOX);

Adding Tree Columns

Call InsertTreeColumn to add more columns to the tree control.

InsertTreeColumn (panelHandle, treeCtrl, 1, NULL);

The third parameter of InsertTreeColumn specifies the zero-based index at which to insert the column. You cannot specify 0.

Adding Images

You can add images to tree items. The tree control maintains a list of images, which you can then specify for items.

int closedBMP, openBMP, cviBMP, closedIdx, openIdx, cviIdx;

GetBitmapFromFileEx ("c:\\temp\\closedfoldericon.ico", -1, &closedBMP);
GetBitmapFromFileEx ("c:\\temp\\openfoldericon.ico", -1, &openBMP);
GetBitmapFromFileEx ("c:\\temp\\cvi.ico", 0, &cviBMP);
closedIdx = AddTreeImage (panelHandle, treeCtrl, closedBMP);
openIdx = AddTreeImage (panelHandle, treeCtrl, openBMP);
cviIdx = AddTreeImage (panelHandle, treeCtrl, cviBMP);
SetCtrlAttribute (panelHandle, treeCtrl, ATTR_SHOW_IMAGES, 1);
/* The fifth parameter specifies the zero-based index at which the image appears in the image list that you specified in preceding code. */
SetTreeItemAttribute (panelHandle, treeCtrl, 0, ATTR_IMAGE_INDEX, cviIdx);

By default, the tree control shows plus and minus icons for expanded and collapsed tree items. If you want to use images other than the plus and minus icons for expanded and collapsed items, set the tree attributes ATTR_EXPANDED_IMAGE_INDEX and ATTR_COLLAPSED_IMAGE_INDEX with SetCtrlAttribute.

int closedIdx, openIdx;

closedIdx = AddTreeImage (panelHandle, PANEL_TREEIMAGE, closedBMP);
openIdx = AddTreeImage (panelHandle, PANEL_TREEIMAGE, openBMP);
cviIdx = AddTreeImage (panelHandle, PANEL_TREEIMAGE, cviBMP);

SetCtrlAttribute (panelHandle, PANEL_TREEIMAGE, ATTR_COLLAPSED_IMAGE_INDEX, closedIdx);
SetCtrlAttribute (panelHandle, PANEL_TREEIMAGE, ATTR_EXPANDED_IMAGE_INDEX, openIdx);

You can put both of the preceding code snippets together and specify images for all tree items.

SetCtrlAttribute (panelHandle, PANEL_TREEIMAGE, ATTR_SHOW_IMAGES, 1);
// All tree items should use the LabWindows/CVI icon.
SetTreeItemAttribute (panelHandle, PANEL_TREEIMAGE, VAL_ALL_OBJECTS, ATTR_IMAGE_INDEX, cviIdx);
// Tree items that are collapsed should use the LabWindows/CVI icon.
SetTreeItemAttribute (panelHandle, PANEL_TREEIMAGE, VAL_ALL_OBJECTS, ATTR_COLLAPSED_IMAGE_INDEX, cviIdx);
// Replace the minus sign with the closed folder icon.
SetCtrlAttribute (panelHandle, PANEL_TREEIMAGE, ATTR_COLLAPSED_IMAGE_INDEX, closedIdx);
// Replace the plus sign with the open folder icon.
SetCtrlAttribute (panelHandle, PANEL_TREEIMAGE, ATTR_EXPANDED_IMAGE_INDEX, openIdx);

Deleting and Replacing Items

// Delete a column.
DeleteTreeColumn (panelHandle, PANEL_TREE, 2);

// Delete a tree item and siblings.

int idxToDelete;
int sibsToDelete;

GetCtrlVal (panelHandle, PANEL_NUMERIC_IDX, &idxToDel);
GetCtrlVal (panelHandle, PANEL_NUMERIC_SIBS, &sibsToDelete);
DeleteListItem (panelHandle, PANEL_RING, idxToDelete, sibsToDelete);

// Replace a list item.
ReplaceListItem (panelHandle, PANEL_TREESEARCH, 1, "DefaultCtrl", 0);

Setting the Active Item

If the tree selection mode is VAL_SELECTION_NONE or VAL_SELECTION_SINGLE, SetCtrlIndex and SetActiveTreeItem have the same behavior.

int activeItem;

SetCtrlAttribute (panelHandle, PANEL_TREEIMAGE, ATTR_SELECTION_MODE, VAL_SELECTION_SINGLE);
GetCtrlVal (panelHandle, PANEL_ACTIVE, &activeItem);
// The following two lines are equivalent.
SetActiveTreeItem (panelHandle, PANEL_TREEIMAGE, activeItem, VAL_REPLACE_SELECTION_WITH_ITEM);
SetCtrlIndex (panelHandle, PANEL_TREEIMAGE, activeItem);

When the selection mode is VAL_SELECTION_MULTIPLE, use SetActiveTreeItem and the selection effect parameter to specify the resulting selection.

SetCtrlAttribute (panelHandle, PANEL_TREEIMAGE, ATTR_SELECTION_MODE, VAL_SELECTION_MULTIPLE);
GetCtrlVal (panelHandle, PANEL_ACTIVE, &activeItem);
SetActiveTreeItem (panelHandle, PANEL_TREEIMAGE, activeItem, VAL_ADD_INTERVAL_TO_SELECTION);

Obtaining Tree Information

Getting the Active Tree Item Index

int activeIndex;

GetActiveTreeItem (panelHandle, PANEL_TREEPATH, &activeIndex);

Getting the Tree Item Path

int pathLength;
char *path;

GetTreeItemPathLength (panelHandle, PANEL_TREEPATH, activeIndex, " > ", &pathLength);
path = malloc ((pathLength + 1) * sizeof (char));
GetTreeItemPath (panelHandle, PANEL_TREEPATH, activeIndex, " > ", path);
SetCtrlVal (panelHandle, PANEL_STRING, path);

Getting the Tree Item Label

char *labelText;
int labelLength;

GetTreeItemAttribute (panelHandle, PANEL_TREEPATH, activeIndex, ATTR_LABEL_TEXT_LENGTH, &labelLength);
labelText = malloc ((labelLength + 1) * sizeof(char));
GetTreeItemAttribute (panelHandle, PANEL_TREEPATH, activeIndex, ATTR_LABEL_TEXT, labelText);
SetCtrlVal (panelHandle, PANEL_STRINGLABEL, labelText);

Getting the Tree Item Value

double itemVal;

GetTreeItemAttribute (panelHandle, PANEL_TREEPATH, activeIndex, ATTR_CTRL_VAL, &itemVal);
SetCtrlVal (panelHandle, PANEL_NUMERICVAL, itemVal);

Getting the Tree Item Tag

char tag[MAX_TREE_ITEM_TAG_LEN];

GetTreeItemTag (panelHandle, PANEL_TREEPATH, activeIndex, tag);
SetCtrlVal (panelHandle, PANEL_STRINGTAG, tag);

Finding the Root of a Tree Item

The root of a tree item is the first-level ancestor.

int ancestor;

GetTreeItem (panelHandle, treeCtrl, VAL_ANCESTOR, treeIndex, VAL_LAST, VAL_NEXT_PLUS_SELF, 0, &ancestor);

Getting Tree Values from a Screen Point

int pointCol, pointArea, pointIdx;
Point point;

switch (event)
{

case EVENT_LEFT_CLICK:

point = MakePoint (eventData2, eventData1);
GetIndexFromPoint (panelHandle, PANEL_TREE, point, &pointIdx, &pointArea, &pointCol);
SetCtrlVal (panelHandle, PANEL_IDXPOINT, pointIdx);
SetCtrlVal (panelHandle, PANEL_AREAPOINT, pointArea);
SetCtrlVal (panelHandle, PANEL_COLPOINT, pointCol);
break;

}
return 0;

}

Copying Tree Items

Use CopyTreeItem to copy tree items within the same tree or to a different tree. This function also copies the descendents of the tree item.

CopyTreeItem (panelHandle, PANEL_TREE, 0, panelHandle, PANEL_TREEIMAGE, VAL_CHILD, 3, VAL_LAST);

Moving Tree Items

Use MoveTreeItem to move an item and all its descendents to a new position in the tree.

MoveTreeItem (panelHandle, PANEL_TREEIMAGE, 3, VAL_CHILD, 8, VAL_LAST);

Searching for Tree Items

To search for items in the tree, you can call GetTreeItem, GetTreeItemFromLabel, and GetTreeItemFromValue. These functions allow you to search for items that are related to a specified item.

char label[256];
int item = 0, beginIndex = VAL_FIRST, direction = VAL_NEXT_PLUS_SELF, firstIteration = 1;

/* Get the search string from the user interface. */
GetCtrlVal (panelHandle, PANEL_SEARCH_STRING, label);
/* Iterate from the active tree item until there are no more matches to find. */
while (item!=-1)

{

GetTreeItemFromLabel (panelHandle, PANEL_TREESEARCH, VAL_ALL, 0, beginIndex, direction, 0, label, &item);
/* On the next iteration, start from current item. */
beginIndex = item;
if (item!=-1)
{

/* Select the tree item if its label matches the specified search string. */
SetTreeItemAttribute (panelHandle, PANEL_TREESEARCH, item, ATTR_LABEL_BGCOLOR, VAL_DK_MAGENTA);

}
/* If the item is not found on the first iteration, pop up a message indicating there are no matches. */
else if (firstIteration)
{

MessagePopup ("No match", "The search string does not match any tree item labels.");

}
/* After the first iteration, no longer include the beginIndex item in the search. */
if (firstIteration)
{

direction = VAL_NEXT;
firstIteration = 0;

}

}

Refine the search by searching through all the children, descendents, or ancestors of a particular item. You can further narrow the search by specifying the state of the item to search. Item states include selected, exposed, marked, and expanded. To combine states, OR the state criteria flags.

int found;

GetTreeItem (panelHandle, PANEL_TREE, VAL_ALL, 1, VAL_FIRST, VAL_NEXT, VAL_MARKED|VAL_SELECTED, &found);
if (found != -1) {

SetTreeItemAttribute (panelHandle, PANEL_TREESEARCH, found, ATTR_LABEL_BGCOLOR, VAL_YELLOW);

}

Sorting Tree Items

To sort tree items, call SortTreeItems.

SortTreeItems (panelHandle, PANEL_TREESEARCH, 4, 0, 0, 1, 0, 0);

The default sort method is a case-sensitive comparison of the tree item labels. If you want to customize the search, pass your own comparison function. You can specify the column by which to sort the items, whether the sort is ascending or descending, and whether to sort the subtrees. Refer to the treesort.cws example for a project that uses a custom search function.

Customizing the Appearance of the Tree Control

You can customize the appearance of the tree control using SetCtrlAttribute and the tree attributes.

SetCtrlAttribute (panelHandle, treeCtrl, ATTR_SHOW_MARKS, 1);
SetCtrlAttribute (panelHandle, treeCtrl, ATTR_SCROLL_BARS, VAL_BOTH_SCROLL_BARS);
SetCtrlAttribute (panelHandle, treeCtrl, ATTR_HIDE_ACTIVE_ITEM_ALWAYS, 1);

Specifying and Obtaining Tree Cell Attributes

Note Note  You cannot set the following attributes for tree cells in the first column:
  • ATTR_CELL_TYPE
  • ATTR_COLOR_PICKER_VALUE
  • ATTR_HORIZONTAL_BAR_COLOR
  • ATTR_HORIZONTAL_BAR_VALUE
  • ATTR_TREE_RUN_STATE

SetTreeCellAttribute (panelHandle, treeCtrl, VAL_ALL_OBJECTS, 0, ATTR_LABEL_BGCOLOR, VAL_OFFWHITE);
SetTreeCellAttribute (panelHandle, treeCtrl, 2, 0, ATTR_TOOLTIP_TEXT, "This is a tooltip");
SetTreeCellAttribute (panelHandle, treeCtrl, 0, 1, ATTR_CELL_TYPE, VAL_CELL_COLOR_PICKER);
SetTreeCellAttribute (panelHandle, treeCtrl, 1, 1, ATTR_CELL_TYPE, VAL_CELL_CHECK_BOX);
SetTreeCellAttribute (panelHandle, treeCtrl, 3, 1, ATTR_CELL_TYPE, VAL_CELL_HORIZONTAL_BAR);
SetTreeCellAttribute (panelHandle, treeCtrl, 3, 1, ATTR_HORIZONTAL_BAR_COLOR, VAL_YELLOW);
SetTreeCellAttribute (panelHandle, treeCtrl, 3, 1, ATTR_HORIZONTAL_BAR_VALUE, 62.0);

Pass VAL_ALL_OBJECTS as the item index parameter to indicate that the attribute applies to all of the cells in a specified column. You also can specify VAL_ALL_OBJECTS the column index parameter to specify that the attribute applies to all columns.

To obtain the value of a tree cell attribute, call GetTreeCellAttribute.

Specifying and Obtaining Tree Column Attributes

Call SetColumnWidthToWidestCellContents to make the width of the column as wide as the widest tree cell label.

SetColumnWidthToWidestCellContents (panelHandle, treeCtrl, 0);
SetColumnWidthToWidestCellContents (panelHandle, treeCtrl, 1);

Call SetTreeColumnAttribute to customize tree columns.

SetTreeColumnAttribute (panelHandle, treeCtrl, 1, ATTR_LABEL_VISIBLE, 1);
SetTreeColumnAttribute (panelHandle, treeCtrl, 0, ATTR_LABEL_VISIBLE, 1);
SetTreeColumnAttribute (panelHandle, treeCtrl, 0, ATTR_LABEL_TEXT, "One");
SetTreeColumnAttribute (panelHandle, treeCtrl, 1, ATTR_LABEL_TEXT, "Two");
SetTreeColumnAttribute (panelHandle, treeCtrl, 0, ATTR_VERTICAL_GRID_COLOR, VAL_RED);
SetTreeColumnAttribute (panelHandle, treeCtrl, 0, ATTR_VERTICAL_GRID_VISIBLE, 1);
SetTreeColumnAttribute (panelHandle, treeCtrl, 1, ATTR_LABEL_BOLD, 1);

Pass VAL_ALL_OBJECTS for the column index parameter to specify that the attribute applies to all columns.

To obtain the value of a tree column attribute, call GetTreeColumnAttribute.

Specifying and Obtaining Tree Item Attributes

You can set attributes for tree items using SetTreeItemAttribute.

SetTreeItemAttribute (panelHandle, treeCtrl, 0, ATTR_MARK_TYPE, VAL_MARK_RADIO);
SetTreeItemAttribute (panelHandle, treeCtrl, 4, ATTR_LABEL_COLOR, VAL_GREEN);
SetTreeItemAttribute (panelHandle, treeCtrl, VAL_ALL_OBJECTS, ATTR_MAX_ENTRY_CHARS, 10);

To obtain the value of a tree item attribute, call GetTreeItemAttribute.

Customizing the Context Menu

The tree control includes a context menu by default.

// Remove and add additional built-in items from the context menu.
HideBuiltInCtrlMenuItem (panelHandle, PANEL_TREE, VAL_EXPAND_SUBTREE);
HideBuiltInCtrlMenuItem (panelHandle, PANEL_TREE, VAL_COLLAPSE_SUBTREE);
HideBuiltInCtrlMenuItem (panelHandle, PANEL_TREE, VAL_EXPAND_ALL);
HideBuiltInCtrlMenuItem (panelHandle, PANEL_TREE, VAL_COLLAPSE_ALL);
ShowBuiltInCtrlMenuItem (panelHandle, PANEL_TREE, VAL_FIND_NEXT, -1);
ShowBuiltInCtrlMenuItem (panelHandle, PANEL_TREE, VAL_FIND_PREV, -1);

// Add your own items to the context menu.
void CVICALLBACK CustomMenu (int panelHandle, int controlID, int MenuItemID, void *callbackData);

. . .

NewCtrlMenuItem (panelHandle, PANEL_TREE, "My Menu Item", -1, CustomMenu, 0);

. . .

void CVICALLBACK CustomMenu (int panelHandle, int controlID, int MenuItemID, void *callbackData)
{

MessagePopup ("Tree Control Menu", "You selected a custom item");

}

// Hide the context menu.
SetCtrlAttribute (panelHandle, PANEL_TREE, ATTR_ENABLE_POPUP_MENU, 0);

You also can use control menu attributes to configure context menus. Call GetCtrlMenuAttribute and SetCtrlMenuAttribute to get and set these attributes.

Using List Box Control Functions

In addition to specific tree control functions, you also can use all of the list box control functions. Some of the list box control functions, such as GetNumListItems and InsertListItem, are equivalent to the tree control functions but are simpler to use. Others, such as DeleteListItem and ReplaceListItem have no tree control function equivalent, and you must use the list box functions.

Related Topics

Programming with Controls

Tree Control Functions

List Box Control Functions