2014-08-30 52 views
0

我正在製作一個仿真工具,它可以在用戶定義的迭代次數上運行仿真(在單獨的線程中),可以在功能區欄的Edit控件中進行輸入。我想重複使用它來顯示仿真過程中的當前迭代。我也把CMFCRibbonProgressBar顯示進度。功能區欄是使用資源編輯器創建的。MFC:更新功能區欄元素以反映操作進度

問題是什麼才能獲得進度條和迭代計數器以及時更新而不會導致GUI無響應?

ON_UPDATE_COMMAND_UI例程的傳統方法需要窗口中的活動,例如移動鼠標。

所以我可能需要一個線程來更新這個控件。諸如簡單地創建一個線程並試圖更新來自或使用concurrency :: parallel_invoke的控件並不合適。前者根本不起作用,後者起作用,但會導致GUI凍結。

我將指針存儲在我的文檔中以簡化對控件的訪問。 https://stackoverflow.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 
} 
} 

什麼是實現這個的正確方法?

回答

0

我解決了這個問題,方法是在執行更新的主窗口中添加一個方法。現在從上面的連續消息發佈到主窗口中的線程更新來執行更新:

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() 

我首先由細微的錯誤被參考,從而迅速過期 但最後,上面的代碼捕獲ħ正是我想要達到的目標

0
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); 
    } 
    } 
} 
+0

請問您可以在此代碼中添加一些說明嗎?它是如何解決OP問題的呢?它是如何解決的? – 2014-08-31 14:59:49

+0

該代碼只是讓您的GUI不會凍結,因爲它允許在仿真運行時處理對話消息。我想,這非常簡單。如果這不能解決你的問題,也許你可以提供真正的MFC代碼而不是僞代碼,所以我可以更好地理解你的意思。 – thomiel 2014-08-31 15:42:28