08-22-2013 03:14 PM
Hi there, I'm designing a new application. I have two main panels, each displays on a unique PC monitor. I have a third panel that displays detailed data common to both of the first two panels. This third panel is a configuration panel, such that it needs to place its updated fields back into the calling panel.
I would prefer to open this same third panel from either of the first two panels. But to do so, I need to know which of the two panels opened the third.
How would I go about doing this withouth making a global variable? Would this be a case for using callbackData? If so, I'm not clear how to go about this.
Solved! Go to Solution.
08-22-2013 03:43 PM
Hi,
in a similar application I have used callbackdata. Because I needed more information I have used a structure to pass this information:
void CVICALLBACK ProcessDisplayPanelMenu ( int menuBar, int menuItem, void *callbackData, int panel )
{
process = ( struct process_structure * ) callbackData;
08-22-2013 04:59 PM
Thanks, Wolfgang. A similar approach without a struct I found here:
For my particular need, I did this:
// panel #1: SetPanelAttribute(overridePanel,ATTR_CALLBACK_DATA,(void *)1); DisplayPanel(overridePanel);
....
// in a control callback on the overridePanel:
switch(callbackData)
{
case PANEL_1:
// do something
break;
}
08-23-2013 01:21 PM
Hi ElectroLund,
I can see a problem in your code.
In the calling callback you are setting the panel callbackData.
This means that in a control callback you must retrieve this value, which is different from the control callbackData you receive in the callback. To retrieve the panel callbackData you must do something like this (I have no CVI install at the moment to test it):
void *cbkd; GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &cbkd); if (cbkd) { // The panel has some callbackData installed } else { // No callbackData installed on the panel }
Finally, comparing callbackData value (that you set to a simple '1') to PANEL_1 which I suppose is a panel constant name is not good: PANEL_1 can be equal to '1' only by chance and this can change if you modify the z-plane order of panels.
08-26-2013 12:40 PM - edited 08-26-2013 12:43 PM
@RobertoBozzolo wrote:
In the calling callback you are setting the panelcallbackData.This means that in a control callback you must retrieve this value, which is different from the control callbackData you receive in the callback.
Finally, comparing callbackData value (that you set to a simple '1') to PANEL_1 which I suppose is a panel constant name is not good: PANEL_1 can be equal to '1' only by chance and this can change if you modify the z-plane order of panels.
You are right, Roberto. I must first get the value of the panel callbackData. The reason I chose to set that value for the panel, rather than a particular control on that panel, is that the panel has several controls that have callback functions. I need all of them to know who originally called the panel do behave differently.
Also, regarding my undefined "PANEL_1", this was supposed to be some enum value. However, instead now I'm taking advantage of the UIR include file IDs. So my declaration of the panel callbackData looks like this:
SetPanelAttribute(mainPanel,ATTR_CALLBACK_DATA,(void *)PANEL);
Finally, when checking the value of the callbackData with a switch statement, it's invalid to use void pointers. So I found that I needed to cast as an int (provided I set the value with an int).
09-12-2013 04:44 PM
Wolfgang, care to elaborate on your syntax for how you assigned your structure to the callbackdata? I'm referring to either a
SetCtrlAttribute(panel,control,ATTR_CALLBACK_DATA,???);
or
SetPanelAttribute(panel,ATTR_CALLBACK_DATA,???);
I'm unclear how exactly to pass a struct into a void pointer without errors.
09-13-2013 02:14 AM
Hello ElectroLund,
in my case I use a menu callback, but the principle of course is the same. I have
SetMenuBarAttribute ( menu_bar_handle, menu_id, ATTR_CALLBACK_DATA, ( void * ) &sensor.process );
to provide the address of the structure.
Hope it helps
09-13-2013 12:36 PM
Yeah, that works really nicely! In my case, I'm assigning my structure to a control callback:
structtype testGlobal;
SetCtrlAttribute(panel,CONTROL1,ATTR_CALLBACK_DATA,(void *)&testGlobal);
And then in the callback function of that control:
int CVICALLBACK TestButton (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { structtype* testLocal; testLocal = (structtype*)callbackData; }