03-05-2009 02:08 PM
Hi,
I have a couple of numeric and text controls on a panel. One of the numerics is a Serial number(SN). Depending on what the user enters in the box, my program will access a database and read and fill out the remainder of the values.
This works as expected, but if the user enters a SN that is not in the Database I output a message saying that the SN is invalid, and then I want to revert the value in the SN numeric to the value it was previously..
For example:
User enters Serial number 0001, We find and display the data for Serial number 0001.
User enters Serial number 0013, We find and display the data for Serial number 0013.
The user enters Serial number 9999 into the numeric. Serial number 9999 doesn't exist so we output error, and then I want to change the value in the numeric back to 0013 because that was the last valid one.
Is there any options to do that or do I have to keep track of what the last valid SN in the program? The best idea I could come up with not having to keep track of the last valid SN was have 2 numeric boxes, one that displays the Serial number as an indicator and another that acts as a search box. So the indicator would only be changed if the Serial number entered in the search box was valid. Any suggestions on how to do this without using 2 numeric boxes would be greatly appreciated.
Thanks
03-05-2009 03:30 PM
Hi Karkala.
The simplest approach I can think of is to use the SavePanelState() and RecallPanelState() functions from the User Interface Library.
If a valid SN is entered:
If an invalid SN is entered:
If you wish, you could use RecallPanelState() when your program starts, to display the last-retrieved database record.
Regards,
Colin.
03-05-2009 04:54 PM - edited 03-05-2009 04:56 PM
Hi Karkala, your problem could be easily solved if CVI handled some sort of EVENT_LOAD, which it doesn't; so let's try to fake it
Suppose your SN callback is made this way:
int CVICALLBACK SNCallback (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
static int previous;
int val;
if (event != EVENT_COMMIT) return 0;
// Record initial value of the control (default value at panel load)
if (callbackData) {
GetCtrlVal (panel, control, &previous);
return 0; // Exit the function
}
// Hadle normal SN input
GetCtrlVal (panel, control, &val);
// Search the database
if (##value not found##) {
MessagePopup ("Serial number", "Serial number not found.");
SetCtrlVal (panel, control, previous); // Restore previous value
return 0; // Exit the function
}
else
previous = val; // Save valid SN
// Other code
return 0;
}
Now, to trigger the "load" event, immediately after loading the panel you can directly call the control callback with a non-null callbackData:
SNCallback (panelHandle, PANEL_NUMERIC_2, EVENT_COMMIT, (void *)1, 0, 0);
This approach relies on using the callbackData parameter which is available for programmer uses; itsupposes that you are not yet using callbackData parameter for other scopes: if you are you possibly could assign a special value to this event, not used elsewere in the program, and discriminate on callbackData value,
It has the advantage that it does not require continuous disk access. Moreover, SavePanelState saves the contents of all controls on the panel: it may be a problem if you have other controls on the panel which you do not want to revert to a previous state.
03-06-2009 03:40 AM
03-06-2009 03:58 AM
No no, nothing of all this! RecallPanelState simply fills the control with values stored with RecallPanelState (the online help clearly states what this command saves). It does not saves the active state of the controls: you will need to manually call CallCtrlCallback on all controls whose value has an effect on othe controls.
I am not using too SavePanelState, but I remember that at least for tab panels made with the EasyTab instrument you need to individually save each panel state and restore each of them one by one: since this command accepts a panel handle I suppose this remains true even for native CVI tab controls, but this wil need to be checked.
03-06-2009 09:55 AM
cdk52:
There may be situations where we don't want all the other controls to revert back. So I am not sure if SavePanelState/LoadPanelState will help
Roberto Bozollo:
After looking at your suggestion, instead of using the callback data and the SNCallback. Wouldn't it be easier for me just to use a global variable and keep track of what the last value using a simple assignment instead of calling the callback function? Any reason why using the callback function would be better or beneficial to just using a global variable?
Thanks,
Karthik Karkala
03-06-2009 10:19 AM
03-06-2009 11:47 AM
You could also use a static local, instead of a global. When you declare a local function variable with the 'static' storage class, the variable keeps its value from one call of that function to the next, just like a global. However, the variable can only be accessed from within that one function, which is a safety/simplicity advantage over globals.
Mert A.
National Instruments