Reputation: 1674
I created an MFC dialog based app in VS2010, and wanted to add timer to update a picture controller every 3 seconds. But the OnTimer method never worked.
I have used Class Wizard to add WM_TIMER into the message queue, which turned out to be as following:
BEGIN_MESSAGE_MAP(CxxxxDlg, CDialogEx)
ON_WM_PAINT()
ON_BN_CLICKED(IDOK, &CxxxxDlg::OnBnClickedOK)
ON_WM_TIMER()
END_MESSAGE_MAP()
In xxxxDlg.cpp, I put SetTimer method in 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;
}
The OnTimer method was declard in xxxxdlv.h:
public:
afx_msg void OnTimer(UINT_PTR nIDEvent);
When I run the app, the SetTimer returned 123. So everything should be all right here. But the program never reached the breakpoint I set in the 1st line of OnTimer method!
Then I wrote another hello world project only to test the timer. I set the timer in exactly the same way and it worked well.
So I thought the OnFullShow() method may be the problem. This method was used to change the window into full screen mode. I comment this line , but still OnTimer never worked.
I have check the questions here. But it doesn't help.
Does anyone know where the problem comes from? Thanks!
PS. I did receive some warnings of memory leaks. Did this matter?
Upvotes: 1
Views: 9670
Reputation: 1674
Thanks to @IInspectable. I found a tech support here. It fully explains the cause and tells one solution:
// 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);
}
This solution does not solve my problem but gives me a hint. PreTranslateMessage
method should be rewritten to let WM_TIMER
pass on through to the DispatchMessage call. But if you are using PreTranslateMessage
to deal with other messages, WM_KEYDOWN
for example, the solution above may not work. It seems to be a problem about priority. In the end, I solve it using switch
instead of 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);
}
I hope this will help anyone who has similar problem.
PS. pMsg->hwnd==NULL
is removed in switch
and I am not sure if it is safe.
Upvotes: 1