維尼的蜂巢

RealTime??!! It’s amazing!!!!

win32 api的 SetTimer 四月 28, 2006

Filed under: VC++/C++/C — kevinlin @ 5:10 下午

SetTimer是一個計數器

原型是這樣   UINT_PTR SetTimer( HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc ) ;

在程式裡我們可以 設定多少時間要做什麼事情 他會觸發WM_TIMER

#define TIMER_SEC 1
#define TIMER_MIN 2
然後使用兩個SetTimer來設定兩個計時器:
SetTimer (hwnd, TIMER_SEC, 1000, NULL) ;
SetTimer (hwnd, TIMER_MIN, 60000, NULL) ;
WM_TIMER的處理如下所示:
case WM_TIMER:
 switch (wParam)
 {
  case TIMER_SEC:
   //每秒一次的處理
   break ;
  case TIMER_MIN:
   //每分鐘一次的處理
   break ;
 }
 return 0 ;

我發現了一個問題

如果TIMER_SEC(每秒1次)做了2分鐘 那TIMER_MIN(每分1次)該怎麼辦
事實上WM_TIMER的訊息在整個OS上的優先權很低的跟WM_PAINT一樣都很低
就是說 當我們正在處理WM_TIMER時 又有WM_TIMER想進來訊息佇列 他會自己當作沒看到 就像是 你只付一人份的錢 以為雙胞胎想輪流著吃飯我會不知道嗎

訊息佇列總會只有一份WM_TIMER存在 所以如果TIMER_SEC處理了2分鐘 那就等到處理完 再看哪個計數器幸運 牌比較前面

 

2 Responses to “win32 api的 SetTimer”

  1. 訪客 Says:


    我發現了一個問題

    如果TIMER_SEC(每秒1次)做了2分鐘 那TIMER_MIN(每分1次)該怎麼辦
    事實上WM_TIMER的訊息在整個OS上的優先權很低的跟WM_PAINT一樣都很低
    就是說 當我們正在處理WM_TIMER時 又有WM_TIMER想進來訊息佇列 他會自己當作沒看到 就像是 你只付一人份的錢 以為雙胞胎想輪流著吃飯我會不知道嗎

    我用VC6测试了一下,发现你说的是错误的

  2. kevin Says:

    恩~~的確說錯了,多謝你的指正,沒有詳細的注意到,timer訊息是不會miss掉的,除非超過一個最大的值😛

    與WM_PAINT訊息一樣WM_TIMER是一個低優先權的訊息,如果訊息佇列中還有其他訊息 WM_TIMER就會被暫時擱置,而且當佇列裡已經有WM_TIMER訊息尚未被處理又發生第二個第三個訊息,作業系統只會合併第二以及後續抵達的WM_TIMER訊息,佇列中一樣只保留一個WM_TIMER訊息。

    所以訊息佇列裡面只能有一個WM_TIMER是確定的😛

    計時器是因為時脈晶片的硬體中斷而具備計算時間的能力,在Windows 98/ME 作業系統下計時器的精度與時脈晶片觸發的精度相符,大約為55毫秒(54.925),Windows NT/2000/XP則有10毫秒的能力,也就是說,對Windows 98/ME作業系統來說,每秒鐘所收到的WM_TIMER訊息不會超過18個。


發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s