高精確度且線程分離的定時器——多媒體定時器


說道定時器,很多人都會想到Windows定時器SetTimer吧!其實,項目里面原本確實是使用這種方法實現動畫效果的,但是后來問題出現了!由於WM_TIMER消息優先級比較低,常常被丟失,導致一個WM_MOUSEMOVE消息都會影響整個動畫的效果。

  這時我就考慮,是否能給定時器創建一個單獨的線程,接着就發現了“多媒體定時器”這個東西。它是一個高精確度定時器,一般的Windows定時器只能精確到55ms,而多媒體定時器能精確到10ms內。同時,在啟動一個多媒體定時器的同時,會自動創建一個線程,專門負責定時器控制。不僅如此,多媒體計時器具有較高的優先級(記得是15),因此能夠滿足實時控制的需求。但是這也為它帶來了不利的因素,同時對於定時器響應函數的內容也有一些限制,具體情況有時間再詳細說明下!

為了學會使用它,我研究了很多相關資料,其中經典的算《C++builder 深度歷險》這本書了。嘿嘿~ 閑暇的時間看了下C++builder,又收獲了一些其它知識。

  首先,簡要介紹下幾個重要的函數,具體說明見MSDN!

 1)MMRESULT timeGetDevCaps( LPTIMECAPS ptc, UINT cbtc );

   功能:獲得計時器所支持的解析度范圍。

 2)MMRESULT timeBeginPeriod( UINT uPeriod );

   功能:調整計時器的解析度,用在啟動計時器之前。

 3)MMRESULT timeEndPeriod( UINT uPeriod );

  功能:調整計時器的解析度,用在結束計時器之后。這兩個函數通常是成對出現。

 4)MMRESULT timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent );

  功能:設置並啟動一個計時器

 5)MMRESULT timeKillEvent( UINT uTimerID );

  功能:取消一個定時器

  好了!廢話不多少,直接跳到使用方法階段:

  1)設置並啟動定時器

1   if (timeBeginPeriod(5) == TIMERR_NOERROR )
2   {
3       m_uTimerID = timeSetEvent(30,5,TimeProc,(DWORD)GetSafeHwnd(),TIME_PERIODIC);
4   }

  2)取消定時器

1 timeKillEvent(m_uTimerID);
2 timeEndPeriod(5);

  3)定時器處理函數

1 void _stdcall TimeProc(UINT uTimerID,UINT uMessage,DWORD dwUser,DWORD dw1,DWORD dw2)
2 {
3     ::SendMessage((HWND)dwUser,UM_TIMER_PROC,0,0);
4 }

 Tip:  定時器處理函數一般定義為全局函數,而函數內部使用的方法也只能是全局變量或函數!

   最后,不要忘記加上以下頭文件和動態鏈接庫:

1 #pragma comment(lib,"Winmm.lib")
2 
3 #include <Mmsystem.h>

 


免責聲明!

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



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