MFC定时器SetTimer函数用法总结
? ? ? CWnd類的SetTimer成員函數只能在CWnd類或其派生類中調用,而API函數SetTimer則沒有這個限制,這是一個很重要的區別。
1、啟動定時器。
?????? 啟動定時器就需要使用CWnd類的成員函數SetTimer。CWnd::SetTimer的原型如下:
??????
參數nIDEvent指定一個非零的定時器ID;
參數nElapse指定間隔時間,單位為毫秒;
參數lpfnTimer指定一個回調函數的地址,如果該參數為NULL,則WM_TIMER消息被發送到應用程序的消息隊列,并被CWnd對象處理。如果此函數成功則返回一個新的定時器的ID,我們可以使用此ID通過KillTimer成員函數來銷毀該定時器,如果函數失敗則返回0。
?????? 通過SetTimer成員函數我們可以看出,處理定時事件可以有兩種方式,一種是通過WM_TIMER消息的消息響應函數,一種是通過回調函數。
?????? 如果要啟動多個定時器就多次調用SetTimer成員函數。另外,在不同的CWnd中可以有ID相同的定時器,并不沖突。
2、為WM_TIMER消息添加消息處理函數,或者定義回調函數。
????? 如果調用CWnd::SetTimer函數時最后一個參數為NULL,則通過WM_TIMER的消息處理函數來處理定時事件。添加WM_TIMER消息的處理函數的方法是,在VS2010工程的類向導,選擇要添加定時器的類,在消息列表中找到WM_TIMER消息,添加消息處理函數。添加后,cpp文件中會出現類似如下內容:
C++代碼
BEGIN_MESSAGE_MAP(CExample44Dlg,CDialogEx)???
??? ......???
??? ON_WM_TIMER()???
END_MESSAGE_MAP()???
??
voidCExample44Dlg::OnTimer(UINT_PTR nIDEvent)???
{???
??? // TODO: Add your message handler code hereand/or call default???
??
??? CDialogEx::OnTimer(nIDEvent);???
}?
?????? 之后就可以在OnTimer函數中進行相應的處理了。OnTimer的參數nIDEvent為定時器ID,即在SetTimer成員函數中指定的定時器ID,如果有多個定時器,我們可以像下面這樣處理:
C++代碼
voidCExample44Dlg::OnTimer(UINT_PTR nIDEvent)??????
{// TODO: Add your message handler code here and/or call default??????
??? switch (nIDEvent)??????
{??????
case 1:??????
??????? //在這添加執行定時器1的任務;??????
??????? break;??????
??? ?case2:??????
?????? //在這添加執行定時器2的任務;?
?????? ?break;?????
??? ......??????
??? default:??????
??????? break;??????
??? }??????
??CDialogEx::OnTimer(nIDEvent);??????
}????
?
?????? 如果調用CWnd::SetTimer函數時最后一個參數不為NULL,則需要定義回調函數。回調函數的形式如下:
C++代碼
?????? 參數hWnd為調用SetTimer成員函數的CWnd對象的句柄,即擁有此定時器的窗口的句柄;參數nMsg為WM_TIMER,而且總是為WM_TIMER;參數nIDEvent為定時器ID;參數dwTime為系統啟動以來的毫秒數,即GetTickCount函數的返回值。
?????? 這樣CWnd::SetTimer函數最后一個參數就可以為TimerProc。
?????? 注意:回調函數的名稱不一定為TimerProc,可以取其他名字,但返回值類型、參數的類型和個數不能改變。
?????? 回調函數的例子:
C++代碼
VOIDCALLBACK TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime)??????
{??????
?? switch(nTimerid)??????
?? {??????
?? case 1:???????
??????? ?// 處理ID為1的定時器的事件???????
???????? break;??????
?? case 2:???????
???????? // 處理ID為2的定時器的事件??????
???????? break;????
?? ......???
?? default:???
??????? break;?????
?? }??????
}????
?
?????? 回調函數為全局函數,需要寫在使用它的位置的前面,或者寫在后面然后在使用之前聲明。
3、銷毀定時器。
???? ??不再使用定時器時,可以銷毀它。銷毀定時器需使用CWnd類的KillTimer成員函數,CWnd::KillTimer函數的原型如下:
C++代碼
BOOLKillTimer(UINT_PTR nIDEvent);?
?
?????? 參數nIDEvent為要銷毀的定時器的ID,是調用CWnd::SetTimer函數時設置的定時器ID。如果定時器被銷毀則返回TRUE,而如果沒有找到指定的定時器則返回FALSE。
?????? 如果要銷毀多個定時器,則多次調用KillTimer函數并分別傳入要銷毀的定時器的ID。
4.MFC定時器經典例子
實現功能:單擊對話框中的“開始計數”按鈕,編輯框中數字每個1s時間遞增顯示。
如下圖:
制作步驟:
1.??在VS2010中新建一個項目,命名為“Timer”,選擇MFC向導建立基于對話框;
2.??在自動生成的對話框模板中,刪除所有靜態文本控件和按鈕控件。添加一個編輯框控件和一個按鈕控件,使用默認的IDC_EDIT1和IDC_BUTTON1,編輯框的ReadOnly屬性設置True。
3.??在CTimerDlg類的類向導中,為編輯框IDC_EDIT1添加int類型成員變量m_CountTime和CEdit類型的m_Edit1對象。
①在CTimerDlg類TimerDlg.h頭文件中找到
int? m_CountTime;將它修改為
static? int?m_CountTime;//靜態整形成員變量;
②在CTimerDlg類TimerDlg.cpp源文件的構造函數中刪除:
m_CountTime=0;
③在CTimerDlg類TimerDlg.cpp源文件的頭文件下方添加:
int? CTimerDlg::m_CountTime=0;//在全局為靜態整形成員變量初始化;
int Num=0;//全局變量;
4.??在CTimerDlg類TimerDlg.cpp源文件中找到BOOLCTimerDlg::OnInitDialog()函數的// TODO: 在此添加額外的初始化代碼,在其下面添加:
注意:要調整好編輯框大小尺寸,以適應設置的文本字體大小;
5. 在CTimerDlg類TimerDlg.cpp源文件中添加SetTimer函數中使用的回調函數:
6. 雙擊“開始計時”按鈕,添加其消息處理函數:
7. 在VS2010工程的類向導,選擇CTimerDlg類,在消息列表中找到WM_CLOSE消息,為對話框右上角“關閉”按鈕添加消息處理函數:
8.總結:
① 在SetTimer函數的回調函數中,如果要使用類中的成員變量m_CountTime,則不僅需要把m_CountTime修改成靜態成員變量,而且還要在全局對m_CountTime初始化賦值。但是這樣雖然編譯無錯誤,但是不能實現每隔1s時間m_CountTime值自加。
②在全局定義了int Num=0;變量,在“開始計時”按鈕的消息處理函數中,將Num賦給m_CountTime,再將m_CountTime值顯示在編輯框中。在SetTimer函數的回調函數中讓Num自加的目的實現。
__________________________________________________________________________________________________________________________________________________________
附頁:
通過Windows API函數使用定時器
?????? 1、啟動定時器。
?????? 使用API函數SetTimer啟動定時器,SetTimer函數的原型如下:
C++代碼
UINT_PTRSetTimer(?????????
??? HWND????
??????????? hWnd,???
??? UINT_PTR????
??????????? nIDEvent,???
??? UINT????
??????????? uElapse,???
??? TIMERPROC????
??????????? lpTimerFunc???
);?
?
?????? 參數hWnd為與定時器關聯的窗口的句柄;參數nIDEvent為非零的定時器ID,如果hWnd等于NULL,且還不存在ID為nIDEvent的定時器,那么nIDEvent參數被忽略,然后生成一個新ID的定時器,而如果hWnd不為NULL,且hWnd指定的窗口已存在ID為nIDEvent的定時器,那么這個已存在的定時器被新定時器所取代。參數uElapse和lpTimerFunc同CWnd::SetTimer函數。
?????? 2、為WM_TIMER消息添加消息處理函數,或者定義回調函數。
?????? 如果調用SetTimer函數時最后一個參數為NULL,我們需要自己為WM_TIMER消息添加處理函數,要注意的是,WM_TIMER消息的附加數據wParam為定時器ID,lParam為回調函數的指針,如果調用SetTimer時回調函數為NULL,那么lParam也為NULL。
?????? 而如果調用SetTimer函數時最后一個參數不為NULL,我們就需要定義回調函數。回調函數的定義同MFC定時器。
?????? 3、銷毀定時器。
?????? 銷毀定時器使用KillTimer API函數,原型如下:
C++代碼
BOOLKillTimer(HWND hWnd,UINT_PTR uIDEvent); ??
?????? 參數hWnd為與定時器關聯的窗口的句柄,與啟動定時器時SetTimer函數的hWnd參數值相同;參數uIDEvent為要銷毀的定時器的ID,如果傳遞給SetTimer的參數hWnd有效,則uIDEvent應與傳遞給SetTimer的參數nIDEvent相同,而如果SetTimer的參數hWnd為NULL,則uIDEvent應為SetTimer返回的定時器ID。該函數成功則返回TRUE,否則返回FALSE。
總結
以上是生活随笔為你收集整理的MFC定时器SetTimer函数用法总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DM860步进电机接线及拨码
- 下一篇: 怎么提高Origin烂橘子的下载速度