SDK編程筆記 — 計時器篇_第1頁
SDK編程筆記 — 計時器篇_第2頁
SDK編程筆記 — 計時器篇_第3頁
SDK編程筆記 — 計時器篇_第4頁
SDK編程筆記 — 計時器篇_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、SDK編程筆記 計時器篇什么時候我們需要用到SetTimer函數(shù)呢?當你需要每個一段時間執(zhí)行一件事的的時候就需要使用SetTimer函數(shù)了。 讓我們先來看看SetTimer函數(shù)的原型: UINT SetTimer(UINT nIDEvent,UINT nElapse,void(CALLBACK EXPO RT *lpfnTimer)(HWND,UINT ,YINT ,DWORD) 當使用SetTimer函數(shù)的時候,就會生成一個計時器。函數(shù)中nIDEvent指的是計時器的標識,也就是名字。nElapse指的是時間間隔,也就是每隔多長時間觸發(fā)一次事件。第三個參數(shù)是一個回調(diào)函數(shù),在這個函數(shù)里,放入你

2、想要做的事情的代碼,你可以將它設(shè)定為NULL,也就是使用系統(tǒng)默認的回調(diào)函數(shù),系統(tǒng)默認認的是onTime函數(shù)。這個函數(shù)怎么生成的呢?你需要在需要計時器的類的生成onTime函數(shù):在ClassWizard里,選擇需要計時器的類,添加WM_TIME消息映射,就自動生成onTime函數(shù)了。然后在函數(shù)里添加代碼,讓代碼實現(xiàn)功能。每隔一段時間就會自動執(zhí)行一次。 例: SetTimer(1,1000,NULL); 1:計時器的名稱; 1000:時間間隔,單位是毫秒; NULL:使用onTime函數(shù)。 當不需要計時器的時候調(diào)用KillTimer(nIDEvent); 例如:KillTimer(1); 2. 或

3、許你會問,如果我要加入兩個或者兩個以上的 timer怎么辦? 繼續(xù)用SetTimer函數(shù)吧,上次的timer的ID是1,這次可以是2,3,4。 SetTimer(2,1000,NULL); SetTimer(3,500,NULL); 嗯,WINDOWS會協(xié)調(diào)他們的。當然onTimer函數(shù)體也要發(fā)生變化,要在函數(shù)體內(nèi)添加每一個timer的處理代碼: onTimer(nIDEvent) switch(nIDEvent) case 1:.; break; case 2:.; break; case 3:.; break; *SDK編程筆記 計時器篇 兩個計時器API的討論SetTimer函數(shù)用于創(chuàng)建

4、一個計時器,KillTimer函數(shù)用于銷毀一個計時器。計時器屬于系統(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的標識,為非零值;如果hWnd為NULL則被忽略;如果hWnd非NULL而且與timer相關(guān)聯(lián)的窗口已經(jīng)

5、存在一個為此標識的timer,則此次SetTimer調(diào)用將用新的timer代替原來的timer。timer標識和窗口相關(guān),兩個不同的窗口可以擁有nIDEvent相同的tiemr uElapse是以毫秒指定的計時間隔值,范圍為1毫秒到4,294,967,295毫秒(將近50天),這個值指示W(wǎng)indows每隔多久時間給程序發(fā)送WM_TIMER消息。 lpTimerFunc是一個回調(diào)函數(shù)的指針,俗稱TimerFunc;如果lpTimerFunc為NULL,系統(tǒng)將向應(yīng)用程序隊列發(fā)送WM_TIMER消息;如果lpTimerFunc指定了一個值,DefWindowProc將在處理WM_TIMER消息時調(diào)用

6、這個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對消息隊列中剩余未處理的WM_TIMER消息的影響,MSDN和Programming Windows上的說法完全相反。MSDN的

7、說法很干脆: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消除消息隊列中任何未處理的WM_

8、TIMER消息,調(diào)用KillTimer后你的程序永遠不會收到一條“漂泊游蕩”的WM_TIMER消息) 關(guān)于WM_TIMER消息wParam為計時器的ID;如果需要設(shè)定多個計時器,那么對每個計時器都使用不同的計時器ID。wParam的值將隨傳遞到窗口過程中的WM_TIMER消息的不同而不同。lParam為指向TimerProc的指針,如果調(diào)用SetTimer時沒有指定TimerProc(參數(shù)值為NULL),則lParam為0(即NULL)。 可以通過在窗口過程中提供一個WM_TIMER case處理這個消息,或者,默認窗口過程會調(diào)用SetTimer中指定的TimerProc來處理WM_TIMER

9、消息使用計時器的三種方法如果在程序的整個執(zhí)行過程中使用計時器,一般在處理WM_CREATE消息時或WinMain中消息循環(huán)前調(diào)用SetTimer,在處理WM_DESTROY消息時或在WinMain中消息循環(huán)后return前調(diào)用KillTimer。根據(jù)SetTimer中的參數(shù)不同,有三種方法使用計時器。方法一:調(diào)用SetTimer時指定窗口句柄hWnd,nIDEvent中指定計時器ID,將lpTimerFunc置NULL從而不使用TimerProc;在窗口過程中處理WM_TIMER消息。調(diào)用KillTimer時,使用SetTimer中指定的hWnd和id。最好使用#define定義timer的i

10、d,例如:#define ID_TIMER 1 SetTimer(hWnd,ID_TIMER,1000,NULL) ;KillTimer(hWnd,ID_TIMER) ;方法二:調(diào)用SetTimer時指定窗口句柄hWnd,nIDEvent中指定計時器ID,lpTimerFunc參數(shù)不為NULL而指定為TimerProc函數(shù)的指針。這種方法使用TimerProc函數(shù)(名字可自定)處理WM_TIMER消息:VOID CALLBACK TimerProc ( HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)/處理WM_TIMER訊息 Time

11、rProc的參數(shù)hwnd是在調(diào)用SetTimer時指定的窗口句柄。Windows只把WM_TIMER消息送給TimerProc,因此消息參數(shù)總是等于WM_TIMER。iTimerID值是計時器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不為N

12、ULL而指定為TimerProc的指針。正如上面SetTimer的討論中所說的,此時SetTimer的返回值正是新建立的計時器的ID,需將這個ID保存以供KillTimer銷毀計時器時所用。當然,KillTimer的hWnd參數(shù)也置為NULL。這種方法同樣用TimerProc處理WM_TIMER消息。UINT_PTR iTimerID ; iTimerID = SetTimer(NULL,0,1000,TimerProc) ;KillTimer(NULL,iTimerID) ;使用這種方法的好處是不必自己指定計時器ID,這樣就不必擔心用錯ID。使用多個計時器使用多個計時器只要在建立計時器時指定

13、不同的ID。比如用上面所述方法一時的情況:#define TIMER_SEC 1#define TIMER_MIN 2然后使用兩個SetTimer來設(shè)定兩個計時器: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īng)存

14、在的計時器設(shè)定為不同的時間間隔,可以簡單地用不同的時間值再次調(diào)用SetTimer。計時器精確嗎?計時器并不精確。有兩個原因:原因一:Windows計時器是硬件和ROM BIOS架構(gòu)下之計時器一種相對簡單的擴充?;氐絎indows以前的MS-DOS程序?qū)懽鳝h(huán)境下,應(yīng)用程式能夠通過攔截者稱為timer tick的BIOS中斷來實現(xiàn)時鐘或計時器。一些為MS-DOS編寫的程序自己攔截這個硬件中斷以實現(xiàn)時鐘和計時器。這些中斷每54.915毫秒產(chǎn)生一次,或者大約每秒18.2次。這是原始的IBM PC的微處理器頻率值4.772720 MHz被218所除而得出的結(jié)果。在Windows 98中,計時器與其下的P

15、C計時器一樣具有55毫秒的解析度。在Microsoft Windows NT中,計時器的解析度為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,它實際上是989毫秒。對每個小于55毫秒的間隔,每個tick都會產(chǎn)生一個WM_TIMER消息。 可見,計時器并不能嚴格按照指定的時間間隔發(fā)送WM_TIMER消息,它總要相

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

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論