2013-07-19 249 views
0

我正在做一個測量系統,我在我的程序中有while while循環。在循環中,它正在檢查是否有任何電機正在移動,因爲它需要在做任何事情之前到達目標位置。MFC雖然循環

在進行測量時,假設告訴我進行測量需要多長時間。

但是,只要它在do while循環中運行,我的所有定時器功能就會停止,就好像它們被置於睡眠模式一樣。

有沒有其他的方法可以實現呢?如果有,請幫助我。

任何幫助將不勝感激。

SetTimer(TIMERECHO, 1000, NULL); 

BOOL bMoving = FALSE; 
do 
{ 
    if (IsMoving(ID, NULL, &bMoving)) 
     GetPosition(); 
} while (bMoving); 


void CLHMDlg::OnTimer(UINT_PTR nIDEvent) 
{ 
    // TODO: Add your message handler code here and/or call default 
    switch(nIDEvent) 
    { 
     case TIMERECHO: 
      UpdateData(FALSE); 
      m_Seconds++; 
      m_TimerEcho.Format(_T("Total time: %ds"), m_Seconds); 
      break; 
    } 
    CDialogEx::OnTimer(nIDEvent); 
} 

回答

0

這是因爲你的循環沒有處理消息。 onTimer被稱爲windows消息的結果。您需要繼續處理循環中的消息或使用基於回調的計時器。

一種方法是使用CreateTimerQueueTimer http://msdn.microsoft.com/en-us/library/windows/desktop/ms682485%28v=vs.85%29.aspx

+0

我該怎麼做?對不起,我是MFC編程的初學者。 – Ashton

+0

一個基於回調的定時器仍然需要一個消息循環 - 回調只是由'DefWindowProc'調用。 –

+0

不,如果它是舊的MM定時器的後代版本之一,則「回調」定時器不需要消息循環,如http://msdn.microsoft.com/en-us/library/windows /desktop/ms682485%28v=vs.85%29.aspx – MichaelH

1

MFC具有消息循環獲取和發送消息,如WM_TIMER。如果你做了一個while循環,那個消息循環沒有運行。它沒有睡覺,它只是等到你停止處理器。

你有兩個選擇:(1)擺脫冗長的循環,並做WM_TIMER消息定期做的事情。 (2)使用第二個線程執行冗長的操作。這對初學者來說有很多困難。

+0

我想如何編碼它,使我不會得到while循環來處理處理器?你能幫我解決嗎?謝謝 – Ashton

+0

而不是循環使用定時器來定期進行測試。每次你做測試返回到MFC。這是不要處理器的方法。 –

+0

如果您關心您的應用程序使用多少CPU,請不要坐在檢查時間的緊密循環中。使用Windows中可用的基於回調的定時器之一(請參閱上面我的回覆中的鏈接) – MichaelH

0

一個非常簡單的解決方案(但並不完美),讓你運行的是你的IsMoving移動到計時器如下:

void CLHMDlg::OnTimer(UINT_PTR nIDEvent) 
{ 
    // TODO: Add your message handler code here and/or call default 
    switch(nIDEvent) 
    { 
     case TIMERECHO: 
      if (IsMoving(ID, NULL, &bMoving)) 
       GetPosition(); 

      UpdateData(FALSE); 
      m_Seconds++; 
      m_TimerEcho.Format(_T("Total time: %ds"), m_Seconds); 
      break; 
    } 
    CDialogEx::OnTimer(nIDEvent); 
} 

但是你必須使用這個線程妥善解決,複雜性這對於簡單到更好的解決方案而言也會有所不同。我爲你編寫了一些代碼,它可能無法編譯,但你明白了。

AfxBeginThread(monitor_motor, this); 

UINT monitor_motor(LPVOId lParam) 
{ 
CMyDlg * dlg = (CMyDlg *) lParam; 
HWND hWnd = (HWND) dlg->m_hWnd; 


do 
{ 
    if (IsMoving(ID, NULL, &dlg->bMoving)) 
     GetPosition(); 

    Sleep(100); // maybe you don't have to poll too hard and give other hardware chance to communicate?..that's upto you 

    PostMessage(hWnd, UPDATE_TIMER_AND_STUFF); 
} while (dlg->bMoving); 

PostMessage(hWnd, UPDATE_MOTOR_MOVED_COMPLETELY); 

} 
+0

對不起,回覆遲了。但是在我的測量中是否需要調用此線程?我有一個「OnMeasurementStart」。我是否需要將線程包含在我的按鈕中? – Ashton

+0

是的,這將是最好的方法。我實際上自己也在做類似的事情,在這種情況下,關於使用線程的相關資源並不多。 – zar

+0

我的意思是,如何將線程調用到我的按鈕?@zadane – Ashton