一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

SetTimer和KillTimer函數(shù)

 冉亮 2010-08-22
SetTimer函數(shù)用于創(chuàng)建一個計(jì)時器,KillTimer函數(shù)用于銷毀一個計(jì)時器。計(jì)時器屬于系統(tǒng)資源,使用完應(yīng)及時銷毀。

  SetTimer的函數(shù)原型如下:
UINT_PTR SetTimer( HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc ) ;
  其中
  hWnd是和timer關(guān)聯(lián)的窗口句柄,此窗口必須為調(diào)用SetTimer的線程所有;如果hWnd為NULL,沒有窗口和timer相關(guān)聯(lián)并且nIDEvent參數(shù)被忽略
  nIDEvent是timer的標(biāo)識,為非零值;如果hWnd為NULL則被忽略;如果hWnd非NULL而且與timer相關(guān)聯(lián)的窗口已經(jīng)存在一個為此標(biāo)識的timer,則此次SetTimer調(diào)用將用新的timer代替原來的timer。timer標(biāo)識和窗口相關(guān),兩個不同的窗口可以擁有nIDEvent相同的tiemr
  uElapse是以毫秒指定的計(jì)時間隔值,范圍為1毫秒到4,294,967,295毫秒(將近50天),這個值指示W(wǎng)indows每隔多久時間給程序發(fā)送WM_TIMER消息。
  lpTimerFunc是一個回調(diào)函數(shù)的指針,俗稱TimerFunc;如果lpTimerFunc為NULL,系統(tǒng)將向應(yīng)用程序隊(duì)列發(fā)送WM_TIMER消息;如果lpTimerFunc指定了一個值,DefWindowProc將在處理WM_TIMER消息時調(diào)用這個lpTimerFunc所指向的回調(diào)函數(shù),因此即使使用TimerProc代替處理WM_TIMER也需要向窗口分發(fā)消息。

  關(guān)于SetTimer的返回值:如果hWnd為NULL,返回值為新建立的timer的ID,如果hWnd非NULL,返回一個非0整數(shù),如果SetTimer調(diào)用失敗則返回0

  KillTimer的函數(shù)原型為:BOOL KillTimer( HWND hWnd, UINT_PTR uIDEvent ) ; 參數(shù)意義同SetTimer。
  關(guān)于KillTimer對消息隊(duì)列中剩余未處理的WM_TIMER消息的影響,MSDN和Programming Windows上的說法完全相反。MSDN的說法很干脆:The KillTimer function does not remove WM_TIMER messages already posted to the message queue. 而petzold則說 The KillTimer call purges the message queue of any pending WM_TIMER messages. Your program will never receive a stray WM_TIMER message following a KillTimer call. (KillTimer消除消息隊(duì)列中任何未處理的WM_TIMER消息,調(diào)用KillTimer后你的程序永遠(yuǎn)不會收到一條“漂泊游蕩”的WM_TIMER消息)

關(guān)于WM_TIMER消息

  wParam為計(jì)時器的ID;如果需要設(shè)定多個計(jì)時器,那么對每個計(jì)時器都使用不同的計(jì)時器ID。wParam的值將隨傳遞到窗口過程中的WM_TIMER消息的不同而不同。
  lParam為指向TimerProc的指針,如果調(diào)用SetTimer時沒有指定TimerProc(參數(shù)值為NULL),則lParam為0(即NULL)。
  可以通過在窗口過程中提供一個WM_TIMER case處理這個消息,或者,默認(rèn)窗口過程會調(diào)用SetTimer中指定的TimerProc來處理WM_TIMER消息

使用計(jì)時器的三種方法

  如果在程序的整個執(zhí)行過程中使用計(jì)時器,一般在處理WM_CREATE消息時或WinMain中消息循環(huán)前調(diào)用SetTimer,在處理WM_DESTROY消息時或在WinMain中消息循環(huán)后return前調(diào)用KillTimer。根據(jù)SetTimer中的參數(shù)不同,有三種方法使用計(jì)時器。

  方法一:調(diào)用SetTimer時指定窗口句柄hWnd,nIDEvent中指定計(jì)時器ID,將lpTimerFunc置NULL從而不使用TimerProc;在窗口過程中處理WM_TIMER消息。調(diào)用KillTimer時,使用SetTimer中指定的hWnd和id。最好使用#define定義timer的id,例如:

#define ID_TIMER 1
SetTimer(hWnd,ID_TIMER,1000,NULL) ;
KillTimer(hWnd,ID_TIMER) ;

  方法二:調(diào)用SetTimer時指定窗口句柄hWnd,nIDEvent中指定計(jì)時器IDlpTimerFunc參數(shù)不為NULL而指定為TimerProc函數(shù)的指針。這種方法使用TimerProc函數(shù)(名字可自定)處理WM_TIMER消息

VOID CALLBACK TimerProc ( HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
 //處理WM_TIMER訊息
}

   TimerProc的參數(shù)hwnd是在調(diào)用SetTimer時指定的窗口句柄。Windows只把WM_TIMER消息送給TimerProc,因此消息參數(shù)總是等于WM_TIMER。iTimerID值是計(jì)時器ID,dwTimer值是與從GetTickCount函數(shù)的返回值相容的值。這是自Windows啟動后所經(jīng)過的毫秒數(shù)。使用這種方法時,相關(guān)函數(shù)調(diào)用的形式為:

SetTimer(hWnd,ID_TIMER,1000,TimerProc) ;
KillTimer(hWnd,ID_TIMER) ;

  方法三:調(diào)用SetTimer時不指定窗口句柄(為NULL),iTimerID參數(shù)自然被忽略,lpTimerFunc不為NULL而指定為TimerProc的指針。正如上面SetTimer的討論中所說的,此時SetTimer的返回值正是新建立的計(jì)時器的ID,需將這個ID保存以供KillTimer銷毀計(jì)時器時所用。當(dāng)然,KillTimer的hWnd參數(shù)也置為NULL。這種方法同樣用TimerProc處理WM_TIMER消息。

UINT_PTR iTimerID ;
iTimerID = SetTimer(NULL,0,1000,TimerProc) ;
KillTimer(NULL,iTimerID) ;

  使用這種方法的好處是不必自己指定計(jì)時器ID,這樣就不必?fù)?dān)心用錯ID。

使用多個計(jì)時器

  使用多個計(jì)時器只要在建立計(jì)時器時指定不同的ID。比如用上面所述方法一時的情況:

#define TIMER_SEC 1
#define TIMER_MIN 2

然后使用兩個SetTimer來設(shè)定兩個計(jì)時器:
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 ;

 

改變計(jì)時器的時間間隔

  如果想將一個已經(jīng)存在的計(jì)時器設(shè)定為不同的時間間隔,可以簡單地用不同的時間值再次調(diào)用SetTimer。

計(jì)時器精確嗎?

  計(jì)時器并不精確。有兩個原因:

  原因一:Windows計(jì)時器是硬件和ROM BIOS架構(gòu)下之計(jì)時器一種相對簡單的擴(kuò)充?;氐絎indows以前的MS-DOS程序?qū)懽鳝h(huán)境下,應(yīng)用程式能夠通過攔截者稱為timer tick的BIOS中斷來實(shí)現(xiàn)時鐘或計(jì)時器。一些為MS-DOS編寫的程序自己攔截這個硬件中斷以實(shí)現(xiàn)時鐘和計(jì)時器。這些中斷每54.915毫秒產(chǎn)生一次,或者大約每秒18.2次。這是原始的IBM PC的微處理器頻率值4.772720 MHz被218所除而得出的結(jié)果。在Windows 98中,計(jì)時器與其下的PC計(jì)時器一樣具有55毫秒的解析度。在Microsoft Windows NT中,計(jì)時器的解析度為10毫秒。Windows應(yīng)用程式不能以高于這些解析度的頻率(在Windows 98下,每秒18.2次,在Windows NT下,每秒大約100次)接收WM_TIMER消息。在SetTimer中指定的時間間隔總是截尾后tick數(shù)的整數(shù)倍。例如,1000毫秒的間隔除以54.925毫秒,得到18.207個tick,截尾后是18個tick,它實(shí)際上是989毫秒。對每個小于55毫秒的間隔,每個tick都會產(chǎn)生一個WM_TIMER消息。
  可見,計(jì)時器并不能嚴(yán)格按照指定的時間間隔發(fā)送WM_TIMER消息,它總要相差那么幾毫秒。

  即使忽略這幾個毫秒的差別,計(jì)時器仍然不精確。請看原因二:
  WM_TIMER消息放在正常的消息隊(duì)列之中,和其他消息排列在一起,因此,如果在SetTimer中指定間隔為1000毫秒,那么不能保證程序每1000毫秒或者989毫秒就會收到一個WM_TIMER消息。如果其他程序的執(zhí)行事件超過一秒,在此期間內(nèi),您的程式將收不到任何WM_TIMER訊息。事實(shí)上, Windows對WM_TIMER消息的處理非常類似于對WM_PAINT消息的處理,這兩個消息都是低優(yōu)先級的,程序只有在消息隊(duì)列中沒有其他消息時才接收它們。
  WM_TIMER還在另一方面和WM_PAINT相似:Windows不能持續(xù)向消息隊(duì)列中放入多個WM_TIMER訊息,而是將多余的WM_TIMER消息組合成一個消息。因此,應(yīng)用程序不會一次收到多個這樣的消息,盡管可能在短時間內(nèi)得到兩個WM_TIMER消息。應(yīng)用程序不能確定這種處理方式所導(dǎo)致的WM_TIMER消息「遺漏」的數(shù)目。
  可見,WM_TIMER消息并不能及時被應(yīng)用程序所處理,WM_TIMER在消息隊(duì)列中的延誤可能就不能用毫秒來計(jì)算了。

  由以上兩點(diǎn),你不能通過在處理WM_TIMER時一秒一秒計(jì)數(shù)的方法來計(jì)時。如果要實(shí)現(xiàn)一個時鐘程序,可以使用系統(tǒng)的時間函數(shù)如GetLocalTime ,而在時鐘程序中,計(jì)時器的作用是定時調(diào)用GetLocalTime獲得新的時間并刷新時鐘畫面,當(dāng)然這個刷新的間隔要等于或小于1秒。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    99热在线精品视频观看| 午夜精品一区二区三区国产| 国产精品久久三级精品| 东京热一二三区在线免| 国产日韩欧美在线播放| 日韩一级毛一欧美一级乱| 久草视频这里只是精品| 黄片免费观看一区二区| 婷婷色网视频在线播放| 免费黄片视频美女一区| 日韩av亚洲一区二区三区| 成人免费视频免费观看| 丰满少妇被粗大猛烈进出视频 | 国产精品熟女在线视频| 五月天丁香婷婷一区二区| 四季精品人妻av一区二区三区| 欧美做爰猛烈叫床大尺度| 黄男女激情一区二区三区| 日本免费一本一二区三区| 中文字幕佐山爱一区二区免费| 亚洲日本中文字幕视频在线观看 | 激情视频在线视频在线视频| 99久久国产精品亚洲| 人妻久久一区二区三区精品99| 欧洲日本亚洲一区二区| 欧美日韩国产成人高潮| 国产三级黄片在线免费看| 欧美性欧美一区二区三区| 国产日韩熟女中文字幕| 国产成人高清精品尤物| 日韩精品免费一区三区| 国产一区二区三区草莓av| 蜜桃av人妻精品一区二区三区| 国产一二三区不卡视频| 尹人大香蕉一级片免费看| 国产一区二区三区丝袜不卡 | 国产午夜精品福利免费不| 草草草草在线观看视频| 男女激情视频在线免费观看| 国产色第一区不卡高清| 亚洲精品偷拍视频免费观看|