LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

updating value in numeric box

Hi.

You don't necessarily have to stop the timer to solve your problem; simply use a static "edit flag" variable in your control callback, and call the control callback from the timer callback.

I have attached a file to illustrate what I mean.

Regards,
Colin.

 

Message Edited by cdk52 on 03-31-2006 08:56 AM

0 Kudos
Message 11 of 21
(2,164 Views)

Thanks for ur suggestion. Well i use my timer control to control what panels get updated and stuff....Well each numeric box i hv a callback function...this is where i check n take in the new value. looking at the code u attached...i tried trapping more events....now it wrks much better than before......i hv attached the callback code...bt now everytime i left click n highlight the value in the box...the timer stops...thus update of all boxes stops.....i input the new value and if i click anywhere else on the panel the timer doesnt resume....bt if i click inside any numeric box it starts wrk fine again n the value that was changed gets updated! also if i click in the same box i was changin the value nothing happens this is because i hv the event got_focus......ideally would love to hv it set so that if user clicks anywhere it starts wrking fine again rather than hvin specifically click inside any other numeric box.

hope to hear from you soon.

thanks

k1_ke

attached is the code...

int CVICALLBACK WriteCallback (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 unsigned int Add,value;
 unsigned int add,val;
 
 switch (event)
 {
      case EVENT_KEYPRESS:
             in_progress=1;
             break;
      case EVENT_VAL_CHANGED:
             in_progress=1;
             break;
     case EVENT_LEFT_CLICK: 
             SetCtrlAttribute (panelhandle, MAIN_TIMER, ATTR_ENABLED, 0);  //enables timer
             break;
     case EVENT_GOT_FOCUS:
             in_progress=0;
             break;
     case EVENT_LOST_FOCUS:
             if(in_progress)
              { 
                    SetrlAttribute (panelhandle, MAIN_TIMER, ATTR_ENABLED, 1);  //enables timer
                    in_progress=1;
               }
              break;
     case EVENT_COMMIT:
           / here is the code that changes the value in modbus
            break;

    }
     return 0;
}

 

0 Kudos
Message 12 of 21
(2,141 Views)
Try adding
SetCtrlAttribute (panelhandle, MAIN_TIMER, ATTR_ENABLED, 1);  //enables timer
to the EVENT_COMMIT as well. 
If you use the Operate Tool you can see which events are "fired" as you operate the user interface to try and find any other scenarios that may have been missed.
0 Kudos
Message 13 of 21
(2,137 Views)

I took a look at the events generated when you enter an leave a control.  This is going to require a little more testing but it may work.

I added a panel callback to enable the timer when you click on the panel outside the control.  I left the flags out of this version since I did not need them.  But you can do it any way works for you.

int CVICALLBACK WriteCallback (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 unsigned int Add,value;
 unsigned int add,val;
 
 switch (event)
 {
      case EVENT_KEYPRESS:
             SetCtrlAttribute (panelhandle, MAIN_TIMER, ATTR_ENABLED, 0);  //enables timer
             break;
//      case EVENT_VAL_CHANGED:
//             break;
     case EVENT_LEFT_CLICK:
             SetCtrlAttribute (panelhandle, MAIN_TIMER, ATTR_ENABLED, 0);  //enables timer
             break;
     case EVENT_GOT_FOCUS:
             SetCtrlAttribute (panelhandle, MAIN_TIMER, ATTR_ENABLED, 0);  //enables timer
             break;
     case EVENT_LOST_FOCUS:
             SetCtrlAttribute (panelhandle, MAIN_TIMER, ATTR_ENABLED, 1);  //enables timer
              break;
     case EVENT_COMMIT:
            // here is the code that changes the value in modbus
            SetCtrlAttribute (panelhandle, MAIN_TIMER, ATTR_ENABLED, 1);
            break;

    }
     return 0;
}


int  CVICALLBACK Panel_CB(int panel, int event, void *callbackData, int eventData1, int eventData2)
{

 switch (event)
 {
     case EVENT_LEFT_CLICK:
             SetCtrlAttribute (panelhandle, MAIN_TIMER, ATTR_ENABLED, 1);  //enables timer
             break;
    }
     return 0;
}

 

0 Kudos
Message 14 of 21
(2,133 Views)
One more change in the callback for the control
   case EVENT_LEFT_CLICK:
             SetCtrlAttribute (panelhandle, MAIN_TIMER, ATTR_ENABLED, 0);  //enables timer
             return(1);  // swallow the left click event 
   case EVENT_GOT_FOCUS:
 
 

Message Edited by mvr on 03-31-2006 11:11 AM

0 Kudos
Message 15 of 21
(2,131 Views)

Hi mvr,

Thanks for the reply. I did what u told me....now it wrks much better....when the programs loads...i ahve to left click inorder to start the timer...even though by default the timer is enabled...any ideas?? so after i left click...it starts running....i go in a numeric box...highlight it...change the value n when i left click outside it wrks fine.....if i use the code then it doesnt even let me highlight the numeric box.......

case EVENT_LEFT_CLICK:
             SetCtrlAttribute (panelhandle, MAIN_TIMER, ATTR_ENABLED, 0);  //enables timer
             return(1);  // swallow the left click event 

   case EVENT_GOT_FOCUS:
 
But now the problem is that....on my main uir...i hv buttons for other panels.....so say nw i click on a button, another panel shows up n the main panel is hidden.....n when in my new panel i press back it should go back to main panel......i dont disable the timer bt still when main panel comes back the timer is disabled.....when i left clcik in the main panel...it starts wrking fine......what could b the reason?
 
thanks for the help! really appreciate it!
 
k1_ke
0 Kudos
Message 16 of 21
(2,092 Views)

What you describe could happen if either there was a missing break statement in the switch statement or if the numeric control is by default the active control on your panel.  You want a different item on the panel to be the first item to become the active control.

The more I play around with this the more it looks like there are potential traps everywhere to this implementation.  If you have the time, it can probably be made to work, but handling the events this way can be a bit tricky.  It your preferance, but seperating the display indicator and input control would be so much simpler to implement. 

Which ever way you choose to go.  Good Luck.

0 Kudos
Message 17 of 21
(2,086 Views)

Hi, thanks for a quick reply. I checked for missing break statements..they are all fine. What do u mean by numeric control is an active control? Well i hv a callback attached to this numeric control......in this control is where i stop the timer....take in the new value....and then as u suggested i hv a panel callback...which jus enables the timer.

When you say separting display and input control...can u please elabrote a little more.....well in the numeric callback...i only read in the value.....the displaying happens in another callback which is called using a timer control.

Do u think its because of one of the above reasons u mentioned that when i go to another panel n come back to the main panel the timer stops??

k1_ke

Message Edited by k1_ke on 04-06-2006 02:31 PM

0 Kudos
Message 18 of 21
(2,085 Views)

I am going to have to answer this in parts. 

>>What do u mean by numeric control is an active control?

The only things that can turn the timer off are  EVENT_KEYPRESS,  EVENT_LEFT_CLICK, and EVENT_GOT_FOCUS being sent to the control callback.  The most likely one is EVENT_GOT_FOCUS being set when the program is first loaded and when the you click from some other panel back to the main panel.  But this control would only get that event if it was already active, that is it is the control that currently is selected to get the events from windows (like a mouse click). 

0 Kudos
Message 19 of 21
(2,076 Views)
>>When you say separting display and input control...
 
You keep the numeric control you have as an indicator.   This is updated by the callback, just as you have now. 
You use a second input control to allow the operator to update the value.  They simply click on that control and enter the number.  The callback for the input control uses the EVENT_COMMIT from that control to disable the timer, update the indicator and the modbus stuff, then re-enable the timer. 
There is a catch with this arrangement,  the increment arrow generates an EVENT_COMMIT each time it is clicked, if this causes problems you can use a separate "Command Button" to handle the update after they have set the control to value desired. 
 
Keeping your input controls separate from your display indicators is just a lot simpler to manage in the long run, particularly when you have some continuous event like a timer going off in the background.  In this case, you may not even have to turn the timer off.  If your timer and update control callbacks do not have anything within them that calls ProcessSystemEvents(), the timer callback is blocked by your update control callback and you can update the indicator without any conflicts with the timer. 
 
Correct Event handling is a tricky thing, especially for new users to CVI or event driven programming environments.  It sometimes trips up the best of us.  But when you do get comfortable with it, it is a very powerful programming tool.
 
[edit for spelling]

Message Edited by mvr on 04-06-2006 02:13 PM

0 Kudos
Message 20 of 21
(2,076 Views)