MFC Timer範例 (SetTimer, KillTimer, OnTimer)

 

幾乎所有一定規模的程式裡, 都會使用定時器(Timer)這個令人愛不釋手的功能,

可能是倒數計時器, Socket定時心跳包, 定時偵測裝置狀態, 也可能是UI介面定時更新,

電腦程式靠著定時器不眠不休地, 忠誠地完成一次次任務,

 

在VC++裡面, 知道下面這三個MFC函數就可以玩得非常開心了

 

必要函數:

1. 設定(啟動)計時器

UINT_PTR WINAPI SetTimer(
  _In_opt_ HWND      hWnd,
  _In_     UINT_PTR  nIDEvent,
  _In_     UINT      uElapse,
  _In_opt_ TIMERPROC lpTimerFunc
);
 

hWnd:視窗的句柄(handle), 也就是要執行Timer的視窗位址(Address),

                在CWnd函數中可以由this->GetSafeHwnd()獲得

nIDEvent:計時器的編號, 視窗可以設定多個計時器, 用編號區分以便同時執行

uElapse:計時器每個多久觸發一次10ms~2147483647ms

lpTimerFunc:計時器每次觸發呼叫的函數, 基本用法設定成NULL,

                  呼叫OnTimer(=WM_TIMER)這個函數即可

 

2. 停止計時器

BOOL WINAPI KillTimer(
  _In_opt_ HWND     hWnd,
  _In_     UINT_PTR uIDEvent
);
 

hWnd:視窗的句柄(handle), 也就是要執行Timer的視窗位址(Address),

                在CWnd函數中可以由this->GetSafeHwnd()獲得

nIDEvent:計時器的編號, 傳入要停止的計時器編號

 

3. 計時器回調(Callback)函數, 也就是隔一段時間, 計時器要做事的函數,

afx_msg void OnTimer( 
   UINT_PTR nIDEvent  
);
 

nIDEvent:計時器的編號, 每隔一段時間被呼叫, 系統會透過這編號,

                    告訴我們現在是呼叫哪個計時器

 

函數定義大致看就好, 等到玩熟悉OnTimer了再回頭看, 會更清楚,

無論寫作業還是職場理論研究說了太多沒幫助, copy範例自己玩最快,

 

範例 - Timer倒數計時器(vs2010):

 

初始介面:

1

 

倒數結束:

2

 

程式碼:

1. TimerTest.h

public:
afx_msg void OnBnClickedBtnCntdown();//開始倒數按鈕
afx_msg void OnBnClickedBtnStop();//停止倒數按鈕
afx_msg void OnTimer(UINT_PTR nIDEvent);//計時器函數

 

2. TimerTest.cpp

MFC消息傳遞都要加在這個映射表裡才有用

BEGIN_MESSAGE_MAP(CTimerTestDlg, CDialogEx)
    ON_BN_CLICKED(IDC_BTN_CNTDOWN, &CTimerTestDlg::OnBnClickedBtnCntdown)
    ON_BN_CLICKED(IDC_BTN_STOP, &CTimerTestDlg::OnBnClickedBtnStop)
    ON_WM_TIMER()
END_MESSAGE_MAP()

 

//按鈕函數CountDown:開始倒數
void CTimerTestDlg::OnBnClickedBtnCntdown()
{
    //把Edit內的數值抓出來轉稱int
    CString strVal;
    ((CEdit*)GetDlgItem(IDC_ED_VAL))->GetWindowText(strVal);
    m_valInput = _ttoi(strVal);//CStrting 轉 int

    SetTimer(0,1000,NULL);//啟動計時器編號0每一秒觸發一次
}

 

//按鈕函數Stop:停止倒數
void CTimerTestDlg::OnBnClickedBtnStop()
{
    KillTimer(0);//停止編號0計時器
    ((CEdit*)GetDlgItem(IDC_ED_VAL))->SetWindowText(_T("10"));//設回10秒
}

 

//計時器函數OnTimer:計時器功能實現區域
void CTimerTestDlg::OnTimer(UINT_PTR nIDEvent)
{
    if(nIDEvent == 0)
    {
        m_valInput = m_valInput - 1;//每一秒數值減1

        //讓新的數值顯是在Edit
        CString strVal;
        strVal.Format(_T("%d"),m_valInput);
        ((CEdit*)GetDlgItem(IDC_ED_VAL))->SetWindowText(strVal);

        if(m_valInput == 0) 
        {
            AfxMessageBox(_T("時間到0秒啦!停止計時器!"));
            KillTimer(0);//停止編號0計時器
        }
    }

    CDialogEx::OnTimer(nIDEvent);
}

 

原始碼下載:Timer倒數計時器(vs2010)

 

重點說明:

基本上只要把上面的程式碼加入你的VC++視窗程式裡, OnTimer就會動了,

但是我們擁有vs2010這種開發工具, 應該用更快更安全的方法可以加入Timer,

 

1. 資源列表找到你要放入計時器的視窗TimerTest

3

 

2. 主視窗->右鍵->類別精靈(Class Wizard)

4

 

3. 訊息->WM_TIMER消息->點兩下加到右側

5

 

4. OnTimer出現在右邊"現有的處理常式"

6

 

5. 回到程式碼, VS2010已經幫你在該加入的地方加入Timer相關宣告了

TimerTest.h

 8  

TimerTest.cpp

 9

7

 

資訊癮想力 | 輕鬆寫程式 | Edward

arrow
arrow
    創作者介紹
    創作者 NoSleep 的頭像
    NoSleep

    NoSleep | 資訊癮想力

    NoSleep 發表在 痞客邦 留言(0) 人氣()