Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ MFC GUI应用程序重写-线程、消息、文档/视图等。需要建议_C++_Windows_Mfc_Thread Safety - Fatal编程技术网

C++ MFC GUI应用程序重写-线程、消息、文档/视图等。需要建议

C++ MFC GUI应用程序重写-线程、消息、文档/视图等。需要建议,c++,windows,mfc,thread-safety,C++,Windows,Mfc,Thread Safety,我正在重写一个有很多问题的MFC应用程序。主要问题是它不稳定 它是一个GUI应用程序,通过USB与外部模块通信。因此,它使用计时器每n毫秒运行一次通信堆栈。但是,系统调用不允许在计时器回调中进行,因此程序不稳定、崩溃和挂起很多 因此,我必须重写应用程序,以便在后台线程中运行通信堆栈。 这里的另一个问题是数据没有完全与表示分离,如果我使用另一个线程,我必须确保保护共享资源 因此,通信堆栈主要会通知应用程序有新数据。这应该由工作线程处理。它运行通信堆栈,处理新消息,然后在更新数据结构时锁定数据结构,

我正在重写一个有很多问题的MFC应用程序。主要问题是它不稳定


它是一个GUI应用程序,通过USB与外部模块通信。因此,它使用计时器每n毫秒运行一次通信堆栈。但是,系统调用不允许在计时器回调中进行,因此程序不稳定、崩溃和挂起很多

因此,我必须重写应用程序,以便在后台线程中运行通信堆栈。 这里的另一个问题是数据没有完全与表示分离,如果我使用另一个线程,我必须确保保护共享资源

因此,通信堆栈主要会通知应用程序有新数据。这应该由工作线程处理。它运行通信堆栈,处理新消息,然后在更新数据结构时锁定数据结构,然后回复模块。然后,它向主线程发送一条带有PostMessage的消息以更新GUI

但是用户也可以告诉应用程序将数据发送到外部模块。这可以通过三种方式完成: 1.发送数据一次。 然后,主线程将向工作线程发送一条消息,以便从队列中取出一条消息并将其发送到模块。 2.定期发送数据。这需要在工作线程内使用一个计时器,或者一个标志就足够了,它将在线程更新函数的每个循环中发送数据。 3.向模块发送消息并等待响应。这需要使用计时器来检查工作线程内的超时。在接收到消息时,工作线程必须通知主线程,以便用响应更新GUI

所以我需要: 1.在单独的线程中运行通信堆栈。comm堆栈是一个状态机,一旦检查新数据,调用它就会通过它运行。它没有while循环。您还可以在其API中调用函数来发送数据

  • 向主线程发送消息,以便在发生事件时更新GUI

  • 向工作线程发送消息,告知它从应用程序发送数据

  • 因此,我的问题是: 1.MFC使用文档/视图模型。我很难找到最好的方法来匹配我想做的事情,或者我是否想部分放弃(跳过文档,用我自己的方式存储数据)。 *如何最好地组织数据?有一个包含所有应用程序数据的大结构,然后工作线程和主线程在访问它时都必须锁定它吗? *当我向主线程发送消息以更新GUI时,如何最好地将消息映射到函数?使用消息映射?但是消息映射是针对windows而不是线程的?我需要确定只有主线程访问GUI。我需要将GUI中的每个不同更改映射到某个函数。这是很多消息,因为GUI中没有统一的显示,而是有很多不同的选项卡(消息日志、对象、自定义消息)


  • 如何处理消息?由于工作线程可以通过正常运行堆栈以及当应用程序告诉它发送消息时访问堆栈,因此我必须完成对堆栈的一次调用,然后再进行另一次调用。如果线程更新总是在处理新消息之前完成它所做的事情,那么这不是问题。或者,当计时器点击时,我可能在堆栈内部,或者我从主线程收到一条新消息,它也开始处理堆栈?也许我不仅要为其他线程锁定堆栈,还要确保工作线程本身不会“同时”以两种方式访问堆栈

  • 重新设置消息和消息映射:

    windows消息队列不会中断程序或线程。消息在队列中等待,直到您返回到消息循环,然后它退出队列并分派下一条消息(如果有消息正在等待)


    正确的消息映射(在主线程中)是针对windows的。工作线程必须向主线程窗口发布或发送消息。如果您有很多这样的消息,那么最好将它们全部发布到主窗口(CMainFrame)。在CMInframe映射中为每条消息添加消息项。然后,CMInframe中的处理程序函数可以根据需要调用其他窗口来更新GUI显示。

    无法将整个消息放入帖子中,因此请阅读这些注释。2。如何处理消息?由于工作线程可以通过正常运行堆栈以及当应用程序告诉它发送消息时访问堆栈,因此我必须完成对堆栈的一次调用,然后再进行另一次调用。如果线程更新总是在处理新消息之前完成它所做的事情,那么这不是问题。或者当计时器点击时,我可能在堆栈中,或者我从主线程收到一条新消息,它也开始处理堆栈?也许我不仅要为其他线程锁定堆栈,还要确保工作线程本身不会“同时”以两种方式访问它。“不允许在计时器回调中进行系统调用“-谁告诉你的?嗯,我现在找不到资源,但我在某个地方读过,发现来源可信。不确定是官方文件还是stackoverflow。还有一位对Windows编程有很多了解的人也这么说。这不是真的吗?使用计时器时出现了几个问题。一个问题是在执行回调时调用了timeKillEvent。代码中的另一个地方使用不同的计时器。也许我不应该使用void CALLBACK TimeProc(UINT-uID、UINT-uMsg、DWORD-dwUser、DWORD-dw1、DWORD-dw2),而应该只使用OnTimer?计时器回调只是Windows提供的一种方便,在正常的消息处理过程中被调用,而不是通常的
    WM\u timer
    处理程序。它没有任何不适用于任何其他messa的限制