MFC:更新 Ribbon Bar 元素以反映操作进度
Posted
技术标签:
【中文标题】MFC:更新 Ribbon Bar 元素以反映操作进度【英文标题】:MFC: Update Ribbon Bar elements to reflect operation progress 【发布时间】:2014-08-30 00:37:34 【问题描述】:我正在制作一个模拟工具,它在用户定义的迭代次数上运行模拟(在单独的线程中),可以在功能区栏上的编辑控件中输入。我想重用它来显示模拟期间的当前迭代。我还放了 CMFCRibbonProgressBar 来显示进度。功能区栏是使用资源编辑器创建的。
问题是什么才能让进度条和迭代计数器及时更新而不导致 GUI 无响应?
ON_UPDATE_COMMAND_UI 例程的传统方式需要在窗口中进行活动,例如移动鼠标。
所以我可能需要一个线程来更新这个控件。诸如简单地创建线程并尝试从 concurrency::parallel_invoke 更新控件或使用 concurrency::parallel_invoke 之类的事情是不合适的。前者根本不起作用,后者起作用,但会导致 GUI 冻结。
我在文档中存储指针以简化对控件的访问。 https://***.com/a/25429446?noredirect=1
我的大致思路是(伪代码)
beginUpdatingThread()
while(simulating)
updateEditControl();
updateProgressBar();
sleep_40_ms();//conserves the resorces as there is no sense to update more frequent than 25 times per second
实现这一点的正确方法是什么?
【问题讨论】:
【参考方案1】: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);
【讨论】:
您能否对此代码进行一些澄清?它如何解决 OPs 问题以及它的作用是什么? 该代码只是防止您的 GUI 冻结,因为它允许在您的模拟运行时处理您的对话消息。这很简单,我想。如果这不能解决您的问题,也许您可以提供真正的 MFC 代码而不是伪代码,这样我可以更好地理解您的意思。【参考方案2】:我通过向执行更新的主窗口添加一个方法解决了这个问题。现在从上面更新的线程不断地向主窗口发布消息以执行更新:
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()
一开始我犯了一个微妙的错误,通过引用捕获 h,它很快就会过期 但最后,上面的代码正是我想要实现的目标
【讨论】:
以上是关于MFC:更新 Ribbon Bar 元素以反映操作进度的主要内容,如果未能解决你的问题,请参考以下文章
(转载)VS2010/MFC编程入门之五十三(Ribbon界面开发:为Ribbon Bar添加控件)
VS2010/MFC编程入门之五十二(Ribbon界面开发:创建Ribbon样式的应用程序框架)