LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

A CVICALLBACK is been executing all the time

Hello,

My panel have a "Acquire" button. It is an "Edtit text button". Its callback is "Acquire_MSMAM" and this callback is ONLY associated to this control. You can find a portion of the code (the relevant, i think) at the file I have attached:

"CallbackCODE.txt"


Well, it runs in the main thread always, and launch another thread, as you can see.
When I click the "Acquire" button, it seems run correctly. Then, if I click at any place of the window: controls, panels, etc., the behaviour is the same that if i click the "Acquire" button.

I have debugged it and this second time, when I click at any place of the window:
- The "Acquire" button is powered off
- its executed the "Acquire_MSMAM" callback,
- the "o
n" variable gets the 0 value (because the button is powered off, i think)
- its executed the "Invalidate_the_Acquisition();" sentence.
- the previous call to "Acquire_MSMAM" finish their execution from
CmtWaitForThreadPoolFunctionCompletion

Could somebody tell me why this occurs? I'd like to be active the other controls at my panel while it is waiting for thread pool function completion.

Thanks in advance,
Silmarba.
0 Kudos
Message 1 of 7
(3,670 Views)
Just from a quick glance, I would suggest that it may have something to do with the EVENT_COMMIT that you are using.

I believe that any event will generate and EVENT_COMMIT, even moving the mouse, losing / gaining focus, etc etc, so your switch statement will always get executed, and since the button value will remain on until you click it off, your case 1 will always be executed.

I would suggest using the control ID in there somewhere as well,

i.e. switch (event && (controlId == YourControlID))

So it will only launch your case1 statement if an EVENT occurs and the Control was your btn, and the btn val was ON.

Also, to switch it off, do the reverse, only do something if an EVENT occurs and the control ID is
your Btn (and its new value is OFF)

If you n
eed me to explain it a bit more, let me know, I just posted a few quick thoughts really,

Regards

Chris
0 Kudos
Message 2 of 7
(3,670 Views)
I am sorry, maybe I haven't explained very well at the first time.

Could you examine the sample project that I have prepared and attached? (It is more simple than original but with the same problem)

At the file "Comments.h" you can find a little explanation.

If there is something you don't understand, could you tell me it, please?

Thanks,
silmarba
0 Kudos
Message 3 of 7
(3,670 Views)
Silmarba...

Ok, having seen it and run it, I think I can help you out here some more.

It is related to what I said previously, in that it is related to the way you are handling the various callbacks.

I have included the following two lines with each call back:

printf("*********************************\nChange Color CALLBACK\nEvent:%d\nControl:%d\nEventData1:%d\nEventData1:%d\n*********************************\n",event,control,eventData1,eventData2);


printf("*********************************\nAQUIRE CALLBACK\nEvent:%d\nControl:%d\nEventData1:%d\nEventData1:%d\n*********************************\n",event,control,eventData1,eventData2);


When you run your application, you can get even more weird behaviour than you state. For example, click the Aquire Button, and then click anywhere else (even off the window).

I shall try and explain it a bit more:

Lets say I run the application,and then I click the aquire button.
This causes the callback Acquire_MSMAM to be called.
You get the attribute for the control and do one of two things.

The first thing to note here, is that you are using the EVENT_COMMIT event.
A single click of your aquire button will cause the callback to be called more than once. In this first case it will be called 3 times.
1st Time: When it gets focus
2nd Time: Something happens
3rd Time: Something else happens (you'll have to check up on these because I forgot to write them down).

But the point is, more than one event will occur for a simple single click of your acquire button.

Now lets assume I have clicked the aquire button, and its quite happily running away, and I now click the Change Color button.

You should see that the Call Back for the Acquire Button is called first.
This is because this will generate an EVENT_COMMIT but the event will be a LOST_FOCUS. Since you clicked off the control and onto a new one, the old one has to lose focus and hence generates its own call back, before it performs the callback on the Change Color Callback.

In this case, it will switch off the Acquire button before it actions the change color callback.

Also, since you don't control how many times it performs the ON and OFF action for the acquire, it gets confused quite easily when you start clicking elsewhere.

You need to check your logic when starting and stopping the acquisition, and also when change color.


Define Some Rules:


1. Only Start and Acquisition if:
a. One is not already running
b. Or, If the control is showing 'off', an acq must be running so don't start another one.
c. If the control is showing 'on', then don't stop an acq.
etc etc

Don't just use EVENT_COMMIT, you must use EVENT_COMMIT and something else, since multiple events can occur on a control, and also events can be generated when pressing other controls. You will have to say use the Control_ID, the eventData1 and eventData2 to actually determine what exactly you want to do.


Just run your app with the new source file attached and look at the I/O Window, and see the events that occur. Single Stepping through the app with this is not the same as when you run it, because the action of clicking off the application when in single step mode, will of course generate its own different set of events.

So, just run it at full speed and watch the I/O Window.

If I get time, I will try and put the proper fixes in for you, but with the above information, you should now see what is happening...

Let me know

Chris

(Mail me at chris.a.wright@motorola.com) if you want a quicker reply offline from here)
0 Kudos
Message 4 of 7
(3,670 Views)
Chris,

I have retouched the code in order that the output become more intuitive, making the event values to be named. I have incremented the events management at Acquire callback too, but I am sure that it doesn't solve the problem.


Well, could you run the new version and sending me a txt file with your output, please ? The only that you have to do is exactly the thing you assume:

"Now lets assume I have clicked the aquire button, and its quite happily running away, and I now click the Change Color button."

The reason is, as you can see at "output2.txt" file that I send you, that the behaviour that you explain to me IS NOT the behaviour that I can observe at my computer.

You said:
"You should see that the Call Ba
ck for the Acquire Button is called first. ... , before it performs the callback on the Change Color Callback."

But I can see that the Call Back for the Acquire Button is called first AND ONLY and it performs the callback on the Change Color Callback NEVER (unless, of course, you click again the Change Color button).


Regards,
silmarba
Download All
0 Kudos
Message 5 of 7
(3,670 Views)
Hello, silmarba

You've found a problem related to the CmtWaitForThreadPoolFunctionCompletion function. The problem has to do with the function not processing User Interface library events properly, even when you specify the OPT_TP_PROCESS_EVENTS_WHILE_WAITING flag. As a result of this, the main thread cannot update its internal notion of the mouse cursor position, and it incorrectly reports any future mouse activity as still taking place over the button (which is wher it was when the original callback was called).

We've fixed the problem, but for now you'll have to work around it. The best workaround I can think of is to not use that function. Instead, you can just set a global variable in the worker thread whenever it fin
ishes executing. The main thread can then check for this variable in a loop and break out of the loop when the variable's value changes. The critial element though, is that while the main thread waits for the variable to change, it should call ProcessSystemEvents. This will allow the UI library to be responsive.

Luis Gomes
NI
0 Kudos
Message 6 of 7
(3,670 Views)
Ok Luis,
I understand what is happening, and I will try to work around the problem.

Really, thanks for all, I was becoming very confused.

silmarba.
0 Kudos
Message 7 of 7
(3,670 Views)