多媒体定时器使用方法是什么?



				
				
克利玛碴
48667 次浏览 2024-06-14 提问
97

最新回答 (5条回答)

2024-06-16 21:31:48 回答

我们知道  ,Windows  NT  和  Windows  98  都是抢先式的操作系统  ,  所以无论应用  程序在做什么工作  ,操作系统都能在多媒体定时器

2024-06-16 21:31:48 回答

一般的成品都会有产品说明书,只需要按照产品说明书上面的操作步骤进行操作就好了

2024-06-16 21:31:48 回答

一般来讲,为了缩减体积和减少冲突,多媒体定时器都是基于操作系统的时钟内核的,所以不同的系统精度确实会有差异,在UNIX下最好可以达到0.05ms,但x86架构的WINDOWS做得最好的也就是1ms(系统结构决定的,WINDOWS最小精度就是1ms,而unix可以无限小)。
希望我的回答对你有帮助。

2024-06-16 21:31:48 回答

您好,
Timer定时器是由应用程序响应定时消息WM_TIMER实现定时。Timer定时器是IBM  PC硬件和ROM  BIOS构造的定时器的简单扩充。PC的ROM初始化8253定时器来产生硬件中断08H,而08H中断的频率为18.2Hz,即至少每隔54.925  ms中断一次。此外,这个定时消息的优先权太低,只有在除WM_PAINT外的所有消息被处理完后,才能得到处理。多媒体定时器也是利用系统定时器工作的,但它的工作机理和普通定时器有所不同。首先,多媒体定时器可以按精度要求设置8253的T/C0通道的计数初值,使定时器不存在54.945ms的限制;其次,多媒体定时器不依赖于消息机制,而是用函数产生一个独立的线程,在一定的中断次数到达后,直接调用预先设置好的回调函数进行处理,不必等到应用程序的消息队列为空,从而切实保障了定时中断得到实时响应,使其定时精度可达1ms。(4)在TimerThread.h文件中定义宏,代码如下:#define  WM_THREADMSG  WM_USER+1(5)在TimerThread.h文件中定义数据结构,代码如下:typedef  struct  THREAD_PARAM{  HWND  hWnd;  int  nTime;  HANDLE  hTimerEvent;  HANDLE  hExitEvent;}_THREAD_PARAM;(6)在CWinThread类中添加成员变量,代码如下:public:  THREAD_PARAM*  m_pThreadParam;(7)在CTimerThread类中重载CWinThread::Run函数,代码如下://  TimerThread.cpp  int  CTimerThread::Run(){  while  (TRUE)  {  //等待定时事件  while  (WAIT_TIMEOUT  ==  WaitForSingleObject(m_pThreadParam->hTimerEvent,  200))  {  //等待退出事件  if  (WaitForSingleObject(m_pThreadParam->hExitEvent,  0)  ==  WAIT_OBJECT_0)  {  ::AfxEndThread(0);  }  }  m_pThreadParam->nTime  +=  100;  //向主线程窗口发送消息  ::PostMessage(m_pThreadParam->hWnd,  WM_THREADMSG,  0,  0);  //复位定时事件  ResetEvent(m_pThreadParam->hTimerEvent);  }}(8)在CDemoDlg类中添加成员变量,代码如下://  DemoDlg.cpp  private:  UINT  m_nTimerID;  CTimerThread*  m_pTimerThread;  THREAD_PARAM  m_ThreadParam;(9)在CDemoDlg类的构造函数和析构函数中添加如下代码://  DemoDlg.cpp  CDemoDlg::CDemoDlg(CWnd*  pParent  /*=NULL*/)  :  CDialog(CDemoDlg::IDD,  pParent){  //  …  m_nTimerID  =  0;  m_pTimerThread  =  NULL;  m_ThreadParam.nTime  =  0;  m_ThreadParam.hTimerEvent  =  CreateEvent(NULL,  TRUE,  FALSE,  NULL);  m_ThreadParam.hExitEvent  =  CreateEvent(NULL,  TRUE,  FALSE,  NULL);}CDemoDlg::~CDemoDlg(){  //取消定时器  if  (m_nTimerID  !=  0)  {  timeKillEvent(m_nTimerID);  }  //结束定时线程  if  (m_pTimerThread  !=  NULL)  {  //设置退出事件  SetEvent(m_ThreadParam.hExitEvent);  //等待定时线程结束  ::WaitForSingleObject(m_pTimerThread->m_hThread,  INFINITE);  delete  m_pTimerThread;  m_pTimerThread  =  NULL;  }  CloseHandle(m_ThreadParam.hTimerEvent);  CloseHandle(m_ThreadParam.hExitEvent);}(10)在CDemoDlg类中为重载CDialog::OnInitDialog函数,代码如下://  DemoDlg.cpp  BOOL  CDemoDlg::OnInitDialog(){  CDialog::OnInitDialog();  //  …  SetDlgItemInt(IDC_TIME,  0);  return  TRUE;}(11)在CDemoDlg类中为WM_THREADMSG添加消息处理函数,代码如下://  DemoDlg.cpp  BEGIN_MESSAGE_MAP(CDemoDlg,  CDialog)  //{{AFX_MSG_MAP(CDemoDlg)  //  …  ON_MESSAGE(WM_THREADMSG,  OnMsgFunc)  //}}AFX_MSG_MAPEND_MESSAGE_MAP()  LRESULT  CDemoDlg::OnMsgFunc(){  SetDlgItemInt(IDC_TIME,  m_ThreadParam.nTime);  return  1;}(12)在CDemoDlg类中为Button控件添加BN_CLICKED消息处理函数,代码如下://  DemoDlg.cpp  void  CDemoDlg::OnTest1(){  //取消定时器  if  (m_nTimerID  !=  0)  {  timeKillEvent(m_nTimerID);  }  //结束定时线程  if  (m_pTimerThread  !=  NULL)  {  //设置退出事件  SetEvent(m_ThreadParam.hExitEvent);  //等待定时线程结束  ::WaitForSingleObject(m_pTimerThread->m_hThread,  INFINITE);  delete  m_pTimerThread;  m_pTimerThread  =  NULL;  }  m_ThreadParam.hWnd  =  GetSafeHwnd();  m_ThreadParam.nTime  =  0;  SetDlgItemInt(IDC_TIME,  0);  TIMECAPS  tc;  //获得定时器分辨率  if  (timeGetDevCaps(&tc,  sizeof(TIMECAPS))  !=  TIMERR_NOERROR)  {  return;  }  UINT  nResolution  =  min(max(tc.wPeriodMin,  1),  tc.wPeriodMax);  UINT  nInterval  =  100;  if  (nInterval  <  nResolution)  {  nInterval  =  nResolution;  }  //设置定时最小分辨率  timeBeginPeriod(nResolution);  //设置定时器  m_nTimerID  =  timeSetEvent(nInterval,  nResolution,  (LPTIMECALLBACK)m_ThreadParam.hTimerEvent,  (DWORD)this,  TIME_PERIODIC  |  TIME_CALLBACK_EVENT_SET);  //创建定时线程  m_pTimerThread  =  (CTimerThread*)AfxBeginThread(RUNTIME_CLASS(CTimerThread),  THREAD_PRIORITY_ABOVE_NORMAL,  0,  CREATE_SUSPENDED);  m_pTimerThread->m_bAutoDelete  =  FALSE;  m_pTimerThread->m_pThreadParam  =  &m_ThreadParam;  m_pTimerThread->ResumeThread();}void  CDemoDlg::OnTest2(){  //取消定时器  if  (m_nTimerID  !=  0)  {  timeKillEvent(m_nTimerID);  }  //结束定时线程  if  (m_pTimerThread  !=  NULL)  {  //设置退出事件  SetEvent(m_ThreadParam.hExitEvent);  //等待定时线程结束  ::WaitForSingleObject(m_pTimerThread->m_hThread,  INFINITE);  delete  m_pTimerThread;  m_pTimerThread  =  NULL;  }}
希望我的答案对您有帮助,望采纳!

2024-06-16 21:31:48 回答

・  设定多媒体定时器的有关参数  例如,可用TimeGetDevCaps函数确定定时器服务提供的最大和最小事件周期,这一参数在不同的计算机上是不同的,但都可以得到用户想要设置的事件触发周期。可用TimeBeginPeriod和TimeEndPeriod函数为系统设置和消除最小时钟事件精度。由于精度越高,定时器消耗的系统资源就越多。因此,在具体的应用程序中,应根据需要综合考虑对精度的设置。  
・  启动多媒体定时器事件  可用TimeSetEvent初始化和启动时间事件,同时给出定时器回调函数的入口地址。其函数原型如下:  MMRESULTtimeSetEvent(UINTuDelay,UINTuResolution,  LPTIMECALLBACKlpTimeProc,  DWORDdwUser,UINTfuEvent);  其中,uDelay表示事件延迟,也就是定时触发的时间间隔;uResolution表示事件精度,其值越小,精度越高,但为了减轻系统的负担,应该选择适合于应用程序的最大值;LpTimeProc为定时触发的事件的回调函数的地址;dwUser为用户自定义的返回值;fu2Event为定时类型,可取TIME—ONESHOT、
TIME—PERIODIC、TIME—CALLBACK—FUNCTION、TI2ME—CALLBACK—EVENT—SET、
TIME—CALLBACK—EVENT—PULSE等值。其中,TIME—PERIODIC表示事  件每uDelay毫秒发生一次。  
・  在事件中展开各种应用  由上可知,lpTimeProc表示事件回调函数的入口地址,但具体的回调函数则需要我们自己编写。但要注意,由于此函数是WindowsAPI类型的函数,不能把它定义为某个具体类的成员。所以,当需要调用MFC类中某个具体的成员函数时,则需要先获取这个类的指针,然后才能引用这个类的成员。另外,如果要获得系统时间,可用函数TimeSetSystemTime。  
・删除定时器以释放系统资源  定时器是一种有限的全局资源,不能无休止的创建。在使用结束后要终止这个定时器,可用函数timeKillEvent来完成这个工作,其原型如下:  MMRESULTtimeKillEvent(UINTuTimerID);  其中uTimerID为由timeSetEvent返回的定时器标识号。

相关问题

页面运行时间: 0.084252119064331 秒