LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Responding to events from within callback function

I have a very simple problem which somehow turned out to be difficult to solve...

My application is starting to take measurements after hiting a Run button (a callback function is assigned to it). This measurement can take quite a long time, so I would like to give a user a chance to break it. And now the problem comes. I cannot find a way to respond to user actions from within a callback function. Once it is invoked I simply cannot do anything, or not everything seems to work as it should.

First question:
How can I check from within callback function if user pressed any key (I couldn't find anything in standard libraries). But I don't wan't to wait until user will press something, I just want to check if ES
C for example was pressed.

Apart from checking the keybord I would like to be able to stop the measurement when the user will press second time the Run button. That involves checking event (EVENT_COMMIT) information. GetUserEvent function for some reason behaves very strange. Apart from processing draw events and giving me the data I need (panel and control numbers) it invokes the callback function which is assigned to the control which was pressed. That's much not normal!!! And doesn't make much sense! If I want to check the event commit information, to be able to process it and respond to it no other callback function should be invoked! Using
SetSystemAttribute (ATTR_SUPPRESS_EVENT_PROCESSING, 1);
doesn't help at all.

Second question:
Is there any way to solve this problem and quit from callback function when user will wish so.

In an attachent is a very simple program (CVI 5.0) which demonstrates my problem
0 Kudos
Message 1 of 4
(3,440 Views)
I've not looked at your source, but hopefully got the 'jist' of what you are trying to do.

A couple of methods I could suggest would be to have your callback execute the measurement code in a seperate thread. You could disable the button to launch that test once entering the new thread. You new thread performing the measurement could then check periodically a variable / flag indicating whether or not an exit from the measurement was requested.
Since the thread would be executing in parallel to the user interface callbacks, the action of say pressing an abort button could set this flag. The thread would detect this, terminate and un-dim the control that started the measurement (and performing any cleanup required).

A more simple method without the thread aspect, would be to include at regular intervals throughout your measurement callback to include a few ProcessEvents calls.
I am assuming that within your measurement code (perhaps I should have opened your code), that it continues until finished.

If say your exit callback (could be your main Call backs function) set a flag, and within your measurements code you checked for that flag it would require to ProcessEvents call to allow that code to execute.

If your measurements code for example was a for loop from 1 to 1 billion, it would execute in its entirety before any user events were actioned. But the placing of a ProcessEvents within your loop would allow the User Interface callbacks to be executed and thus you could update a flag in here.

The disadvantage of the second method over the thread method is that say you called an external function called getMeasurement that you had no control over, you would still have to wait the finite period for that function to complete execution before stopping the measurement, by which time it has already finished.

Using a thread method you can effectively kill the thread at your own discression as and when required (performing the necessary clean up functions)

Hope this helps more than confuses, if you need me to go any further, just give drop me a mail (chris.a.wright@motorola.com) or via this list.
Message 2 of 4
(3,440 Views)
There is something I did not mentioned and I should. In my real application I have almost 20 controls on the panel, most of them have associated callbacks. And I don't want any of these callbacks to be invoked when the measurements are in progres. In both cases either with multithread programing (what in fact I wouldn't like to use as my programs fits well to one thread concept) or with placing a ProcessEvents call inside my measurement callback a user will be able to invoke all these callbacks. What is nasty as well - hiting a Run button second time will start measurement function again from the begining. Dimming (or changing to indicators) manually by the measurement callback all these controls after starting a measurement that's a lot of work and doesn't look ver
y professional.

I still think that invoking a callbacks by GetUserEvent function is a bug, which makes quite a lot of trouble. And to be honest I'm still not sure how nicely solve my problem 😕

Thanks Chris for taking your time and answering my question.
0 Kudos
Message 3 of 4
(3,440 Views)
The dimming of the controls can be achieved in two lines by ensuring that the 'tab' ordering of the controls in question are consecutive, and then just running a single loop to dim them all, and then on completion of the mesurement, another loop to un-dim them.

Good luck with the problem...
0 Kudos
Message 4 of 4
(3,440 Views)