11-09-2012 09:56 AM
Basic question. I'm trying to use a common Quit button across multiple panels in my project. So with a single callback function, I a couple nested switch statements, the first of course checking for EVENT_COMMIT, and the next down checking for the active panel. For instance:
switch (panel) // TODO: this isn't working. panel variable doesn't seem to be changing { case AUTOPANEL: printf("AUTOPANEL"); HidePanel(autopanel); DisplayPanel(frontpanel); break; case MANPANEL: printf("MANPANEL"); HidePanel(manualpanel); DisplayPanel(frontpanel); break; case PASSPANEL: printf("PASSPANEL"); HidePanel(passpanel); DisplayPanel(frontpanel); break; case FRONTPANEL: printf("FRONTPANEL"); QuitUserInterface(0); break; }
However, when I do this, I get very unpredictable behavior. It would appear that the panel switch isn't what I think it should be in the callback. The value of panel seems to not match the macro value for the respective panels that I'm in when I click their QUIT buttons.
Solved! Go to Solution.
11-09-2012 10:08 AM
Are AUTOPANEL, MANPANEL,... the panel handles you obtained using LoadPanel () ?
11-09-2012 10:09 AM
Keep in mind that you need to pass the panel handle to HidePanel function, while it appears you are passing the panel constant names. This cannot work correctly as those values are very different!
As far as I can see, you have several panels: a main one, whose Quit button terminates the program, ans several other panels each of them hase a Close button that hides its panel and shows the main one. If this is the case, the callback can simply hide the panel whose handle is passed as a parametet to the function. The only test to perform is to check that variable against the handle of the main panel (which you must have global to the project). Something like this:
int CVICALLBACK ButtonCbk (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: if (panel == mainPanelHandle) QuitUserInterface (0); else { HidePanel (panel); DisplayPanel (mainPanelHandle); } break; } return 0; }
11-09-2012 10:09 AM
In a callback the value of panel will match the value of the handle obtained when you called LoadPanel().
You need to use these handles as your cases.
switch (panel) // TODO: this isn't working. panel variable doesn't seem to be changing { case autopanel: printf("AUTOPANEL"); HidePanel(autopanel); DisplayPanel(frontpanel); break; case manualpanel: printf("MANPANEL"); HidePanel(manualpanel); DisplayPanel(frontpanel); break; case passpanel: printf("PASSPANEL"); HidePanel(passpanel); DisplayPanel(frontpanel); break; case frontpanel: printf("FRONTPANEL"); QuitUserInterface(0); break; }
11-09-2012 02:23 PM
RobertoBozzolo wrote:
Keep in mind that you need to pass the panel handle to HidePanel function, while it appears you are passing the panel constant names. This cannot work correctly as those values are very different!
As far as I can see, you have several panels: a main one, whose Quit button terminates the program, ans several other panels each of them hase a Close button that hides its panel and shows the main one.
You are correct. I have four panels, one of which is the "main" panel. The others are little sub-panels.
Wolfgang wrote:
Are AUTOPANEL, MANPANEL,... the panel handles you obtained using LoadPanel () ?
That's correct. I load all four in my main function like this:
//----------------------------------- // module globals //----------------------------------- int frontpanel; // main panel int manualpanel; // manual control panel int autopanel; // automatic control panel int passpanel; // password panel .... frontpanel = LoadPanel (0, "panels.uir", FRONTPANEL); manualpanel = LoadPanel (0, "panels.uir", MANPANEL); autopanel = LoadPanel (0, "panels.uir", AUTOPANEL); passpanel = LoadPanel (0, "panels.uir", PASSPANEL); if (frontpanel < 0 || manualpanel < 0 || autopanel < 0 || passpanel < 0) return -1;
simonnj wrote:
In a callback the value of panel will match the value of the handle obtained when you called LoadPanel().
You need to use these handles as your cases.
Ok, I attempted this, but I got a compiler error, stating that the cases need to be constant. But I can't just declare them as const int, because I assign value to each of them in the LoadPanel call.
RobertoBozzolo wrote:
Keep in mind that you need to pass the panel handle to HidePanel function, while it appears you are passing the panel constant names. This cannot work correctly as those values are very different!
I'm confused. Why are these values different? I see now that this is so as I step through code. But how come LabWindows doesn't assign the same value to my LoadPanel return, as it assigns to the macros for the panel name? In other words, I think it would obviously be convenient for this:
autopanel = LoadPanel(0, "panels.uir", AUTOPANEL);
...to be equal to this:
#define AUTOPANEL 1
11-09-2012 03:00 PM - edited 11-09-2012 03:03 PM
I think you're a bit confused Fortunately, it is possible to resolve it easily:
panel_handle = LoadPanel ( 0, file_name, panel_resource_id )
As you can see, panel_handle is the return value of the function call, while you have used the resource id. Or, citing the help: The function returns a panel handle that you use in subsequent function calls to specify the panel.
You can answer your question by looking into your UI include files: probably FRONTPANEL etc. all are defined as 1 (because the first panel in a UI file is enumerated as first element, hence 1, and all your four different UI files start enumerating panels / controls / menus with 1...) - so how should the program distinguish which panel / which '1' you have in mind? That's what the function LoadPanel is for, it creates a unique handle, while the constants may not be unique if there is more than one file...
11-09-2012 03:11 PM
Correct again, Wolfgang -- I'm confused! But it won't be the first or last time.
I see what you are saying, that the resource IDs are not matching the return values of the function LoadPanel. But let me ask another way: What are the resource IDs that are auto-generated for each panel for? As you can see below, mine are not all 1. They increment at a top level structure, i.e., each panel constant is unique. Then, each control within that panel starts at 2 and increments.
#define AUTOPANEL 1
#define AUTOPANEL_QUITBUTTON 2 /* control type: command, callback function: QuitCallback */
#define AUTOPANEL_GOBUTTON 3 /* control type: command, callback function: AutoStart */
#define FRONTPANEL 2
#define FRONTPANEL_TEXTMSG 2 /* control type: textMsg, callback function: (none) */
#define FRONTPANEL_TECHBUTTON 3 /* control type: command, callback function: ModeEntry */
#define FRONTPANEL_ENGBUTTON 4 /* control type: command, callback function: ModeEntry */
#define FRONTPANEL_QUITBUTTON 5 /* control type: command, callback function: QuitCallback */
#define MANPANEL 3
#define MANPANEL_LED3 2 /* control type: LED, callback function: (none) */
#define MANPANEL_LED2 3 /* control type: LED, callback function: (none) */
#define MANPANEL_LED1 4 /* control type: LED, callback function: (none) */
#define MANPANEL_LED0 5 /* control type: LED, callback function: (none) */
#define MANPANEL_BINARYSWITCH3 6 /* control type: binary, callback function: ButtonFio3 */
#define MANPANEL_BINARYSWITCH2 7 /* control type: binary, callback function: ButtonFio2 */
#define MANPANEL_BINARYSWITCH1 8 /* control type: binary, callback function: ButtonFio1 */
#define MANPANEL_BINARYSWITCH0 9 /* control type: binary, callback function: ButtonFio0 */
#define MANPANEL_QUITBUTTON 10 /* control type: command, callback function: QuitCallback */
#define MANPANEL_TEXTMSG4 11 /* control type: textMsg, callback function: (none) */
#define MANPANEL_TEXTMSG3 12 /* control type: textMsg, callback function: (none) */
#define MANPANEL_TEXTMSG2 13 /* control type: textMsg, callback function: (none) */
#define MANPANEL_TEXTMSG1 14 /* control type: textMsg, callback function: (none) */
#define PASSPANEL 4
#define PASSPANEL_PASSSTRING 2 /* control type: string, callback function: StringCallback */
#define PASSPANEL_OKBUTTON 3 /* control type: command, callback function: OkCallback */
#define PASSPANEL_QUITBUTTON 4 /* control type: command, callback function: QuitCallback */
11-09-2012 03:30 PM
The panel constants are not identical 1 because they are all in the same UI file... but you could also load two or three UI files, what then?
Also, the include file does not distinguish between panels and controls, '2' can be both a panel and a control...
So what are these constants for - they are needed to generate a handle that is (always) unique
11-09-2012 04:06 PM - edited 11-09-2012 04:09 PM
Just to add some detail to Wolfgang answer, consider that you can load the same panel more than once, and each instance of it will have independent life!
Situation is as follows:
11-13-2012 09:09 AM - edited 11-13-2012 09:10 AM
simonnj wrote:
In a callback the value of panel will match the value of the handle obtained when you called LoadPanel().
You need to use these handles as your cases.
switch (panel) // TODO: this isn't working. panel variable doesn't seem to be changing { case autopanel: printf("AUTOPANEL"); HidePanel(autopanel); DisplayPanel(frontpanel); break; case manualpanel: printf("MANPANEL"); HidePanel(manualpanel); DisplayPanel(frontpanel); break; case passpanel: printf("PASSPANEL"); HidePanel(passpanel); DisplayPanel(frontpanel); break; case frontpanel: printf("FRONTPANEL"); QuitUserInterface(0); break; }
What I've learned is that switch statement cases must be known at compile time. Because the above suggested cases are loaded during run-time with the return of LoadPanel(), they by definition are not constants at compile time. So a switch statement won't work there. Bummer.
So a big ugly if-else block is in order for my situation, checking the panel handles.