0

我正在修复一个用 C++ 编写的 MFC 应用程序。它是一个 GUI,它与通过 USB 连接到 PC 的外部模块进行通信。

我想避免使用单独的线程。有没有办法可以将东西添加到主循环中,以便它连续运行而不是基于事件?

我希望主循环在每个循环中调用函数 runCommStack()。

4

3 回答 3

1

当没有消息(如键、鼠标、重绘)到达时,主循环暂停程序,等待下一条消息。所以向主循环添加调用的想法会给你带来非常不稳定的操作。例如,最小化您的窗口将停止所有 USB 通信。

使用 SetTimer 并在 WM_TIMER 处理程序中调用 runCommStack 函数可能会更令人满意。

于 2013-08-14T13:29:59.433 回答
1

一些可能的方法:

  1. 您可以使用CWnd::SetTimer来设置计时器。
  2. 您可以覆盖CWinApp::OnIdle(由 调用CWinApp::Run)。
  3. 您可以覆盖CWinApp:Run、复制和修改原始 MFC 的CWinApp:Run. 这绝对不是最简单的解决方案。
  4. 您可以创建一个后台线程。

这取决于runCommStack(). 这个功能运行时间长吗?那么您可能不想在 GUI 线程中运行它。runCommStack 是否需要每 n 毫秒调用一次?那么在它自己的线程中运行它也可能会更好。在其他情况下,您可以只使用计时器或 OnIdle 方法。

关于解决方案 1:正如 Tim 指出的那样,WM_TIMER消息是低优先级消息,不会传递给应用程序,而其他高优先级消息在消息队列中。另请参见确定窗口消息的优先级

使用解决方案 2,您应该提醒OnIdle只有在没有可用的窗口消息时才会调用它。所以这与解决方案 1 完全相同(实际上更糟一些)。

另请记住,如果调用对话框或显示消息框,解决方案 2 和 3 可能会导致您runCommStack没有被调用。DoModal()这是因为在MessageBox()控制期间没有返回CWinApp::Run()

我会实施解决方案 1 或 4。

于 2013-08-14T11:24:45.723 回答
0

您可以将空闲处理与CWinApp::OnIdle一起使用;如果读取您的 USB 设备只需要很短的时间,这将起作用,否则在长时间读取期间用户界面将被阻止。

但是使用单独的线程绝对是更好的方法。

于 2013-08-14T10:07:14.777 回答