LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Tree control items selection issue

I'm using the regular tree control in CVI 7.1. I need the code to detect the selected items the moment I do the selection. I've tried a few methods to achieve this, one of them is intercepting the tree EVENT_VAL_CHANGED event the following way:
 
 switch (event)
 {
  case EVENT_VAL_CHANGED:
  
   sprintf(sz, "");
   
   GetNumTreeItems (panel, control, VAL_ALL, 0, VAL_FIRST, VAL_NEXT_PLUS_SELF, 0, &count); 
   for(i = 0; i < count; i ++)
   {
    GetTreeItemAttribute(panel, control, i, ATTR_SELECTED, &selected);
    if(selected)
    {
     GetTreeCellAttribute(panel, control, i, 0, ATTR_LABEL_TEXT, text);
     strcat(sz, text);
     strcat(sz, " ");    
    }
   }
   SetCtrlVal(panel, PANEL_STRING, sz);          
   break;
 }
 
 
The code is supposed to build a string containing labels of all the selected items.
 
Now, the problem is: the string I see contains the items that were PREVIOUSLY selected, i.e. that were supposed to be reflected on the previous interception of this event. This way I get a "delay" of one event instead of being able to see the results immediately upon selection change.
 
I've also tried to intercept EVENT_LEFT_CLICK and EVENT_SELECTION_CHANGE, with the same results.
 
 
Alex.

Message Edited by rag3ous on 12-11-2005 07:21 AM

0 Kudos
Message 1 of 4
(3,809 Views)
Hi Alex,

Your problem comes from the fact that the selection change is not fully complete at the time your callback is called.  This is a signal to you that the event is about to happen.  To fix this, try using PostDeferredCall to do your processing after all the event has been fully processed.  Also, I'd advise using the EVENT_SELECTION_CHANGE, since this seems to be the event you're really interested in.  The code below demonstrates how to do all this:

static int eventPanel, eventControl;

void CVICALLBACK GetSelectedLabels (void *callbackData)
{
    int index;
    char text[50], sz[1000];  /* use appropriate sizes */

     sprintf(sz, "");
                  
     /* This will get only the indices that are selected, */
     /* instead of iterating through all indices          */
     for(GetTreeItem(eventPanel, eventControl, VAL_ALL, 0,
                VAL_FIRST, VAL_NEXT_PLUS_SELF, VAL_SELECTED, &index);
          index >= 0;
          GetTreeItem(eventPanell, eventControl, VAL_ALL, 0,
                index, VAL_NEXT, VAL_SELECTED, &index))
    {
         GetTreeCellAttribute(eventPanel, eventControl,
            index, 0, ATTR_LABEL_TEXT, text);
         strcat(sz, text);
         strcat(sz, " ");
    }
    SetCtrlVal(eventPanel, PANEL_STRING, sz);
}


And in your tree callback...

switch (event)
 {
     case EVENT_SELECTION_CHANGE:
         eventPanel = panel;
         eventControl = control;
         PostDeferredCall(GetSelectedLabels, 0);
         break;
}


Hope you find this helpful.

Mert A.
National Instruments
Message 2 of 4
(3,768 Views)

Using the EVENT_VAL_CHANGED event to keep track of selection changes can give you incorrect results since.....

1) as you noted, the selection isn't updated until after the tree receives the EVENT_VAL_CHANGED. Even if you posted a deferred callback that is called after the tree is updated, you can still get an incorrect selection since....

2) the selection can change without the active item changing. For example, hit <ctrl+spacebar> on a tree in multiple selection mode, and the active item's selection is toggled and you don't get an EVENT_VAL_CHANGED since the active item was never changed.

Check out the help page on 'TreeControl Events', and look at the EVENT_SELECTION_CHANGE. This event is sent for each item when it's selection state is about to change. This event is swallowable for trees, so the selection state is not updated until after the event is sent and the event was not swallowed. Use eventData2 and eventData1, which indicate the item index whose selection state is about to change and it's new selection state.

Note that the EVENT_SELECTION_CHANGE is sent for each item, so if you group select or deselect items, you'll get multiple events.

- jared

Message 3 of 4
(3,761 Views)

Mert and Jared, thanks for your reply.

 

I realized I have to use such function in order to be able to see the changes immediately, I just didn't know which one.

PostDeferredCall does the job.

 

I've also checked and noticed the difference between EVENT_SELECTION_CHANGE and EVENT_VAL_CHANGED, indeed I have to use EVENT_SELECTION_CHANGE.

 

Thanks alot for the help.

 

Alex.

0 Kudos
Message 4 of 4
(3,751 Views)