我在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。我确实收到了一些内存泄漏的警告。这有关系吗?
答案 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
,我不确定它是否安全。