久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Windows WM_TIMER消息

 VoidOc 2013-10-26

Windows定時器是一種周期性的消息產(chǎn)生裝置,,它會每隔一段指定時間發(fā)送一次定時消息WM_TIMER。它是一個很重要的系統(tǒng)消息,,當(dāng)系統(tǒng)所設(shè)置的時間到達(dá)以后,,系統(tǒng)就會自動發(fā)送該消息。與該消息聯(lián)系密切的函數(shù)是SetTimer(),,它設(shè)置一個系統(tǒng)時鐘,,當(dāng)設(shè)置的時間到時,系統(tǒng)產(chǎn)生WM_TIMER消息,。通過對SetTimer()函數(shù)的參數(shù)進(jìn)行設(shè)置,,可以告訴用戶哪一個時鐘的時間到了。因此,,可以將一些周期性的工作放入WM_TIMER的消息處理函數(shù)中,。

定時器的使用一般遵循下列步驟:

(1)使用SetTimer()函數(shù)設(shè)置定時器

SetTimer()函數(shù)的原型如下:

 

UINT SetTimer(UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT*lpfnTimer)(HWNDUINT, UINT, DWORD));

 

其中,,參數(shù)nIDEvent為新創(chuàng)建的定時器標(biāo)識號碼(非零),,當(dāng)一個應(yīng)用程序需要多個定時器時,靠此參數(shù)的不同來加以區(qū)別,;參數(shù)nElapse為定時器間隔,,以毫秒為單位,當(dāng)由該參數(shù)規(guī)定的時間到后,,系統(tǒng)發(fā)送WM_TIMER消息,;參數(shù)lpfnTimer為指定處理消息WM_TIMER的函數(shù),通常為NULL時,,表示由CWnd對象的OnTimer成員函數(shù)來處理該消息,,當(dāng)然也可以超載該函數(shù)。

如果創(chuàng)建成功,,則返回新的定時器的號碼:否則返回0,。

(2)超載OnTimer()函數(shù),完成用戶希望的操作

通過第一步設(shè)置的定時器會按其設(shè)置的時間間隔向應(yīng)用程序發(fā)送WM_TIMER消息,,為了接收和處理該消息,,應(yīng)超載消息處理函數(shù)OnTimer()(可以由ClassWizard自動產(chǎn)生),,其函數(shù)原型如下:

 

afx_msg void OnTimer(UINT nIDEvent);

 

其中,參數(shù)nIDEvent為定時器的標(biāo)識,。若在程序中設(shè)置了多個定時器時,,靠此參數(shù)的不同來加以區(qū)別。

(3)撤銷定時器

CWnd::KillTimer
    BOOL KillTimer( int nIDEvent );
    返回值:
      指定了函數(shù)的結(jié)果,。如果事件已經(jīng)被銷毀,,則返回值為非零值。如果KillTimer成員函數(shù)不能找到指定的定時器事件,,則返回0,。
    參數(shù):

nIDEvent傳遞給SetTimer的定時器事件值。
傳遞給SetTimer的定時器事件值,。


   說明:
銷毀以前調(diào)用SetTimer創(chuàng)建的用nIDEvent標(biāo)識的定時器事件,。任何與此定時器有關(guān)的未處理的WM_TIMER消息都從消息隊列中清除。



 

定時器使用完后,,可以通過調(diào)用KillTimer()函數(shù)來清除定時器,,其函數(shù)原型如下:

 

BOOL KillTimer(int nIDEvent);

 

其中,參數(shù)nIDEvent為準(zhǔn)備清除的定時器號碼,,該參數(shù)的值必須在SetTimer()函數(shù)中設(shè)置過,,即不能夠清除一個不存在的定時器號碼。

【例9.4 本程序在例9.3程序的基礎(chǔ)上增加定時器的功能,。當(dāng)按B鍵時,,啟動定時器,屏幕上的圖形自動移動,;當(dāng)按S鍵時,,撤銷定時器,停止自動移動,。 程序演示

(1)在字符消息映射函數(shù)中添加啟動和撤銷定時器的代碼

 

void CKeyMsgView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)

{

switch(nChar)

{

case 'b':

case 'B':

SetTimer(1,100,NULL); //建立一號定時器,,時間間隔為100ms

break;

case 's':

case 'S':

KillTimer(1); //撤銷一號定時器

break;

}

}

 

(2)添加WM_TIMER的消息映射函數(shù)OnTimer()的實現(xiàn)代碼

 

void CKeyMsgView::OnTimer(UINT nIDEvent)

{

//圖形往右下角自動移動

CRect OldRect=m_Rect;

m_Rect.OffsetRect(CPoint(1,1)); //圖形往右下角移動一個像素

OldRect.UnionRect(OldRect,m_Rect);

InvalidateRect(OldRect); //將指定矩形區(qū)域OldRect的內(nèi)容刷新

CView::OnTimer(nIDEvent);

}

 

TimerProc函數(shù)是一個應(yīng)用程序定義的回調(diào)函數(shù),用于處理WM_TIMER消息,。

 

函數(shù)原型:

VOID CALLBACK TimerProc(

    HWND hwnd, // 定時器消息的窗口句柄

    UINT uMsg,    // WM_TIMER 消息

    UINT idEvent, // 定時器標(biāo)識符

    DWORD dwTime   // 當(dāng)前系統(tǒng)時間

   );

 

參數(shù)說明:

hwnd

       標(biāo)識了與定時器進(jìn)行關(guān)聯(lián)的窗口,。 

uMsg

       指定WM_TIMER消息。

idEvent

       指定定時器的標(biāo)識符,。 

dwTime

       指定自窗口啟動開始所經(jīng)過的毫秒數(shù),。這是GetTickCount函數(shù)的返回值。

返回值: 

       這個函數(shù)沒有返回值,。

備注: 

TimerProc是一個應(yīng)用程序定義函數(shù)名稱的占位符,。

 

 

百度知道:

SetTimer函數(shù)的用法  1 )用WM_TIMER來設(shè)置定時器

  先請看SetTimer這個API函數(shù)的原型

  UINT_PTR SetTimer(

  HWND hWnd, // 窗口句柄

  UINT_PTR nIDEvent, // 定時器ID,多個定時器時,,可以通過該ID判斷是哪個定時器

  UINT uElapse, // 時間間隔,單位為毫秒

  TIMERPROC lpTimerFunc // 回調(diào)函數(shù)

  );

  例如

  SetTimer(m_hWnd,1,1000,NULL); //一個1秒觸發(fā)一次的定時器

  在MFC程序中SetTimer被封裝在CWnd類中,,調(diào)用就不用指定窗口句柄了

  于是SetTimer函數(shù)的原型變?yōu)椋?/font>

  UINT SetTimer(UINT nIDEvent,UINT nElapse,void(CALLBACK EXPORT *lpfnTimer)(HWND,UINT ,UINT ,DWORD))

  當(dāng)使用SetTimer函數(shù)的時候,就會生成一個計時器,。函數(shù)中nIDEvent指的是計時器的標(biāo)識,,也就是名字。nElapse指的是時間間隔,,

  也就是每隔多長時間觸發(fā)一次事件,。第三個參數(shù)是一個回調(diào)函數(shù),在這個函數(shù)里,,放入你想要做的事情的代碼,,你可以將它設(shè)定為NULL,

  也就是使用系統(tǒng)默認(rèn)的回調(diào)函數(shù),,系統(tǒng)默認(rèn)認(rèn)的是onTime函數(shù),。這個函數(shù)怎么生成的呢?你需要在需要計時器的類的生成onTime函數(shù):

  在ClassWizard里,,選擇需要計時器的類,,添加WM_TIME消息映射,就自動生成onTime函數(shù)了,。然后在函數(shù)里添加代碼,,讓代碼實現(xiàn)功能。

  每隔一段時間就會自動執(zhí)行一次,。

  SetTimer計時器是系統(tǒng)資源,,使用完畢應(yīng)及時用KillTimer銷毀,關(guān)于SetTimer的返回值:如果hWnd為NULL,,返回值為新建立的timer的ID,,如果hWnd非NULL,返回一個非0整數(shù),,如果SetTimer調(diào)用失敗則返回0 ,,簡言之,SetTimer的返回值用于將來的銷毀,。

  改變計時器的時間間隔

  如果想將一個已經(jīng)存在的計時器設(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中,,計時器與其下的PC計時器一樣具有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消息,。

  可見,,計時器并不能嚴(yán)格按照指定的時間間隔發(fā)送WM_TIMER消息,它總要相差那么幾毫秒,。

  即使忽略這幾個毫秒的差別,,計時器仍然不精確。請看原因二:

  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)用程序不會一次收到多個這樣的消息,盡管可能在短時間內(nèi)得到兩個WM_TIMER消息,。應(yīng)用程序不能確定這種處理方式所導(dǎo)致的WM_TIMER消息「遺漏」的數(shù)目,。

  可見,WM_TIMER消息并不能及時被應(yīng)用程序所處理,,WM_TIMER在消息隊列中的延誤可能就不能用毫秒來計算了,。

  由以上兩點,你不能通過在處理WM_TIMER時一秒一秒計數(shù)的方法來計時,。如果要實現(xiàn)一個時鐘程序,,可以使用系統(tǒng)的時間函數(shù)如GetLocalTime

  ,,而在時鐘程序中,,計時器的作用是定時調(diào)用GetLocalTime獲得新的時間并刷新時鐘畫面,當(dāng)然這個刷新的間隔要等于或小于1秒,。

例:

  1) 不用回調(diào)函數(shù)

  SetTimer(1,1000,NULL);

  1:計時器的名稱,;

  1000:時間間隔,單位是毫秒,;

  NULL:使用onTime函數(shù),。

  當(dāng)不需要計時器的時候調(diào)用KillTimer(nIDEvent);

  例如:KillTimer(1);

  2) 調(diào)用回調(diào)函數(shù)

  此方法首先寫一個如下格式的回調(diào)函數(shù)

  void CALLBACK TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime);

  然后再用SetTimer(1,100,TimerProc)函數(shù)來建一個定時器,第三個參數(shù)就是回調(diào)函數(shù)地址,。

  或許你會問,,如果我要加入兩個或者兩個以上的 timer怎么辦?

  繼續(xù)用SetTimer函數(shù)吧,,上次的timer的ID是1,,這次可以是2,3,,4,。。,。,。

  SetTimer(2,1000,NULL);

  SetTimer(3,500,NULL);

  嗯,WINDOWS會協(xié)調(diào)他們的,。當(dāng)然onTimer函數(shù)體也要發(fā)生變化,,要在函數(shù)體內(nèi)添加每一個timer的處理代碼:

  onTimer(nIDEvent)

  {

  switch(nIDEvent)

  {

  case 1:........;

  break;

  case 2:.......;

  break;

  case 3:......;

  break;

  }

  }

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多