首页 > 代码库 > 定时器非多线程

定时器非多线程




本文由 代码助手软件 整理发布 内容与本软件无关 更惬意的读、更舒心的写、更轻松的发布









首先,要说明的是:定时器使用感觉像是一个线程,但其实并不是多线程。

他是通过消息触发实现的,通过SetTimer函数设定定时器后,在规定的时间内向消息队列中加入WM_TIMER来触发事件,并且只有该消息返回后才处理下个消息。

定时器是系统消息,如同左键按下消息一样,所以需要添加此定时器消息

ON_WM_TIMER()

    afx_msg void OnTimer(UINT nIDEvent);

void CView::OnTimer(UINT nIDEvent)
{
    CScrollView::OnTimer(nIDEvent);
}

加入定时器消息后,要想触发定时器,你总要告诉机器多久触发一次吧,所以要设置定时时间SetTimer

设置后,就告诉了机器,自此时,要隔某段时间触发一次定时器消息。

SetTimer(m_nID,60,NULL); //60MS m_nID为定时器事件ID

当时间满足时,变会触发定时器消息,因此在定时器消息函数中处理事件

void CMainFrame::OnTimer(UINT nIDEvent)
{
  // TODO: 在此添加消息处理程序代码和/或调用默认值
  if(nIDEvent == m_ nID)
  {
  }
  CFrameWnd::OnTimer(nIDEvent);
}

当解决问题后,不想再使用定时器时,需要将其关闭

KillTimer(m_nID);

错误使用:

    SetTimer (1,300,NULL);
    m_nNum=0;
    while(1)
    {
        if (m_nNum>20)
        {
            break;
        }
    }
    KillTimer (1);

在定时器事件中 将m_nNum不断增加,可是调试时发现,定时器事件一直不触发。

所以,由此看出定时器不是线程。

修改为:

void CRichEditDlg::OnSelectGroup ()
{
    CString currentDirectory;
    currentDirectory=theApp.exeDirectory+L"\\res\\音效\\声音\\";
    currentDirectory+=L"gu.wav";
    PlaySound(currentDirectory, NULL, SND_ASYNC | SND_FILENAME |SND_LOOP);
    SetTimer (1,300,NULL);
    m_nNum=0;
}

void CRichEditDlg::OnTimer(UINT_PTR nIDEvent)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    if (nIDEvent==1)
    {
        m_pView->RandScoreChunk ();
        m_pView->Invalidate ();
        m_nNum++;
        if (m_nNum>20)
        {
            KillTimer (1);
            PlaySound(NULL, NULL, SND_ASYNC | SND_FILENAME );
        }
    }
    CDialogEx::OnTimer(nIDEvent);
}


定时器非多线程