Visual c++ setTimer()只生成一次WM_定时器消息

Visual c++ setTimer()只生成一次WM_定时器消息,visual-c++,mfc,Visual C++,Mfc,我正在使用添加了资源ID的计时器,并基于WM_计时器消息。 我想在OnTimer()上调用一个像duckendragon()这样的例程,但是在调用SetTimer(id,10sec,NULL)之后只调用一次。我们知道,调用KillTimer()内部duckendragon()例程可以解决问题。这样可以吗,还是我错过了一些很棒的计时器 int CYourDialog::OnInitDialog() { __super::OnInitDialog(); SetTimer(0x10, 1

我正在使用添加了资源ID的计时器,并基于WM_计时器消息。 我想在
OnTimer()
上调用一个像
duckendragon()
这样的例程,但是在调用
SetTimer(id,10sec,NULL)
之后只调用一次。我们知道,调用
KillTimer()
内部
duckendragon()
例程可以解决问题。这样可以吗,还是我错过了一些很棒的计时器

int CYourDialog::OnInitDialog()
{
   __super::OnInitDialog();

   SetTimer(0x10, 10000, NULL);

   return true;
}

void CYourDialog::OnTimer(UINT_PTR ignore)
{
   DrunkenDragon();
}

并确保消息映射中的WM\U计时器上有

您没有遗漏任何内容,您必须使用KillTimer for system停止生成WM\U计时器消息

您还可以使用CreateTimerQueueTimer并以只调用一次回调的方式设置参数

(只有在其他人像我一样遇到它并且对可用的答案不满意时才回答此问题)

因此,在WindowClass.h中,您可以做的是枚举要使用的计时器标识符。虽然您当然可以使用原始数值,但从长远来看,使用符号可能更容易处理

class WindowClass : CWnd
{
    // other parts of the interface...

protected:

    enum
    {
        TIMER_MAIN_UPDATE = 1,
        TIMER_PLASTERED_DRAGON
    };
};
同时,回到WindowClass.cpp中

int WindowClass::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    // { ... other initialization code }

    // In case you want to do other types of updates at regular intervals.
    SetTimer(TIMER_MAIN_UPDATE, 1000, NULL);

    // Note the symbolic identifiers.
    SetTimer(TIMER_PLASTERED_DRAGON, 10000, NULL);

    return 0;
}
不过,如果您想在创建窗口10秒后执行此操作,那么这才有好处。您还可以随时在其他事件处理程序中调用SetTimer():

void WindowClass::OnJustGotPaid()
{
    // { ... other handling }

    // Since our dragon is a real lightweight, it apparently only takes
    // 10 seconds to get him puking up flaming vomit.
    SetTimer(TIMER_PLASTERED_DRAGON, 10000, NULL);
}
当需要处理实际事件时,通常在Windows OnTimer()回调中处理。如果需要,可以通过在SetTimer()的第三个参数中指定有效的函数指针而不是NULL,将计时器事件定向到其他(自定义)回调

void WindowClass::OnTimer(UINT_PTR p_timer_id)
{
    switch(p_timer_id)
    {

    default:
        break;

    case TIMER_MAIN_UPDATE:

        // { ... main update code }
        break;

    case TIMER_PLASTERED_DRAGON:

        // Killing the timer first in case DrunkenDragon() takes a good
        // long while for whatever reason.
        KillTimer(TIMER_PLASTERED_DRAGON);

        DrunkenDragon();

        break;
    }
}

为什么是资源id?您可以使用计数器变量检查计时器是否第一次触发。