VC高精度定時



一、VC實現高精度定時器__基本流程
  1、頭文件包含        #include <MMSystem.h>
    
  2、類成員中添加變量    UINT   m_iTimerId; //定時器句柄   
    
  3、創建回調函數,響應定時器事件
    void   CALLBACK   CatchTimer
        ( UINT    IDEvent,
          UINT    uReserved,
          DWORD    dwUser,
          DWORD    dwReserved1,
          DWORD    dwReserved2)
    {  //在這里寫定時器事件的處理  }   
    
  4、開始啟動定時器
    //設置定時器分辨率,1ms   
    timeBeginPeriod(1);   

    //產生間隔100毫秒,周期執行的定時器事件;啟動定時器   
     m_iTimerId=timeSetEvent(1,100,CatchTimer,(DWORD)this->m_hWnd,TIME_PERIODIC);   
    
    
  5、結束使用定時器   
    //刪除定時器事件   
    if(m_iTimerId)   
    timeKillEvent(m_iTimerId);   
    //清除定時器分辨率   
    timeEndPeriod(1);   

設置兩個時鍾定時器,一個間隔是1毫秒,一個間隔是2秒,
每執行一次,輸出當前系統時鍾值到文件“cure.out”,以 比較此定時器的精確度。
(此程序在中文windows95及Microsoft VC5.0編譯通過。只節取與定時器有關的部分程序。)     

#include   <   stdio.h   >   
  //包含所用系統函數的頭文件,   
  如果編譯有問題,可調整此語句的位置   
  #include   <   mmsystem.h   >   
    
  //定義1毫秒和2秒時鍾間隔,以毫秒為單位   
  #define ONE_MILLI_SECOND1   
  #define TWO_SECOND 2000   
  //定義時鍾分辨率,以毫秒為單位   
  #define TIMER_ACCURACY1   
    
  UINT   wTimerRes_1ms,wTimerRes_2s;     //定義時間間隔   
  UINT   wAccuracy;//定義分辨率   
  UINT   TimerID_1ms,TimerID_2s;//定義定時器句柄   
    
  CCureApp::CCureApp()   
  :   fout("cure.out",   ios::out)//打開輸出文件“cure.out”   
  {   
  //   TODO:   add   construction   code   here,   
  //   Place   all   significant   
                initialization   in   InitInstance   
  //給時間間隔變量賦值   
  wTimerRes_1ms   =   ONE_MILLI_SECOND ;   
  wTimerRes_2s   =   TWO_SECOND;   
    
  TIMECAPS   tc;   
  //通過函數timeGetDevCaps取出系統   
  的分辨率取值范圍(對intel系統,   
  1~16毫秒),//如果無錯則繼續   
  if(timeGetDevCaps(&tc,   sizeof(TIMECAPS))   
  ==   TIMERR_NOERROR)   
  {   
  //分辨率的值不能超出系統的取值范圍   
  wAccuracy   =   min(max(tc.wPeriodMin,   
  TIMER_ACCURACY),tc.wPeriodMax);   
  //調用timeBeginPeriod函數設置定時器   
  的分辨率,類似於for循環的步長   
  timeBeginPeriod(wAccuracy);   
  //設置定時器   
  InitializeTimer();   
  }   
  }   
    
  CCureApp::~CCureApp()   
  {   
  //結束時鍾   
  fout   <   <     "結束時鍾"   <   <     endl;   
  //刪除兩個定時器   
  timeKillEvent(TimerID_1ms);   
  timeKillEvent(TimerID_2s);   
  //刪除設置的分辨率   
  timeEndPeriod(wAccuracy);   
  }   
  注:使用完的定時器及分辨率一定   
  要刪除,否則系統會越來越慢。   
    
  void CCureApp::InitializeTimer()   
  {   
  StartOneMilliSecondTimer();   
  StartTwoSecondTimer();   
  }   
    
  //一毫秒定時器的回調函數,   
  類似於中斷處理程序   
  voidPASCAL//一定要聲明為全局PASCAL函數,   
  否則編譯會有問題   
  OneMilliSecondProc(UINT wTimerID,   UINT   msg,   
  DWORD dwUser,   DWORD   dw1,   DWORD   dw2)   
  {   
  static int ms   =   0;//定義計數器   
  CCureApp *app   =   (CCureApp   *)dwUser;   
  //取得系統時間以毫秒為單位   
  DWORD   osBinaryTime   =   GetTickCount();   
  //輸出計數器值和當前系統時間到文件   
  app-   >fout   <   <     ++ms   <   <     ":   1ms   :   "   
    <   <     osBinaryTime   <   <     endl;   
  }   
    
  //加裝1毫秒定時器   
  void   CCureApp::StartOneMilliSecondTimer()   
  {   
  if((TimerID_1ms   =   timeSetEvent(wTimerRes_1ms,   wAccuracy,   
    (LPTIMECALLBACK)   OneMilliSecondProc,//回調函數   
    (DWORD)this,//用戶自傳送到回調函數的數據   
  /*周期調用,只使用一次用TIME_ONESHOT*/   
  TIME_PERIODIC))   ==   0)   
  {   
  AfxMessageBox("不能計時",   MB_OK   |   MB_ICONASTERISK);   
  }   
  else//不等於0表明加裝成功,   
  返回此定時器的句柄   
  fout   <   <     "16ms計時:"   <   <     endl;   
  }   
    
  以下為2秒定時器的回調函   
  數和加裝函數,與1毫秒的類似;   
  void   PASCAL   
  TwoSecondProc(UINT wTimerID,   UINT   msg,   
      DWORD dwUser,   DWORD   dw1,   DWORD   dw2)   
  {   
  static int s   =   0;   
  CCureApp *app   =   (CCureApp   *)dwUser;   
  DWORD   osBinaryTime   =   GetTickCount();   
  app-   >fout   <   <     "***********************   
  ***********************"   <   <     endl;   
  app-   >fout   <   <     ++s   <   <     ":   2s   :   "   
    <   <     osBinaryTime   <   <     endl;   
  }   
    
  void CCureApp::StartTwoSecondTimer()   
  {   
  if((TimerID_2s   =   timeSetEvent(wTimerRes_2s,   wAccuracy,   
    (LPTIMECALLBACK)   TwoSecondProc,   
    (DWORD)this,   
      TIME_PERIODIC))   ==   0)   
  {   
  AfxMessageBox("不能計時",   MB_OK   |   MB_ICONASTERISK);   
  }   
  else   
  fout   <   <     "2s計時:"   <   <     endl;   
  }     

timeSetEvent函數原型

 1 MMRESULT timeSetEvent( UINT uDelay,
 2                                  UINT uResolution,
 3                                  LPTIMECALLBACK lpTimeProc,
 4                                  WORD dwUser,
 5                                  UINT fuEvent )
 6 
 7         uDelay:以毫秒指定事件的周期。
 8          Uresolution:以毫秒指定延時的精度,數值越小定時器事件分辨率越高。缺省值為1ms。
 9          LpTimeProc:指向一個回調函數。
10          DwUser:存放用戶提供的回調數據。
11          FuEvent:指定定時器事件類型:
12          TIME_ONESHOT:uDelay毫秒后只產生一次事件
13          TIME_PERIODIC :每隔uDelay毫秒周期性地產生事件。

可以同時設置多個定時器:

 1 m_iTimerId = timeSetEvent(1000,1,CatchTimer,(DWORD)this->m_hWnd,TIME_PERIODIC);   
 2 
 3     m_iTimerId2 = timeSetEvent(5000,1,CatchTimer,(DWORD)this->m_hWnd,TIME_PERIODIC);   
 4 
 5     theApp.id1 = m_iTimerId;
 6     theApp.id2 = m_iTimerId2;
 7 
 8 
 9 void   CALLBACK   CatchTimer
10     ( UINT    IDEvent,
11     UINT    uReserved,
12     DWORD    dwUser,
13     DWORD    dwReserved1,
14     DWORD    dwReserved2) 
15 {
16     if (IDEvent == theApp.id1)
17     {
18         MessageBoxA(0,"A",0, 0);
19     } 
20     else
21     {
22         if (IDEvent == theApp.id2)
23         {
24             MessageBoxA(0,"B",0, 0);
25         }
26     }
27 
28     
29     static int n = 0;
30     n++;
31     CString str;
32     str.Format("%d", n);
33     theApp.pEdit->SetWindowText(str);
34 
35 }  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM