Windows定时器使用方法
来源:互联网 发布:ps软件启动不了 编辑:程序博客网 时间:2024/06/05 19:52
范围
本文只讨论MFC环境下使用定时器的例子,用纯Win32 SDK是类似的。
主要思想
定时器的属性:
- ID:每个定时器有个ID(UINT类型)。一个程序或窗体(如对话框)可以有多个定时器对象,每个定时器用ID区分。
- Elapse:定时器的超时时间,单位是ms。
- 回调函数(TimerProc):可以在SetTimer的时候直接指定定时器的回调函数。但在MFC方式下,使用WM_TIMER消息较为方便。
处理流程:
- 初始化定时器的ID和Elapse;
- SetTimer()创建定时器。之后,每隔Elapse的时间,都会触发WM_TIMER消息。
- WM_TIMER消息处理:在Elapse间隔时间到的时候,do something.
- KillTimer(): 当不再用定时器的时候,调用这个函数销毁定时器。
示例一(TimerTest)
一个简单的MFC对话框程序,两个按钮(Start&Stop),分别表示启动定时器和销毁定时器。每隔1秒钟更新一个整数值,并显示在UI上面。
成员变量
private: DWORD m_dwCount; UINT m_nTimerID; UINT m_nElapse;
消息处理函数的声明
public: afx_msg void OnBnClickedStart(); afx_msg void OnBnClickedStop(); afx_msg void OnTimer(UINT_PTR nIDEvent);
对话框资源
IDD_TIMERTEST_DIALOG DIALOGEX 0, 0, 233, 95STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAMEEXSTYLE WS_EX_APPWINDOWCAPTION "TimerTest"FONT 8, "MS Shell Dlg", 0, 0, 0x1BEGIN PUSHBUTTON "Start",IDC_START,32,24,78,18 PUSHBUTTON "Stop",IDC_STOP,140,23,71,17 EDITTEXT IDC_COUNT,34,62,174,19,ES_AUTOHSCROLLEND
Message Map
删除了其他自动生成的代码,仅关注定时器相关:
BEGIN_MESSAGE_MAP(CTimerTestDlg, CDialogEx) ON_BN_CLICKED(IDC_START, &CTimerTestDlg::OnBnClickedStart) ON_BN_CLICKED(IDC_STOP, &CTimerTestDlg::OnBnClickedStop) ON_WM_TIMER()END_MESSAGE_MAP()
DDX
void CTimerTestDlg::DoDataExchange(CDataExchange* pDX){ CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_COUNT, m_dwCount);}
初始化
BOOL CTimerTestDlg::OnInitDialog(){ CDialogEx::OnInitDialog(); // 自动生成的部分略过... // TODO: Add extra initialization here m_dwCount = 0; UpdateData(FALSE); m_nTimerID = 1; m_nElapse = 1000; GetDlgItem(IDC_START)->EnableWindow(TRUE); GetDlgItem(IDC_STOP)->EnableWindow(FALSE); return TRUE;}
按钮事件&定时器消息处理
因为这个示例只有一个定时器,所以在OnTimer()用了一个assert。通常情况下,不需要这么做,参见下一个示例。
void CTimerTestDlg::OnBnClickedStart(){ SetTimer(m_nTimerID, m_nElapse, NULL); GetDlgItem(IDC_START)->EnableWindow(FALSE); GetDlgItem(IDC_STOP)->EnableWindow(TRUE);}void CTimerTestDlg::OnBnClickedStop(){ KillTimer(m_nTimerID); GetDlgItem(IDC_START)->EnableWindow(TRUE); GetDlgItem(IDC_STOP)->EnableWindow(FALSE);}void CTimerTestDlg::OnTimer(UINT_PTR nIDEvent){ assert(nIDEvent == m_nTimerID); m_dwCount++; UpdateData(FALSE); const DWORD MAX_COUNT = 100; if (m_dwCount == MAX_COUNT) { OnBnClickedStop(); } CDialogEx::OnTimer(nIDEvent);}
示例二(TimerTest2)
上面的例子,用了一个定时器。现在用2个定时器,以说明多个定时器的处理情况。
直接在上面的例子基础上修改,上面是显示一个整数,现在显示两个,对应两个Edit控件,一个称为Fast,另一个为Slow。前者定时器时长是1s,后者是2s。
资源文件
IDD_TIMERTEST_DIALOG DIALOGEX 0, 0, 233, 101STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAMEEXSTYLE WS_EX_APPWINDOWCAPTION "TimerTest"FONT 8, "MS Shell Dlg", 0, 0, 0x1BEGIN PUSHBUTTON "Start",IDC_START,32,24,69,18 PUSHBUTTON "Stop",IDC_STOP,140,23,71,17 LTEXT "Fast",IDC_STATIC,30,52,63,13 EDITTEXT IDC_FAST,29,67,68,19,ES_AUTOHSCROLL LTEXT "Slow",IDC_STATIC,136,51,63,13 EDITTEXT IDC_SLOW,135,66,68,19,ES_AUTOHSCROLLEND
.h文件
public: afx_msg void OnBnClickedStart(); afx_msg void OnBnClickedStop(); afx_msg void OnTimer(UINT_PTR nIDEvent);private: DWORD m_dwFast; DWORD m_dwSlow; UINT m_nFastTimerID; UINT m_nSlowTimerID; UINT m_nElapse;
.cpp文件
static const UINT FAST_TIMER_ID = 1;static const UINT SLOW_TIMER_ID = 2;BEGIN_MESSAGE_MAP(CTimerTestDlg, CDialogEx) // some codes were delete ... ON_BN_CLICKED(IDC_START, &CTimerTestDlg::OnBnClickedStart) ON_BN_CLICKED(IDC_STOP, &CTimerTestDlg::OnBnClickedStop) ON_WM_TIMER()END_MESSAGE_MAP()BOOL CTimerTestDlg::OnInitDialog(){ CDialogEx::OnInitDialog(); // ... // TODO: Add extra initialization here m_dwFast = m_dwSlow = 0; UpdateData(FALSE); m_nFastTimerID = FAST_TIMER_ID; m_nSlowTimerID = SLOW_TIMER_ID; m_nElapse = 1000; GetDlgItem(IDC_START)->EnableWindow(TRUE); GetDlgItem(IDC_STOP)->EnableWindow(FALSE); return TRUE;}void CTimerTestDlg::OnBnClickedStart(){ SetTimer(m_nFastTimerID, m_nElapse, NULL); SetTimer(m_nSlowTimerID, m_nElapse * 2, NULL); GetDlgItem(IDC_START)->EnableWindow(FALSE); GetDlgItem(IDC_STOP)->EnableWindow(TRUE);}void CTimerTestDlg::OnBnClickedStop(){ KillTimer(m_nFastTimerID); KillTimer(m_nSlowTimerID); GetDlgItem(IDC_START)->EnableWindow(TRUE); GetDlgItem(IDC_STOP)->EnableWindow(FALSE);}void CTimerTestDlg::OnTimer(UINT_PTR nIDEvent){ switch (nIDEvent) { case FAST_TIMER_ID: m_dwFast++; break; case SLOW_TIMER_ID: m_dwSlow++; break; default: assert(false);//Unreachable branch } const DWORD MAX_COUNT = 100; if ((m_dwFast == MAX_COUNT) || (m_dwSlow == MAX_COUNT)) { OnBnClickedStop(); } UpdateData(FALSE); CDialogEx::OnTimer(nIDEvent);}
附件
附件是VS2010下的示例代码。
http://download.csdn.net/detail/u013344915/9417309
0 0
- Windows Timer定时器使用方法
- Windows定时器使用方法
- 定时器使用方法
- 定时器使用方法
- Windows程序设计(三)---定时器的三种使用方法
- windows定时器
- Windows定时器
- Windows定时器
- 定时器的使用方法
- VC++ WM_TIMER 定时器使用方法
- java的定时器使用方法
- VC++ WM_TIMER 定时器使用方法
- java的定时器使用方法
- java的定时器使用方法
- VC++ WM_TIMER 定时器使用方法
- VC++WM_TIMER 定时器使用方法
- C#多媒体定时器使用方法
- stm32的定时器使用方法
- 【转】使用Eclipse远程调试发布在Tomcat上的Web应用
- Funny In C++ 计算机基础
- 值得珍藏的书籍推荐(原)
- 【转】Release下报错,Debug下正常原因总结
- Visual Studio 2010离线安装MSDN Library[转]
- Windows定时器使用方法
- 【转】MyEclipse8优化设置
- java性能测试工具
- 【转】追加内容到文件末尾的几种常用方法
- 【转】是什么造就了伟大的程序员?
- Firefox上实现跨域访问
- 【转】是什么成就了一名“高级”程序员?
- 有关ListView优化机制及滑动时数据错乱问题的讨论
- 【转】JAVA下的多线程程序造成系统时钟变快