10-13-2009 04:38 PM
I have an application that uses a numeric control to enter a position. The control moves a PI translation stage. The users started using the arrow up and down keys to move the translation stages. The problem is that they push the button to fast (like thier waiting for an elevator) and overshoot where they want to be. Once they are done pushing the button for the last time, they have to wait while the system keeps processing the button pushes.
I think everytime they push the button they are queuing an event in the event queue. I double checked the code and I am not calling ProcessSystemEvents() anywhere. I also tried clearing the queue with while(GetUserEvent (0, NULL, NULL)){}; but that didn't work either.
Is there a way to ignore additional button presses until the move is compete?
10-13-2009 11:46 PM
Well, up and down arrows can be hided in the numeric control, either in the UIR editor (via Show / Hide parts... button in the control properties)or setting the corresponding attribute at runtime. This excludes that the user can modify the value other than entering a new number.
One alternative way at code level could be to disable the control while executing the code with SetCtrlAttribute (panelHandle, controlID, ATTR_CTRL_MODE, VAL_INDICATOR); remember to set it to VAL_HOT after you have finished.
Third solution can be to use a global flag set at the beginning of the moving code and reset at the end. In the numeric control callback you must intercept EVENT_KEYPRESS event and swallow it if the flag is set (i.e. use "return 1").
10-14-2009 12:47 AM
Another way to avoid multiple clicks is to dim the control and call ProcessSystemEvents() while it's dimmed. If events are processed while a control is dimmed, those events will get ignored.
See the attached sample program. It gives some options so you can see how the parts work together, but the general flow to avoid multiple clicks is:
In the callback for the numeric control,
Use SetCtrlAttribute to dim the control.
Perform your move function and wait for it to be completed.
ProcessSystemEvents to process any additional clicks while the control was dimmed.
Use SetCtrlAttribute to undim the control.
Return from the callback.
A couple of other options for your callback:
Use SetWaitCursor(1) to show the operator that the program is busy, and then SetWaitCursor(0) after the move is complete.
Use ProcessDrawEvents after you dim the control to show that it's disabled.
My attached sample uses both of these options.
See this thread for a related question.
http://forums.ni.com/ni/board/message?board.id=180&message.id=15262&query.id=1210995#M15262