VC++中使用定时器的方法_第1页
VC++中使用定时器的方法_第2页
VC++中使用定时器的方法_第3页
VC++中使用定时器的方法_第4页
VC++中使用定时器的方法_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 启用一个定时器直接调用函数 SetTimer 1 500 NULL 定义时钟 1 时间间隔为 500ms SetTimer 2 1000 NULL 定义时钟 2 时间间隔为 1000ms 可以在按钮按下时启用定时器 void CTimeDlg OnButton1 TODO Add your control notification handler code here SetTimer 1 500 NULL 定义时钟 1 时间间隔为 500ms SetTimer 2 1000 NULL 定义时钟 2 时间间隔为 1000ms 2 关闭定时器 可以在按钮中调用如下函数关闭某定时器 void CTimeDlg OnButton2 TODO Add your control notification handler code here KillTimer 1 关闭 1 号定时器 KillTimer 2 关闭 2 号定时器 3 添加定时器时间到的处理代码 1 在开发界面中 Ctrl W 进入 MFCclass wizard 页面 2 选择 Message Maps 选项卡 3 在 Project 中选择你的工程 4 在 object Ids 中选择 C Dlg 5 在 Messages 中选择 WM TIMER 此时 Member functions 中自动定位到 W OnTimer ON WM TIMER 6 单击 EDIT code 或双击 W OnTimer ON WM TIMER 自动进入如下函数 void CTimeDlg OnTimer UINT nIDEvent TODO Add your message handler code here and or call default switch nIDEvent case 1 1 号定时器应该处理的事情 break case 2 2 号定时器应该处理的事情 break CDialog OnTimer nIDEvent 此句 VC 自动生成 秘密 在 VC 中 定时有三种方法 一是利用 WM TIMER 消息的 API 函数 二是使用多媒体定时器 三是多线程定时器 不知 道是不是可以这样分啊 1 WM TIMER SetTimer 函数是用来设立一个定时器 SetTimer 函数的原型如下 UINT PTR SetTimer HWND hWnd 窗口句柄 UINT PTR nIDEvent 定时器 ID UINT uElapse 时间间隔 单位为毫秒 TIMERPROC lpTimerFunc 回调函数 第一个参数是窗口句柄 在 MFC 中 SetTimer 函数被封装在 CWnd 类中 调用时不用指出窗口句柄 第二个参数是定时器 ID 在启用多个定时器时 用来标识各个不同的定时器 在不使用 MFC 的情况下 当接收到 WM TIMER 消息时 WPARAM wParam 就是这个 ID API 的东西 都忘得差不多了 第三个参数为时间间隔 也就是回调函数的调用周期 单位是毫秒 第四个参数是回调函数 当设为 NULL 时 调用系统默认的回调函数 这个默认的回调函数是 OnTimer 可以在需要定 时器的类中添加 添加时只要在 ClassWizard 里添加 WM TIMER 的消息映射就可以了 函数的返回值为定时器 ID 这个函数的使用有点像定时器中断 SetTimer 就是开中断 回调函数就是中断子程 既然有开中断就一定要有关中断 在 VC 里面用 KillTimer 来取消定时器 KillTimer 函数的原型如下 BOOL KillTimer HWND hWnd 窗口句柄 UINT PTR uIDEvent ID 与 SetTimer 一样 当在 MFC 中使用时 不用指定窗口句柄 正确取消定时器则返回 true 否则返回 false 前面说到 SetTimer 第四个参数为回调函数 不设为 NULL 时 它就是一个回调函数的地址 回调函数格式如下 void CALLBACK TimerProc HWND hWnd UINT nMsg UINT nTimerid DWORD dwTime 第一个参数是窗口句柄 第二个是消息 第三个是定时器 ID 必须与 SetTimer 中的一致 最后一个是回调函数中要 使用的参数 例 SetTimer 1 1000 NULL SetTimer 2 2000 NULL 这样产生了两个定时器 我们在 OnTimer 函数中对两个不同的定时器作不同的处理 void C OnTimer UINT nIDEvent switch nIDEvent case 1 Timer1Proc break case 2 Timer2Proc break 当使用回调函数时 上面 SetTimer 函数第三个参数不用 NULL nTimerid 用来判断是哪个定时器 void CALLBACK TimerProc HWND hWnd UINT nMsg UINT nTimerid DWORD dwTime switch nTimerid case 1 处理 ID 为 1 的定时器 Timer1Proc break case 2 处理 ID 为 2 的定时器 Timer2Proc break 最后不要忘了取消掉定时器 KillTimer 1 KillTimer 2 2 多媒体定时器 前面提到的通过 SetTimer 来设置定时器的方法 操作起来很简单 但是精度不高 只能用于精度要求不高的场合 在精度要求稍高的场合中 可以用多媒体定时器 多媒体定时器有两种使用方法 1 timeGetTime 函数 定时精度为 ms 级 返回从 Windows 启动开始所经过的时间 该函数是通过查询的方式来进行 定时的 因此在程序中 必须建立一个循环来不断地查询以便进行定时 所以这个函数通常都在循环 do while 或者 for 循环 中 2 timeSetEvent 函数 原型如下 MMRESULT timeSetEvent UINT uDelay UINT uResolution LPTIMECALLBACK lpTimeProc DWORD dwUser UINT fuEvent 第一个参数 uDelay 延迟时间 也就是多久调用一定回调函数 单位为毫秒 第二个参数 uResolution 时间精度 单位为毫秒 缺省时为 1ms 第三个参数 lpTimeProc 回调函数 第四个参数参数 dwUser 用户提供的回调数据 第五个参数 fuEvent 定时器的事件类型 可以有两种取值 TIME ONESHOT 表示执行一次 TIME PERIODIC 表示周期 性执行 调用周期为 uDelay 回调函数格式为 void CALLBACK TimeProc UINT uID UINT uMsg DWORD dwUser DWORD dw1 DWORD dw2 参数 uID 是该多媒体定时器的标识 dwUser 必须与 timeSetEvent 中的 DwUser 一致 传递回调函数中需要使用的参数 回调函数必须声明为 PASCAL 全局函数 否则编译时会有问题 如 void PASCAL TimeProc UINT wTimerID UINT msg DWORD dwUser DWORD dwl DWORD dw2 成功后返回事件的标识符代码 否则返回 NULL timeSetEvent 函数的使用不像 SetTimer 那样简单 一般我们在使用之前 要先确认系统的分辨率的取值范围 无误 之后才开始使用 例 TIMECAPS tc 利用函数 timeGetDevCaps 取出系统分辨率的取值范围 如果无错则继续 if timeGetDevCaps 分辨率的值不能超出系统的取值范围 调用 timeBeginPeriod 函数设置定时器的分辨率 timeBeginPeriod wAccuracy 设置定时器 timeSetEvent nDelay wAccuracy lpTimeProc dwUser TIME PERIODIC 在精度要求较高的情况下 如要求定时误差不大于 1ms 时 可以利用 GetTickCount 函数 它返回自计算机启动后的 时间 返回值是 DWORD 型 单位为毫秒 通过两次调用 GetTickCount 函数 然后控制它们的差值来取得定时效果 GetTickCount 函数不带参数 与前面提到的 timeGetTime 类似的 必须有定时查询 前面多次提到查询这个词 下面就举个例子来说明怎么来实现吧 下面的一小段程序实现的是一个 50ms 的定时 DWORD dwStart dwStop dwStop GetTickCount while TRUE 上一次的中止值变成新的起始值 开始新一次的定时 dwStart dwStop 这里可以添加处理程序 do dwStop GetTickCount 查询时间 while dwStop 50 dwStart 50ms 到则退出循环 最后说一下注意事项 1 任务处理的时间不能大于周期间隔时间 2 在定时器使用完毕后 应及时调用 timeKillEvent 将其释放 3 多媒体定时器执行后会启动额外的线程 线程这东西一直都没弄明白过 4 由于多媒体定时器是另启动线程处理定时操作 所以在 回调函数中只能访问本线程的 MFC 对象 不能调用任何 系统函数 除了 PostMessage timeGetSystemTime timeGetTime timeSetEvent timeKillEvent midiOutShortMsg midiOutLongMsg OutputDebugString 等 5 使用多媒体定时器时 必须在工程里包含 winmm lib 用前面的两种方法取得的定时效果在许多场合已经满足实际的要求 但它们的精度只有毫秒级的 这样在要求定时时 间间隔小时 实际定时误差就很大 比如说定时 1ms 在使用多媒体定时器时 由于它还要启动额外的线程 这一部 分的开销相比 1ms 来说还是相当可观的 对于精确度要求更高的定时操作 则应该使用 QueryPerformanceFrequency 和 QueryPerformanceCounter 函数 这两 个函数是 Visual C 提供并且只能在 Windows 95 及其后续版本中使用 其精度与 CPU 的时钟频率有关 它们要求计 算机从硬件上支持精确定时器 QueryPerformanceFrequency 函数和 QueryPerformanceCounter 函数的原型如下 BOOL QueryPerformanceFrequency LARGE INTEGER lpFrequency BOOL QueryPerformanceCounter LARGE INTEGER lpCount 上述两个函数的参数的数据类型 LARGE INTEGER 既可以是一个 8 字节长的整型数 也可以是两个 4 字节长的整型数的 联合结构 其具体用法根据编译器是否支持 64 位而定 该类型的定义如下 typedef union LARGE INTEGER struct DWORD LowPart 4 字节整型数 LONG HighPart 4 字节整型数 LONG QuadPart 8 字节整型数 LARGE INTEGER 使用 QueryPerformanceFrequency 和 QueryPerformanceCounter 函数进行精确定时的步骤如下 1 调用 QueryPerformanceFrequency 函数取得高精度运行计数器的频率 f 单位是 Hz 此数一般很大 我在我的 电脑测试了一下 是 3579545 呵呵 2 在需要定时的代码的两端分别调用 QueryPerformanceCounter 函数以取得高精度运行计数器的数值 n1 n2 两 次数值的差值通过 f 换算成时间间隔 t n2 n1 f 当 t 大于或等于定时时间长度时 启动定时器 到现在也没有说到多线程的问题 其实这个方法还是前面说到的查询的方法 只不够使用的查询工具不同罢了 之所 以把它单列出来 因为它的精度最高的 哈哈哈 至于多线程呢 其实和这两个函数关系也不是那么大 在程序中另外启动一个线程就成了 要实现多线程 一般用 AfxBeginThread 函数 这个函数的原型为 CWinThread AfxBeginThread AFX THREADPROC pfnThreadProc 线程函数地址 LPVOID pParam 线程参数 int nPriority THREAD PRIORITY NO

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论