Multithreading MFC:更新功能区栏元素以反映操作进度
我正在制作一个模拟工具,在用户定义的迭代次数上运行模拟(在单独的线程中),可以在功能区栏上的编辑控件中输入。我想在模拟过程中重用它来显示当前的迭代。我还放置了CMFCRibbonProgressBar来显示进度。功能区栏是使用资源编辑器创建的 问题是什么是让进度条和迭代计数器及时更新而不导致GUI无响应的方法 传统的ON_UPDATE_命令_UI例程需要在窗口中进行活动,比如移动鼠标 所以我可能需要一个线程来更新这个控件。简单地创建一个线程并尝试从或使用concurrency::parallel_invoke更新控件是不合适的。前者根本不起作用,后者起作用,但会导致GUI冻结 我在文档中存储指针,以简化对控件的访问 我的总体想法是(伪代码)Multithreading MFC:更新功能区栏元素以反映操作进度,multithreading,visual-c++,mfc,ribbon,Multithreading,Visual C++,Mfc,Ribbon,我正在制作一个模拟工具,在用户定义的迭代次数上运行模拟(在单独的线程中),可以在功能区栏上的编辑控件中输入。我想在模拟过程中重用它来显示当前的迭代。我还放置了CMFCRibbonProgressBar来显示进度。功能区栏是使用资源编辑器创建的 问题是什么是让进度条和迭代计数器及时更新而不导致GUI无响应的方法 传统的ON_UPDATE_命令_UI例程需要在窗口中进行活动,比如移动鼠标 所以我可能需要一个线程来更新这个控件。简单地创建一个线程并尝试从或使用concurrency::parallel
正确的实施方法是什么 我通过向执行更新的主窗口添加一个方法解决了这个问题。现在,从上面进行更新的线程会不断将消息发布到主窗口以执行更新:
ASSERT(m_hWnd!=NULL);
MSG msg;
while (simulating)
{
// Handle dialog messages
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(!IsDialogMessage(&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
auto h = static_cast<CMainFrame*>(AfxGetMainWnd())->m_hWnd;
//here code for starting simulation in a separate thread
std::thread updating([this,h]{
while (simulating)
{
::PostMessage(h, WM_UPDATE_VISUALS, sumulator.getCurrentIteration(), 0);
std::this_thread::sleep_for(std::chrono::milliseconds(40));
}
::PostMessage(h, WM_UPDATE_VISUALS, num_iterations, 0);
});
updating.detach()
auto h=static_cast(AfxGetMainWnd())->m_hWnd;
//这里是在单独线程中启动模拟的代码
线程更新([this,h]{
同时(模拟)
{
::PostMessage(h,WM_UPDATE_VISUALS,sumulator.getCurrentIteration(),0);
std::this_线程::sleep_for(std::chrono::毫秒(40));
}
::PostMessage(h,WM_UPDATE_VISUALS,num_iterations,0);
});
正在更新.detach()
我一开始犯了一个微妙的错误,通过引用捕获了h,很快就过期了
但最后,上述代码正是我想要实现的请您对此代码进行一些澄清,好吗?它是如何解决OPs问题的?它的作用是什么?该代码只是防止GUI冻结,因为它允许在模拟运行时处理对话框消息。我想,这几乎是直截了当的。如果这不能解决您的问题,也许您可以提供真实的MFC代码而不是伪代码,这样我就可以更好地理解您的意思。
auto h = static_cast<CMainFrame*>(AfxGetMainWnd())->m_hWnd;
//here code for starting simulation in a separate thread
std::thread updating([this,h]{
while (simulating)
{
::PostMessage(h, WM_UPDATE_VISUALS, sumulator.getCurrentIteration(), 0);
std::this_thread::sleep_for(std::chrono::milliseconds(40));
}
::PostMessage(h, WM_UPDATE_VISUALS, num_iterations, 0);
});
updating.detach()