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

分享

VS2010/MFC編程入門(mén)之四十四(MFC常用類(lèi):定時(shí)器Timer)

 牛人的尾巴 2015-10-27

       前面一節(jié)雞啄米講了CTime類(lèi)和CTimeSpan類(lèi)的使用,本節(jié)繼續(xù)講與時(shí)間有關(guān)的定時(shí)器。定時(shí)器并不是一個(gè)類(lèi),主要考慮到,提起時(shí)間的話(huà)就不能不說(shuō)定時(shí)器,所以就把它放到CTime和CTimeSpan之后講解。

       定時(shí)器簡(jiǎn)介

       定時(shí)器,可以幫助開(kāi)發(fā)者或者用戶(hù)定時(shí)完成某項(xiàng)任務(wù)。在使用定時(shí)器時(shí),我們可以給系統(tǒng)傳入一個(gè)時(shí)間間隔數(shù)據(jù),然后系統(tǒng)就會(huì)在每個(gè)此時(shí)間間隔后觸發(fā)定時(shí)處理程序,實(shí)現(xiàn)周期性的自動(dòng)操作。例如,我們可以在數(shù)據(jù)采集系統(tǒng)中,為定時(shí)器設(shè)置定時(shí)采集時(shí)間間隔為1個(gè)小時(shí),那么每隔1個(gè)小時(shí)系統(tǒng)就會(huì)采集一次數(shù)據(jù),這樣就可以在無(wú)人操作的情況下準(zhǔn)確的進(jìn)行操作。

       MFC定時(shí)器

       VS2010編程中,我們可以使用MFC的CWnd類(lèi)提供的成員函數(shù)SetTimer實(shí)現(xiàn)定時(shí)器功能,也可以使用Windows API函數(shù)SetTimer來(lái)實(shí)現(xiàn)。兩者使用方法實(shí)際上很類(lèi)似,但也有不同。

       CWnd類(lèi)的SetTimer成員函數(shù)只能在CWnd類(lèi)或其派生類(lèi)中調(diào)用,而API函數(shù)SetTimer則沒(méi)有這個(gè)限制,這是一個(gè)很重要的區(qū)別。因?yàn)楸窘坛讨饕侵v解MFC編程,所以這里就先重點(diǎn)講解MFC定時(shí)器的用法,關(guān)于API函數(shù)SetTimer的用法雞啄米會(huì)在MFC定時(shí)器講解的基礎(chǔ)上進(jìn)行延伸。

       雞啄米下面分步驟給出使用MFC定時(shí)器的方法。

       1、啟動(dòng)定時(shí)器。

       啟動(dòng)定時(shí)器就需要使用CWnd類(lèi)的成員函數(shù)SetTimer。CWnd::SetTimer的原型如下:

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

       參數(shù)nIDEvent指定一個(gè)非零的定時(shí)器ID;參數(shù)nElapse指定間隔時(shí)間,單位為毫秒;參數(shù)lpfnTimer指定一個(gè)回調(diào)函數(shù)的地址,如果該參數(shù)為NULL,則WM_TIMER消息被發(fā)送到應(yīng)用程序的消息隊(duì)列,并被CWnd對(duì)象處理。如果此函數(shù)成功則返回一個(gè)新的定時(shí)器的ID,我們可以使用此ID通過(guò)KillTimer成員函數(shù)來(lái)銷(xiāo)毀該定時(shí)器,如果函數(shù)失敗則返回0。

       通過(guò)SetTimer成員函數(shù)我們可以看出,處理定時(shí)事件可以有兩種方式,一種是通過(guò)WM_TIMER消息的消息響應(yīng)函數(shù),一種是通過(guò)回調(diào)函數(shù)。

       如果要啟動(dòng)多個(gè)定時(shí)器就多次調(diào)用SetTimer成員函數(shù)。另外,在不同的CWnd中可以有ID相同的定時(shí)器,并不沖突。

       2、為WM_TIMER消息添加消息處理函數(shù),或者定義回調(diào)函數(shù)。

       如果調(diào)用CWnd::SetTimer函數(shù)時(shí)最后一個(gè)參數(shù)為NULL,則通過(guò)WM_TIMER的消息處理函數(shù)來(lái)處理定時(shí)事件。添加WM_TIMER消息的處理函數(shù)的方法是,在VS2010工程的Class View類(lèi)視圖中找到要添加定時(shí)器的類(lèi),點(diǎn)擊右鍵,選擇Properties,顯示其屬性頁(yè),然后在屬性頁(yè)工具欄上點(diǎn)擊Messages按鈕,下面列表就列出了所有消息,找到WM_TIMER消息,添加消息處理函數(shù)。添加后,cpp文件中會(huì)出現(xiàn)類(lèi)似如下內(nèi)容:

C++代碼
  1. BEGIN_MESSAGE_MAP(CExample44Dlg, CDialogEx)   
  2.     ......   
  3.     ON_WM_TIMER()   
  4. END_MESSAGE_MAP()   
  5.   
  6. void CExample44Dlg::OnTimer(UINT_PTR nIDEvent)   
  7. {   
  8.     // TODO: Add your message handler code here and/or call default   
  9.   
  10.     CDialogEx::OnTimer(nIDEvent);   
  11. }  

       之后就可以在OnTimer函數(shù)中進(jìn)行相應(yīng)的處理了。OnTimer的參數(shù)nIDEvent為定時(shí)器ID,即在SetTimer成員函數(shù)中指定的定時(shí)器ID,如果有多個(gè)定時(shí)器,我們可以像下面這樣處理:

C++代碼
  1. void CExample44Dlg::OnTimer(UINT_PTR nIDEvent)      
  2. {      
  3.     // TODO: Add your message handler code here and/or call default      
  4.     switch (nIDEvent)      
  5.     {      
  6.     case 1:      
  7.         // 如果收到ID為1的定時(shí)器的消息則調(diào)用func1函數(shù)      
  8.         func1();      
  9.         break;      
  10.     case 2:      
  11.         // 如果收到ID為2的定時(shí)器的消息則調(diào)用func2函數(shù)      
  12.         fun2();    
  13.        break;     
  14.     ......      
  15.     default:      
  16.         break;      
  17.     }      
  18.      
  19.     CDialogEx::OnTimer(nIDEvent);      
  20. }     

       如果調(diào)用CWnd::SetTimer函數(shù)時(shí)最后一個(gè)參數(shù)不為NULL,則需要定義回調(diào)函數(shù)。回調(diào)函數(shù)的形式如下:

C++代碼
  1. void CALLBACK EXPORT TimerProc(   
  2.   
  3. HWND hWnd, // handle of CWnd that called SetTimer   
  4.   
  5. UINT nMsg, // WM_TIMER   
  6.   
  7. UINT nIDEvent // timer identification   
  8.   
  9. DWORD dwTime // system time   
  10.   
  11. );  

       參數(shù)hWnd為調(diào)用SetTimer成員函數(shù)的CWnd對(duì)象的句柄,即擁有此定時(shí)器的窗口的句柄;參數(shù)nMsg為WM_TIMER,而且總是為WM_TIMER;參數(shù)nIDEvent為定時(shí)器ID;參數(shù)dwTime為系統(tǒng)啟動(dòng)以來(lái)的毫秒數(shù),即GetTickCount函數(shù)的返回值。

       這樣CWnd::SetTimer函數(shù)最后一個(gè)參數(shù)就可以為T(mén)imerProc。

       這里注意下,回調(diào)函數(shù)的名稱(chēng)不一定為T(mén)imerProc,可以取其他名字,但返回值類(lèi)型、參數(shù)的類(lèi)型和個(gè)數(shù)不能改變。

       雞啄米給出一個(gè)回調(diào)函數(shù)的例子:

C++代碼
  1. void CALLBACK EXPORT TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime)      
  2. {      
  3.    switch(nTimerid)      
  4.    {      
  5.    case 1:       
  6.          // 處理ID為1的定時(shí)器的事件      
  7.          func1();      
  8.          break;      
  9.    case 2:       
  10.          // 處理ID為2的定時(shí)器的事件      
  11.          func2();      
  12.          break;    
  13.    ......   
  14.    default:   
  15.         break;     
  16.    }      
  17. }     

       回調(diào)函數(shù)為全局函數(shù),需要寫(xiě)在使用它的位置的前面,或者寫(xiě)在后面然后在使用之前聲明。

       3、銷(xiāo)毀定時(shí)器。

       不再使用定時(shí)器時(shí),可以銷(xiāo)毀它。銷(xiāo)毀定時(shí)器需使用CWnd類(lèi)的KillTimer成員函數(shù),CWnd::KillTimer函數(shù)的原型如下:

C++代碼
  1. BOOL KillTimer(UINT_PTR nIDEvent);  

       參數(shù)nIDEvent為要銷(xiāo)毀的定時(shí)器的ID,是調(diào)用CWnd::SetTimer函數(shù)時(shí)設(shè)置的定時(shí)器ID。如果定時(shí)器被銷(xiāo)毀則返回TRUE,而如果沒(méi)有找到指定的定時(shí)器則返回FALSE。

       如果要銷(xiāo)毀多個(gè)定時(shí)器,則多次調(diào)用KillTimer函數(shù)并分別傳入要銷(xiāo)毀的定時(shí)器的ID。

       通過(guò)Windows API函數(shù)使用定時(shí)器

       如果我們不使用MFC定時(shí)器,而通過(guò)Windows API函數(shù)使用定時(shí)器,其實(shí)是很類(lèi)似的。下面雞啄米簡(jiǎn)單說(shuō)下步驟吧。

       1、啟動(dòng)定時(shí)器。

       使用API函數(shù)SetTimer啟動(dòng)定時(shí)器,SetTimer函數(shù)的原型如下:

C++代碼
  1. UINT_PTR SetTimer(         
  2.     HWND    
  3.             hWnd,   
  4.     UINT_PTR    
  5.             nIDEvent,   
  6.     UINT    
  7.             uElapse,   
  8.     TIMERPROC    
  9.             lpTimerFunc   
  10. );  

       參數(shù)hWnd為與定時(shí)器關(guān)聯(lián)的窗口的句柄;參數(shù)nIDEvent為非零的定時(shí)器ID,如果hWnd等于NULL,且還不存在ID為nIDEvent的定時(shí)器,那么nIDEvent參數(shù)被忽略,然后生成一個(gè)新ID的定時(shí)器,而如果hWnd不為NULL,且hWnd指定的窗口已存在ID為nIDEvent的定時(shí)器,那么這個(gè)已存在的定時(shí)器被新定時(shí)器所取代。參數(shù)uElapse和lpTimerFunc同CWnd::SetTimer函數(shù)。

       2、為WM_TIMER消息添加消息處理函數(shù),或者定義回調(diào)函數(shù)。

       如果調(diào)用SetTimer函數(shù)時(shí)最后一個(gè)參數(shù)為NULL,我們需要自己為WM_TIMER消息添加處理函數(shù),要注意的是,WM_TIMER消息的附加數(shù)據(jù)wParam為定時(shí)器ID,lParam為回調(diào)函數(shù)的指針,如果調(diào)用SetTimer時(shí)回調(diào)函數(shù)為NULL,那么lParam也為NULL。

       而如果調(diào)用SetTimer函數(shù)時(shí)最后一個(gè)參數(shù)不為NULL,我們就需要定義回調(diào)函數(shù)?;卣{(diào)函數(shù)的定義同MFC定時(shí)器。

       3、銷(xiāo)毀定時(shí)器。

       銷(xiāo)毀定時(shí)器使用KillTimer API函數(shù),原型如下:

C++代碼
  1. BOOL KillTimer(HWND hWnd,UINT_PTR uIDEvent);   

       參數(shù)hWnd為與定時(shí)器關(guān)聯(lián)的窗口的句柄,與啟動(dòng)定時(shí)器時(shí)SetTimer函數(shù)的hWnd參數(shù)值相同;參數(shù)uIDEvent為要銷(xiāo)毀的定時(shí)器的ID,如果傳遞給SetTimer的參數(shù)hWnd有效,則uIDEvent應(yīng)與傳遞給SetTimer的參數(shù)nIDEvent相同,而如果SetTimer的參數(shù)hWnd為NULL,則uIDEvent應(yīng)為SetTimer返回的定時(shí)器ID。該函數(shù)成功則返回TRUE,否則返回FALSE。

       MFC定時(shí)器應(yīng)用實(shí)例

       雞啄米給大家演示一個(gè)定時(shí)器的例子,該實(shí)例功能很簡(jiǎn)單,就是使用兩個(gè)定時(shí)器,定時(shí)更新兩個(gè)編輯框中的顯示內(nèi)容,第一個(gè)編輯框每秒刷新一次,從1刷新到10,然后銷(xiāo)毀定時(shí)器,第二個(gè)編輯框每?jī)擅胨⑿乱淮?,?刷新到5,然后銷(xiāo)毀定時(shí)器。下面簡(jiǎn)單說(shuō)下步驟:

       1、創(chuàng)建基于對(duì)話(huà)框的工程,名稱(chēng)設(shè)為“Example44”。

       2、在自動(dòng)生成的對(duì)話(huà)框模板IDD_EXAMPLE44_DIALOG中,刪除“TODO: Place dialog controls here.”靜態(tài)文本控件。添加兩個(gè)靜態(tài)文本框控件,Caption分別設(shè)為“1秒鐘刷新一次”和“2秒鐘刷新一次”,再添加兩個(gè)個(gè)Edit Control控件,ID使用默認(rèn)的IDC_EDIT1和IDC_EDIT2,兩者的Read Only屬性都設(shè)為T(mén)rue。此時(shí)的對(duì)話(huà)框模板如下圖:

MFC定時(shí)器對(duì)話(huà)框模板

       3、為CExample44Dlg類(lèi)添加兩個(gè)成員變量,分別為m_nData1、m_nData2,并在CExample44Dlg類(lèi)的構(gòu)造函數(shù)中初始化:

C++代碼
  1. CExample44Dlg::CExample44Dlg(CWnd* pParent /*=NULL*/)   
  2.     : CDialogEx(CExample44Dlg::IDD, pParent)   
  3. {   
  4.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);   
  5.     // 兩個(gè)數(shù)據(jù)初始化為0   
  6.     m_nData1 = 0;   
  7.     m_nData2 = 0;   
  8. }  

       4、在對(duì)話(huà)框模板上雙擊OK按鈕,添加點(diǎn)擊消息的處理函數(shù),并修改如下:

C++代碼
  1. void CExample44Dlg::OnBnClickedOk()   
  2. {   
  3.     // TODO: Add your control notification handler code here   
  4.     // 啟動(dòng)ID為1的定時(shí)器,定時(shí)時(shí)間為1秒   
  5.     SetTimer(1, 1000, NULL);   
  6.     // 啟動(dòng)ID為2的定時(shí)器,定時(shí)時(shí)間為2秒   
  7.     SetTimer(2, 2000, NULL);   
  8.   
  9.     //CDialogEx::OnOK();   
  10. }  

       這樣,點(diǎn)擊OK按鈕時(shí)就不會(huì)退出,而是啟動(dòng)兩個(gè)定時(shí)器。

       5、根據(jù)上面MFC定時(shí)器講解中為WM_TIMER消息添加處理函數(shù)的方法,添加WM_TIMER的消息處理函數(shù)OnTimer,并修改其實(shí)現(xiàn)如下:

C++代碼
  1. void CExample44Dlg::OnTimer(UINT_PTR nIDEvent)   
  2. {   
  3.     // TODO: Add your message handler code here and/or call default   
  4.     switch (nIDEvent)   
  5.     {   
  6.     case 1:   
  7.         // 如果m_nData1已經(jīng)達(dá)到10,則銷(xiāo)毀ID為1的定時(shí)器   
  8.         if (10 == m_nData1)   
  9.         {   
  10.             KillTimer(1);   
  11.             break;   
  12.         }   
  13.         // 刷新編輯框IDC_EDIT1的顯示   
  14.         SetDlgItemInt(IDC_EDIT1, ++m_nData1);   
  15.         break;   
  16.     case 2:   
  17.         // 如果m_nData2已經(jīng)達(dá)到5,則銷(xiāo)毀ID為2的定時(shí)器   
  18.         if (5 == m_nData2)   
  19.         {   
  20.             KillTimer(2);   
  21.             break;   
  22.         }   
  23.         // 刷新編輯框IDC_EDIT2的顯示   
  24.         SetDlgItemInt(IDC_EDIT2, ++m_nData2);   
  25.     default:   
  26.         break;   
  27.     }   
  28.   
  29.     CDialogEx::OnTimer(nIDEvent);   
  30. }  

       6、運(yùn)行程序,點(diǎn)擊OK按鈕,查看效果。

MFC定時(shí)器實(shí)例

       關(guān)于定時(shí)器的內(nèi)容就講這些,相信了解了這些,一般的定時(shí)器應(yīng)用都能解決了。雞啄米謝謝大家一直以來(lái)的陪伴,讓我有動(dòng)力更新下去??!

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    国产高清一区二区不卡| 久久香蕉综合网精品视频| 麻豆剧果冻传媒一二三区| 国产又猛又黄又粗又爽无遮挡 | 麻豆果冻传媒一二三区| 成人精品一区二区三区综合| 人妻人妻人人妻人人澡| 日本免费熟女一区二区三区| 亚洲第一视频少妇人妻系列| 女厕偷窥一区二区三区在线| 精品欧美日韩一二三区| 国产精品免费福利在线| 国产女性精品一区二区三区| 亚洲性生活一区二区三区| 91日韩欧美中文字幕| 少妇人妻无一区二区三区| a久久天堂国产毛片精品| 亚洲精品中文字幕无限乱码| 欧美日本道一区二区三区| 国产午夜福利在线观看精品| 日本一级特黄大片国产| 好吊妞在线免费观看视频| 国产精品成人免费精品自在线观看| 熟女免费视频一区二区| 少妇被粗大进猛进出处故事| 日本人妻熟女一区二区三区 | 欧美一区二区三区五月婷婷| 少妇人妻一级片一区二区三区| 国产免费观看一区二区| 十八禁日本一区二区三区| 九九热视频免费在线视频| 偷自拍亚洲欧美一区二页| 粗暴蹂躏中文一区二区三区| 国产一区二区三区免费福利 | 麻豆亚州无矿码专区视频| 都市激情小说在线一区二区三区| 人妻久久一区二区三区精品99| 国产精品涩涩成人一区二区三区| 好吊色免费在线观看视频| 美日韩一区二区精品系列| 中文字幕免费观看亚洲视频|