Chinaunix首页 | 论坛 | 博客
  • 博客访问: 178040
  • 博文数量: 35
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 305
  • 用 户 组: 普通用户
  • 注册时间: 2016-02-01 12:35
个人简介

不断超越自己,将更强大!

文章分类

全部博文(35)

文章存档

2022年(1)

2017年(5)

2016年(29)

我的朋友

分类: C/C++

2016-03-22 22:28:26

       VC++默认的定时器,好像精度不大,秒内的不错,但是如果精确到毫秒(ms),不行,如果使用媒体定时器,multimedia timer,则效果显著,基本上精确到毫秒吧,一般的10ms之类的延时,应该可以保证了。
       如何使用呢?网上有例子,但没有完整的,大部分只是介绍,因此我根据网上的代码实现了一下,使用MFC实现,可以在下面的链接下载下来学习与研究。
       可能通过MSDN找到操作媒体定时器(multimedia timer)的相关介绍,主要的操作函数:
(1)timeSetEvent设置定时器(配置并开启)
(2)timeKillEvent关闭定时器
(3)CALLBACK TimerCallBack也可回调函数,(定时器中断了,要执行的函数),名字可以随便起,只是格式上,要符合标准的格式。
(4)OnMMTimer  具体的实现函数:网上是定义为虚函数,然后重写,这里我觉得随便取个名字应该可以,就是用定时器干什么,延时到了,用户要实现什么功能,可以写在这里。上面第三个函数就调用这个函数进行用户程序的实现。


(1)首先工程中要加入头文件:
#include "windows.h"
#include "Mmsystem.h"
(2)设置工程选项:加入Winmm.lib 库,这是使用媒体定时器的库。


界面如下:
 






对话框类的成员函数与成员变量:
public:
UINT m_ms;//毫秒,注意在构造函数里初始化为0
UINT m_timerId;
UINT m_s;
UINT m_m;
UINT m_h;
virtual void OnMMTimer();//声明要回调的成员方法
void TimerCtrl(const bool bEn);//定时器打开与关闭
int i;
MMRESULT TimerID;//媒体定时器的ID,标识



点击(此处)折叠或打开

  1. void CTimeSetEvent_V1Dlg::OnBtnTimerStart()
  2. {
  3.         // TODO: Add your control notification handler code here
  4.         TimerCtrl(TRUE);
  5.         GetDlgItem(IDC_BTN_TIMER_START)->EnableWindow(FALSE);
  6.         GetDlgItem(IDC_BTN_TIMER_STOP)->EnableWindow(TRUE);
  7. }

  8. void CTimeSetEvent_V1Dlg::OnBtnTimerStop()
  9. {
  10.         // TODO: Add your control notification handler code here
  11.         TimerCtrl(FALSE);
  12.         GetDlgItem(IDC_BTN_TIMER_START)->EnableWindow(TRUE);
  13.         GetDlgItem(IDC_BTN_TIMER_STOP)->EnableWindow(FALSE);
  14. }

  15. void CTimeSetEvent_V1Dlg::OnMMTimer()
  16. {
  17.         CString str = "";
  18.         m_ms++;
  19.         str.Format("%ld",m_ms);
  20.         str+="";
  21.         SetDlgItemTextA(IDC_STATIC_MS,str);
  22.         CEdit *pEt = (CEdit *)GetDlgItem(IDC_EDIT_HIST);
  23.         int nLen=pEt->GetWindowTextLength();
  24.         pEt->SetSel(nLen,nLen);
  25.         pEt->ReplaceSel(str);
  26.         //GetDlgItem(IDC_EDIT_HIST)->
  27. }

  28. void CTimeSetEvent_V1Dlg::TimerCtrl(const bool bEn)
  29. {
  30.         if (bEn)
  31.         {
  32.                 m_h = m_m = m_s = 0;
  33.                 m_timerId = timeSetEvent(1,1,&TimerCallBack,(DWORD)this,TIME_PERIODIC);
  34.         }
  35.         else
  36.       timeKillEvent(m_timerId);
  37. }

  38. void CTimeSetEvent_V1Dlg::OnOK()
  39. {
  40.         // TODO: Add extra validation here
  41.         GetDlgItem(IDC_EDIT_HIST)->SetWindowText("");
  42.         m_ms=0;
  43.         //CDialog::OnOK();
  44. }

  45. void CTimeSetEvent_V1Dlg::OnCancel()
  46. {
  47.         // TODO: Add extra cleanup here
  48.         
  49.         CDialog::OnCancel();
  50. }


点击(此处)折叠或打开

  1. static void CALLBACK TimerCallBack(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
  2. {
  3.         CTimeSetEvent_V1Dlg * pThis=(CTimeSetEvent_V1Dlg *)dwUser;//由this指针获得实例的指针
  4.         
  5.     pThis->OnMMTimer(); //调用要回调的成员方法
  6. }

  7. /////////////////////////////////////////////////////////////////////////////
  8. // CTimeSetEvent_V1Dlg dialog

  9. CTimeSetEvent_V1Dlg::CTimeSetEvent_V1Dlg(CWnd* pParent /*=NULL*/)
  10.         : CDialog(CTimeSetEvent_V1Dlg::IDD, pParent)
  11. {
  12.         //{{AFX_DATA_INIT(CTimeSetEvent_V1Dlg)
  13.                 // NOTE: the ClassWizard will add member initialization here
  14.         //}}AFX_DATA_INIT
  15.         // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  16.         m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  17.         m_ms=0;
  18.         m_s=0;
  19.         m_m=0;
  20.         m_h=0;
  21. }

以上为主要的函数实现功能。
目前只是打印出数字来,证明定时器中断可以用,当然,如果设置什么数据发送,如1S中发送100次或是200次,也可以加入。


VC6工程下载:TimeSetEvent_V1.zip

阅读(2329) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~