OnTimer方法在MFC中不起作用

时间:2013-10-07 05:57:43

标签: c++ visual-studio-2010 timer mfc message-queue

我在VS2010中创建了一个基于MFC对话框的应用程序,并希望添加计时器每3秒更新一次图片控制器。但OnTimer方法从未起作用。

我使用类向导将WM_TIMER添加到消息队列中,结果如下:

BEGIN_MESSAGE_MAP(CxxxxDlg, CDialogEx)
    ON_WM_PAINT()
    ON_BN_CLICKED(IDOK, &CxxxxDlg::OnBnClickedOK)
    ON_WM_TIMER()
END_MESSAGE_MAP()

在xxxxDlg.cpp中,我将SetTimer方法放在OnInitDialog中:

BOOL CxxxxDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    SetIcon(m_hIcon, TRUE);
    SetIcon(m_hIcon, TRUE);

    _imageCounter = 1;
    _isMale = 3;
    _testNum = 0;

    SetTimer(123, 2000, NULL);

    bFullScreen = false;
    OnFullShow();
    updateImages();
    UpdateData();

    return TRUE;
}

OnTimer方法在xxxxdlv.h中声明:

public:
    afx_msg void OnTimer(UINT_PTR nIDEvent);

当我运行应用程序时,SetTimer返回123.所以一切都应该在这里。 但该程序从未达到我在OnTimer方法第一行中设置的断点!

然后我写了另一个 hello world 项目来测试计时器。我以完全相同的方式设置计时器并且运行良好。

所以我认为OnFullShow()方法可能是问题所在。此方法用于将窗口更改为全屏模式。我评论这一行,但OnTimer仍然无法工作。

我已查看问题here。但它没有帮助。

有谁知道问题的来源?谢谢!

PS。我确实收到了一些内存泄漏的警告。这有关系吗?

1 个答案:

答案 0 :(得分:1)

感谢@IInspectable。我找到了技术支持here。它完全解释了原因并告诉了一个解决方案:

// Rewrite PreTranslateMessage method
BOOL CMyApp::PreTranslateMessage( MSG *pMsg )
{
   // If this is a timer callback message let it pass on through to the
   // DispatchMessage call.
   if( (pMsg->message==WM_TIMER) && (pMsg->hwnd==NULL) )
       return FALSE;
   ...
   // The rest of your PreTranslateMessage goes here.
   ...

   return CWinApp::PreTranslateMessage(pMsg);
}

这个解决方案并没有解决我的问题,但给了我一个提示。应该重写PreTranslateMessage方法,让WM_TIMER传递给DispatchMessage调用。 但是,如果您使用PreTranslateMessage来处理其他消息,例如WM_KEYDOWN,则上述解决方案可能无效。这似乎是优先考虑的问题。最后,我使用switch代替if来解决问题:

// Rewrite PreTranslateMessage method
BOOL CMyApp::PreTranslateMessage( MSG *pMsg )
{
   // If this is a timer callback message let it pass on through to the
   // DispatchMessage call.
   switch(pMsg->message)
   {
    case WM_KEYDOWN: // your codes
    case WM_TIMER: return false;
    ...
   }
   ...
   // The rest of your PreTranslateMessage goes here.
   ...

   return CWinApp::PreTranslateMessage(pMsg);
}

我希望这可以帮助那些有类似问题的人。

PS。 pMsg->hwnd==NULL已移除switch,我不确定它是否安全。