Re: Thread and Timer
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Wed, 12 Mar 2008 10:39:20 -0500
That's right. That's what you would expect in a thread which has no message pump, or for
which you blocked the message pump.
First, callback timers are about the most useless entities in all of Windows. Try to
avoid them because they give no value, and only add gratuitous complexity to the problem,
such as the pointless global variables you have. These would not be needed had the timer
callback been designed correctly, which it wasn't.
The presence of global variables should already be a sign that the approach is wrong.
There are very limited number of APIs for which these make sense at all, and every one of
those APIs represents a faulty design on the part of Microsoft.
On Wed, 12 Mar 2008 00:55:52 -0700 (PDT), Stefano <posting@xxxxxxxxxx> wrote:
Hi,****
I'd like to use a timer inside a thread (CWinThread derived class).
If I use the CALLBACK procedure I get the timer, if I don't use the
CALLBACK and handle in OnTimer I never get the message.
Here is the code:
// WatchDog.cpp : implementation file
//
#include "stdafx.h"
#include "xcrashreport.h"
#include "WatchDog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CString g_sFileName;
HWND g_hWnd;
UINT g_iMessage;
UINT g_iTimer;
UINT g_iTimerTimeout;
/////////////////////////////////////////////////////////////////////////////
// CWatchDog
void CALLBACK OnTimerProc(
HWND hwnd, // handle to window
UINT uMsg, // WM_TIMER message
UINT_PTR idEvent, // timer identifier
DWORD dwTime // current system time
)
{ // OnTimerProc
if (idEvent == g_iTimer)
{
PostMessage(g_hWnd, g_iMessage, WPARAM (0), LPARAM (0));
KillTimer( NULL, g_iTimer );
AfxEndThread( 0, false );
}
} // OnTimerProc
IMPLEMENT_DYNCREATE(CWatchDog, CWinThread)
BOOL CWatchDog::InitInstance()
{
// TODO: perform and per-thread initialization here
return TRUE;
}
int CWatchDog::ExitInstance()
{
// TODO: perform any per-thread cleanup here
return CWinThread::ExitInstance();
}
BOOL CWatchDog::IsIdleMessage( MSG* pMsg )
{
if ( !CWinThread::IsIdleMessage( pMsg ) || ( pMsg->message ==
WM_TIMER ) )
This code should not exist. Drop this whole function!
****
{****
return FALSE;
}
return TRUE;
}
BEGIN_MESSAGE_MAP(CWatchDog, CWinThread)
//{{AFX_MSG_MAP(CWatchDog)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
ON_THREAD_MESSAGE(WM_TIMER, OnTimer)
Why not do something very simple: ON_WM_TIMER()?
You have added tons of complexity to what is a trivial problem.
****
****
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWatchDog message handlers
void CWatchDog::Monitor(CString sFileName, HWND hWnd, UINT iMessage,
int iFrequency, int iTimeout)
{
//g_iTimer = ::SetTimer(NULL, NULL, iFrequency, (TIMERPROC)
OnTimerProc);
g_iTimer = SetTimer(NULL, 0, iFrequency, NULL);
g_hWnd = hWnd;
g_iMessage = iMessage;
Why not
SetTimer(iFrequency, NULL);
which is so much simpler?
****
}****
void CWatchDog::OnTimer(WPARAM wParam, LPARAM lParam)
{
if ((UINT) wParam == g_iTimer)
{
PostMessage(g_hWnd, g_iMessage, WPARAM (0), LPARAM (0));
}
}
You do not need a g_iTmer, g_hWnd, or g_iMessage here, if this were a handler for
WM_TIMER. Get rid of them. I can't even imagine why they are needed at all, since they
coudl be member variables of the CWatchDog class.
Treat tasks that require global variables as deeply suspect.
joe
****
Joseph M. Newcomer [MVP]
Thanks in advance,
Stefano
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- Follow-Ups:
- Re: Thread and Timer
- From: Stefano
- Re: Thread and Timer
- From: AliR \(VC++ MVP\)
- Re: Thread and Timer
- References:
- Thread and Timer
- From: Stefano
- Thread and Timer
- Prev by Date: Re: system language
- Next by Date: Re: Can you change the Semaphore Timeout for Serial I/O?
- Previous by thread: Re: Thread and Timer
- Next by thread: Re: Thread and Timer
- Index(es):
Relevant Pages
|