本帖最后由 VisualEleven 于 2013-01-11 10:47:09 编辑

解决方案 »

  1.   

    两点:
    1.OnTimer是否有用,程序中有没有SetTimer?如果程序没有SetTimer,则OnTimer不会被调用。
    2.TimeProc不要设置为对话框类的静态函数,应该设置为全局函数。把对话框类的this指针当作参数传递给TimeProc。
      

  2.   

    1我程序里另外一个编辑框用的就是SetTimer。
    2TimeProc不设置为对话框类的静态函数的话,程序就会出错。现在的错误只是a没有声明。我不知道怎么声明全局变量。
      

  3.   

    报什么错?报错就解决。我还想知道a是什么东西?你贴出的代码中可没有工。
    windows下定时器,参考Timers Tutorial
    代码如下:void CTimersDlg::OnButtonBegin()
    {
    .
    .
    .
        // Set resolution to the minimum supported by the system    TIMECAPS tc;
        timeGetDevCaps(&tc, sizeof(TIMECAPS));
        m_uResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);
        timeBeginPeriod(resolution);    // create the timer    m_idEvent = timeSetEvent(
            m_elTime,
            resolution,
            TimerFunction,
            (DWORD)this,
            TIME_PERIODIC);
    }void CTimersDlg::OnButtonStop()
    {
        // destroy the timer
        timeKillEvent(m_idEvent);    // reset the timer
        timeEndPeriod (m_uResolution);
    }void CTimersDlg::MMTimerHandler(UINT nIDEvent) // called every elTime milliseconds
    {
    // do what you want to do, but quickly
    .
    .
    .
    }void CALLBACK TimerFunction(UINT wTimerID, UINT msg,
        DWORD dwUser, DWORD dw1, DWORD dw2)
        {
        // This is used only to call MMTimerHandler    // Typically, this function is static member of CTimersDlg    CTimersDlg* obj = (CTimersDlg*) dwUser;
        obj->MMTimerHandler(wTimerID);
        }看到没?TimerFunction是回调函数,在其中再调用对话框的MMTimerHandler,而不是把对话框类的静态成员函数设置为回调。
      

  4.   

    在CPP文件中回调函数要在这个函数前面
    void CTimerSampleDlg::OnButtonstarttimer() 
    {
        TimerID = timeSetEvent(100,1,TimeProc,0,TIME_PERIODIC); 
    }
    否则就会出错.....
      

  5.   

    Quote: 引用 4 楼 BeanJoy 的回复:

    引用 2 楼 VCAlice 的回复:
    1我程序里另外一个编辑框用的就是SetTimer。
    2TimeProc不设置为对话框类的静态函数的话,程序就会出错。现在的错误只是a没有声明。我不知道怎么声明全局变量。
    报什么错?报错就解决。我还想知道a是什么东西?你贴出的代码中可没有工。报错如下 
    error C2664: 'timeSetEvent' : cannot convert parameter 3 from 'void.....
    另外一个就是m_Cal undeclared identifier。(没有a,上面的写错了)
      

  6.   


    写错了,没有a这个变量,只有m_Cal这个变量,想通过定时器在编辑框中显示一个不断增加的数字。
      

  7.   

    好好体会我5楼帖的代码,其中TimerFunction的定义放在OnButtonBegin前面。
      

  8.   

    “error C2664: 'timeSetEvent' : cannot convert parameter 3 from 'void.....”
    (LPTIMECALBACK)TimeProc
      

  9.   

    多媒体定时器不会在到达时间后给你发消息的
    你只能在一个类里建一个static函数或干脆就弄一个全局函数
    然后判断这一时刻和上一时刻的计时差
    比如:
    while(1)
    {
       if(presentTime - previousTime >100)
            yourFun();
    }
    精度太高了可是非常吃cpu的
      

  10.   


    void CALLBACK TimerFunction(UINT wTimerID, UINT msg,
        DWORD dwUser, DWORD dw1, DWORD dw2)
        {
        // This is used only to call MMTimerHandler
     
        // Typically, this function is static member of CTimersDlg
     
        CTimersDlg* obj = (CTimersDlg*) dwUser;
        obj->MMTimerHandler(wTimerID);
        
    }
    你没看代码吗?
    定时到了后,系统会自动调用TimerFunction,在这个函数中,可以得到对话框指针,然后调用对话框函数的MMTimerHandler。
      

  11.   

    程序这样写以后,居然可以运行了!
    1只是发现点击结束定时按钮再点开始定时按钮时多媒体计时器显示的那个编辑框里的数字跳变到一个和前面不连续的数字继续增加,是不是点结束按钮以后,仍在计时呢?
    2多媒体定时的那个编辑框的数字比SetTimer定时的那个编辑框里的数字要大,而且差距越拉越大。
    int a;void CMYDlg::OnTimer(UINT nIDEvent) 
    {
    // TODO: Add your message handler code here and/or call default
    m_Edit+=1;
    m_Cal=a;
    UpdateData(FALSE);
    CDialog::OnTimer(nIDEvent);
    }
    void CALLBACK CMYDlg::TimeProc(UINT uID,UINT uMsg,DWORD dwUser,DWORD dw1,DWORD dw2){
       a=a+1;}
      

  12.   

    我按照你的程序改写了以后,出错说m_uResolution ,resolution undeclared identifier
      

  13.   

     Header: Declared in mmsystem.h.
      Import Library: Use winmm.lib.MMRESULT timeSetEvent(
      UINT uDelay,                
      UINT uResolution,           
      LPTIMECALLBACK lpTimeProc,  
      DWORD dwUser,               
      UINT fuEvent                
    );
      

  14.   

    麻烦你可否把这个程序的完整代码发给我,我想看下我到底遗漏了什么东西,编译已经没有错了,但是运行时总是出现Dug Assertion Failed!
      

  15.   

    这很正常啊!
    你用了两个定时器,一个OnTimmer,一个timeSetEvent。两个定时器设置的间隔时间是否一样?即使一样,也是有误差的,并非数字都相同。
    另外,我还真想借用赵老师的话了,F5、F10、F11什么的。
      

  16.   

    报什么错?报错就解决。我还想知道a是什么东西?你贴出的代码中可没有工。
    windows下定时器,参考Timers Tutorial
    代码如下:void CTimersDlg::OnButtonBegin()
    {
    .
    .
    .
        // Set resolution to the minimum supported by the system    TIMECAPS tc;
        timeGetDevCaps(&tc, sizeof(TIMECAPS));
        m_uResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);
        timeBeginPeriod(resolution);    // create the timer    m_idEvent = timeSetEvent(
            m_elTime,
            resolution,
            TimerFunction,
            (DWORD)this,
            TIME_PERIODIC);
    }void CTimersDlg::OnButtonStop()
    {
        // destroy the timer
        timeKillEvent(m_idEvent);    // reset the timer
        timeEndPeriod (m_uResolution);
    }void CTimersDlg::MMTimerHandler(UINT nIDEvent) // called every elTime milliseconds
    {
    // do what you want to do, but quickly
    .
    .
    .
    }void CALLBACK TimerFunction(UINT wTimerID, UINT msg,
        DWORD dwUser, DWORD dw1, DWORD dw2)
        {
        // This is used only to call MMTimerHandler    // Typically, this function is static member of CTimersDlg    CTimersDlg* obj = (CTimersDlg*) dwUser;
        obj->MMTimerHandler(wTimerID);
        }看到没?TimerFunction是回调函数,在其中再调用对话框的MMTimerHandler,而不是把对话框类的静态成员函数设置为回调。
    回调函数里再调用对话框类的一个函数 和直接在回调函数里实现相应功能 有什么区别呢  比如说我想在对话框中显示一些东西 若直接在全局的回调函数里实现,则还需要传递对话框句柄什么的 现在用你这个方法是不是就不需要了呢?
      

  17.   

    报什么错?报错就解决。我还想知道a是什么东西?你贴出的代码中可没有工。
    windows下定时器,参考Timers Tutorial
    代码如下:void CTimersDlg::OnButtonBegin()
    {
    .
    .
    .
        // Set resolution to the minimum supported by the system    TIMECAPS tc;
        timeGetDevCaps(&tc, sizeof(TIMECAPS));
        m_uResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);
        timeBeginPeriod(resolution);    // create the timer    m_idEvent = timeSetEvent(
            m_elTime,
            resolution,
            TimerFunction,
            (DWORD)this,
            TIME_PERIODIC);
    }void CTimersDlg::OnButtonStop()
    {
        // destroy the timer
        timeKillEvent(m_idEvent);    // reset the timer
        timeEndPeriod (m_uResolution);
    }void CTimersDlg::MMTimerHandler(UINT nIDEvent) // called every elTime milliseconds
    {
    // do what you want to do, but quickly
    .
    .
    .
    }void CALLBACK TimerFunction(UINT wTimerID, UINT msg,
        DWORD dwUser, DWORD dw1, DWORD dw2)
        {
        // This is used only to call MMTimerHandler    // Typically, this function is static member of CTimersDlg    CTimersDlg* obj = (CTimersDlg*) dwUser;
        obj->MMTimerHandler(wTimerID);
        }看到没?TimerFunction是回调函数,在其中再调用对话框的MMTimerHandler,而不是把对话框类的静态成员函数设置为回调。
    回调函数里再调用对话框类的一个函数 和直接在回调函数里实现相应功能 有什么区别呢  比如说我想在对话框中显示一些东西 若直接在全局的回调函数里实现,则还需要传递对话框句柄什么的 现在用你这个方法是不是就不需要了呢?
    两者最大的区别在于,在对话框类的函数里,可以使用对话框类的成员变量,而在回调函数中,如果没有对话框类的指针,你是无法使用对话框类的成员变量。
      

  18.   

    报什么错?报错就解决。我还想知道a是什么东西?你贴出的代码中可没有工。
    windows下定时器,参考Timers Tutorial
    代码如下:void CTimersDlg::OnButtonBegin()
    {
    .
    .
    .
        // Set resolution to the minimum supported by the system    TIMECAPS tc;
        timeGetDevCaps(&tc, sizeof(TIMECAPS));
        m_uResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);
        timeBeginPeriod(resolution);    // create the timer    m_idEvent = timeSetEvent(
            m_elTime,
            resolution,
            TimerFunction,
            (DWORD)this,
            TIME_PERIODIC);
    }void CTimersDlg::OnButtonStop()
    {
        // destroy the timer
        timeKillEvent(m_idEvent);    // reset the timer
        timeEndPeriod (m_uResolution);
    }void CTimersDlg::MMTimerHandler(UINT nIDEvent) // called every elTime milliseconds
    {
    // do what you want to do, but quickly
    .
    .
    .
    }void CALLBACK TimerFunction(UINT wTimerID, UINT msg,
        DWORD dwUser, DWORD dw1, DWORD dw2)
        {
        // This is used only to call MMTimerHandler    // Typically, this function is static member of CTimersDlg    CTimersDlg* obj = (CTimersDlg*) dwUser;
        obj->MMTimerHandler(wTimerID);
        }看到没?TimerFunction是回调函数,在其中再调用对话框的MMTimerHandler,而不是把对话框类的静态成员函数设置为回调。
    回调函数里再调用对话框类的一个函数 和直接在回调函数里实现相应功能 有什么区别呢  比如说我想在对话框中显示一些东西 若直接在全局的回调函数里实现,则还需要传递对话框句柄什么的 现在用你这个方法是不是就不需要了呢?
    两者最大的区别在于,在对话框类的函数里,可以使用对话框类的成员变量,而在回调函数中,如果没有对话框类的指针,你是无法使用对话框类的成员变量。

    嗯 是啊  我最近正在试图使用多媒体定时器替换原来的系统定时器ontimer()。 之前我就是简单的把所有的对话框类的成员变量都用对话框类的指针指一下,但是SetItemText()函数总是报错,之前ontimer()里这个函数里只有两个参数,我也不明白为什么,但是在多媒体定时器中编译时他就提示我参数不够,唉  那我用你得方法这个会得到解决么 是不是可以直接将ontimer里的代码复制进去就可以啦? 还有我不太明白你得MMTimerHandler(UINT nIDEvent)函数里的 nIDEvent这个参数有什么用呢? 怎么用呢
      

  19.   

    报什么错?报错就解决。我还想知道a是什么东西?你贴出的代码中可没有工。
    windows下定时器,参考Timers Tutorial
    代码如下:void CTimersDlg::OnButtonBegin()
    {
    .
    .
    .
        // Set resolution to the minimum supported by the system    TIMECAPS tc;
        timeGetDevCaps(&tc, sizeof(TIMECAPS));
        m_uResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);
        timeBeginPeriod(resolution);    // create the timer    m_idEvent = timeSetEvent(
            m_elTime,
            resolution,
            TimerFunction,
            (DWORD)this,
            TIME_PERIODIC);
    }void CTimersDlg::OnButtonStop()
    {
        // destroy the timer
        timeKillEvent(m_idEvent);    // reset the timer
        timeEndPeriod (m_uResolution);
    }void CTimersDlg::MMTimerHandler(UINT nIDEvent) // called every elTime milliseconds
    {
    // do what you want to do, but quickly
    .
    .
    .
    }void CALLBACK TimerFunction(UINT wTimerID, UINT msg,
        DWORD dwUser, DWORD dw1, DWORD dw2)
        {
        // This is used only to call MMTimerHandler    // Typically, this function is static member of CTimersDlg    CTimersDlg* obj = (CTimersDlg*) dwUser;
        obj->MMTimerHandler(wTimerID);
        }看到没?TimerFunction是回调函数,在其中再调用对话框的MMTimerHandler,而不是把对话框类的静态成员函数设置为回调。
    回调函数里再调用对话框类的一个函数 和直接在回调函数里实现相应功能 有什么区别呢  比如说我想在对话框中显示一些东西 若直接在全局的回调函数里实现,则还需要传递对话框句柄什么的 现在用你这个方法是不是就不需要了呢?
    两者最大的区别在于,在对话框类的函数里,可以使用对话框类的成员变量,而在回调函数中,如果没有对话框类的指针,你是无法使用对话框类的成员变量。

    嗯 是啊  我最近正在试图使用多媒体定时器替换原来的系统定时器ontimer()。 之前我就是简单的把所有的对话框类的成员变量都用对话框类的指针指一下,但是SetItemText()函数总是报错,之前ontimer()里这个函数里只有两个参数,我也不明白为什么,但是在多媒体定时器中编译时他就提示我参数不够,唉  那我用你得方法这个会得到解决么 是不是可以直接将ontimer里的代码复制进去就可以啦? 还有我不太明白你得MMTimerHandler(UINT nIDEvent)函数里的 nIDEvent这个参数有什么用呢? 怎么用呢
    你看我4楼的回复,照着做,先编译通过了,再考虑其他的。回调函数里先可以什么都不做,等编译通过,单步调试没问题后再尝试加其他代码。