user1190832
user1190832

Reputation:

MFC - Add function call to mainloop?

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

Answers (3)

ScottMcP-MVP
ScottMcP-MVP

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

Werner Henze
Werner Henze

Reputation: 16771

Some possible approaches:

  1. You can use CWnd::SetTimer to set a timer.
  2. You can override CWinApp::OnIdle (called by CWinApp::Run).
  3. You can override CWinApp:Run, copying and modifying the original MFC's CWinApp:Run. This definitely is not the easiest solution.
  4. You can create a background thread.

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

Jabberwocky
Jabberwocky

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

Related Questions