LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Question regarding numeric controls

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

0 Kudos
Message 1 of 8
(3,721 Views)

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:

  • update the other controls as required
  • call SavePanelState() to record the current state of the panel in a file on disk

If an invalid SN is entered:

  • pop up your "Invalid Serial Number" dialog
  • call RecallPanelState() to "roll back" all controls to the last consistent state

 

If you wish, you could use RecallPanelState() when your program starts, to display the last-retrieved database record.

 

Regards,

Colin.

 

0 Kudos
Message 2 of 8
(3,719 Views)

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 Smiley Wink

 

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.

Message Edited by Roberto Bozzolo on 03-05-2009 11:56 PM


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 3 of 8
(3,706 Views)
I've never used the SavePanelState() / RecallPanelState() function, so I
wonder what their potential uses are.
When you recall a panel state, does it trigger all the control events that
_would_ have been necessary to reach that state from the previous one,
changing each control one by one ? In what order ? I can see plenty of
contradictions if that is the case (for instance a bool control the disables
other controls).
--
Guillaume Dargaud
http://www.gdargaud.net/


0 Kudos
Message 4 of 8
(3,685 Views)

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.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 5 of 8
(3,684 Views)

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

0 Kudos
Message 6 of 8
(3,664 Views)
While a global variable can indeed work for your needs, their use is considered bad programming practice since it makes less readable a program: a global variable could potentially be modified from everywhere in the program so you are not always sure of what its content is; this universality could also make more complicated to debug a program that heavily relies on globals; look here for a brief explanation of it. I tend to agree with this opinion especially considering the need for code maintenability over time and when you share coding with other programmers: the use of globals must be well documented and clearly noted every time in the program you are using them.


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 7 of 8
(3,659 Views)

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

0 Kudos
Message 8 of 8
(3,649 Views)