Reputation:
I am fixing a MFC applivation written in C++. It is a GUI and it communicates with an external module connected to the PC via USB.
I want to avoid using a separate thread. Is there a way I can add things to the mainloop so that it runs continously rather than being event based?
I want the mainloop to make a call to a function runCommStack() in every loop.
Upvotes: 0
Views: 1142
Reputation: 10425
When there are no messages (like keys, mouse, repaint) arriving the main loop suspends the program, waiting for the next message. So the idea of adding a call to the main loop will give you very erratic operation. For example, minimizing your window will stop all the USB communication.
Using SetTimer and calling your runCommStack function in a WM_TIMER handler will probably be much more satisfactory.
Upvotes: 1
Reputation: 16771
Some possible approaches:
CWnd::SetTimer
to set a timer.CWinApp::OnIdle
(called by CWinApp::Run
).CWinApp:Run
, copying and modifying the original MFC's CWinApp:Run
. This definitely is not the easiest solution.It depends on the requirements of runCommStack()
. Is this function running long times? Then you probably won't want to run it in the GUI thread. Does runCommStack need to get called every n milliseconds? Then it might also be better to run it in it's own thread. In other cases you can just use the timer or OnIdle approach.
Regarding solution 1: as Tim pointed out WM_TIMER
messages are low priority messages and will not be passed to the application while other higher-priority messages are in the message queue. See also Determine priority of a window message.
With solution 2 you should remind that OnIdle
will only be called if no window message is available. So this is quite the same as solution 1 (in fact a little worse).
Also keep in mind that solutions 2 and 3 might result in your runCommStack
not getting called if a dialog's DoModal()
is called or if a message box is displayed. This is because during MessageBox()
the control is not returned to CWinApp::Run()
.
I'ld implement solution 1 or 4.
Upvotes: 1
Reputation: 50883
You can use idle processing with CWinApp::OnIdle; this will work if reading your USB device takes only a short amount of time, otherwise the user interface will be blocked during long reads.
But using a separate thread is definitely a better method.
Upvotes: 0