03-19-2013 11:55 AM
This is exactly the way the package works...
A control callback receives all events fired: it's up to you to tailor the callback code so that only interesting events are handled, while the others are simply ignored (but the callback is indeed executed).
03-19-2013 12:03 PM
Thank you, Roberto. Now...is there any documentation that describes this behavior (and other stuff) at a conceptual level?
So far, my impression of the CVI documentation has been that it's pretty good for reference, but not so good for learning concepts. Is there perhaps some documentation I'm not aware of? For example, where would I have found the answer to this particular question?
03-19-2013 12:10 PM
Well, I must admit that most of my knowledge of CVI has been acquired on the way by reading documents, forum posts, tutorials and so on amd making a lot of tests: as far as I know there is not a complete conceptual document explaining CVI paradigms. A lot of informations can be found in the Programmer's Reference book in the help, but in the particular case we are discussing here you could have found some informations in this chapter of the User Interface Library help: Using Callback Functions to Respond to User Interface Events
03-19-2013 01:19 PM
That's a helpful page, Roberto...thanks.
One thing I'm still trying to fully understand is the use of callbackData. I notice in the examples on that page, that the pointer didn't seem to be used anywhere. Is the callback routine supposed to do something with that? In my example above, my callbackData value is NULL, so I'm not sure what I'm supposed to do with it.
03-19-2013 05:45 PM - edited 03-19-2013 05:47 PM
callbackData parameter is designed completely for programmer's use: the system does anything with it, except passing it to the control function.
I can give you an example of how I use it: I often have to develop programs that take care of several independent equipments, each of them must be setup, started and stopped. I normally have a list of buttons in my main panel, one per each equipment, to which I have installed as callbackData the equipment ID; the callback of these buttons, unique for all of them, displays a status window for the selected equipment, which it discriminates via callbackData value.
Again, when displaying the status window I install the same callbackData on settings, start and stop buttons, and so again one single callback can operate on every equipment simply using callbackData value to discriminate which is the equipment to address.
There is no limit on callbackData parameter usage, wolfgang has pointed you to fileBrowser custom control which intensively uses it; my example is probably simpler but easier to understand.
03-20-2013 05:17 PM
Hi, Roberto -
I think I understand the principle of the field; it's more the mechanics of using it that I still don't get. This is considered an input to the callback routine, right? So...how do I "load" that field with data before the callback is called? I put breakpoints in my CBs and the value of the pointer is NULL.
03-21-2013 02:46 AM - edited 03-21-2013 02:47 AM
callbackData is left for programmer's needs, so it's the programmer that is in charge of filling and retrieving values from the variable.
To set a value in callbackdata parameter you must either do this:
SetCtrlAttribute (panelHandle, PANEL_CONTROLID, ATTR_CALLBACK_DATA, (void *)value);
or this
InstallCtrlCallback (panelHandle, PANEL_CONTROLID, eventFunction, (void *)callbackData);
To retrieve a value from the variable if inside the control callback you simply have to cast it to appropriate data type:
int CVICALLBACK myCallbackFunction (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { int value; if (event != EVENT_COMMIT) return 0; value = (int)callbackData; // Other code here return 0; }
If outside of the control callback, you must first read it in a void * variable and then cast it to the appropriate type:
void *cbkd; int value; GetCtrlAttribute (panelHandle, PANEL_CONTROLID, ATTR_CALLBACK_DATA, &cbkd); value = (int)cbkd;
As already pointed out in one of the posts linked by wolfgang, if used as a pointer callbackData must point to an object that is still valid when it is retrieved: that is, you cannot point it to a variable local to a function and retrieve it in another function.
03-21-2013 09:01 AM
Ahh! There's the ingredient I was missing. The SetCtrlAttribute() routine, along with the ATTR_CALLBACK_DATA parameter, was the Rosetta Stone.
Thank you SO much, Roberto...this helps a great deal.