CWnd::SetTimer() is not a static member function -- that means, that in
order to call it, you MUST have a valid CWnd object.
Why do you use callbacks, instead of handling WM_TIMER in the window class?
-n
I must admit I never did it that way. What's always worked for me was to
use something like:
SetTimer(201, 10, NULL);
and use class wizard to handle the WM_TIMER message
in an OnTimer(UINT nIDEvent).
which has stuff like:
switch (nIDEvent)
{
case 201:
KillTimer(201);
...
If you decide to try the WM_TIMER way, what you'll have to do is add a
handler function for WM_TIMER (the MS IDE's let you do in a "point and
click" fashion, but the details vary depending of the version of the IDE
you're using). It will end up looking something like this:
void CYourWnd::OnTimer(UINT nIDEvent)
{
if(nIDEvent == 998)
{ // this is the "998" timer
...
return;
}
if(nIDEvent == 999)
{ // this is the "999" timer
...
return;
}
// You can add more "if" blocks like the above here
// for as many timer ID's as you need.
//
// Remember to call the base class if you did not
// recognize the timer ID. If your class is derived
// from something other than CWnd, then replace
// CWnd with the appropriate base class
CWnd::OnTimer(nIDEvent);
}
Now, when you set the timer, you can do something like this:
SetTimer(998, 5000, NULL);
-n
You should make this decision carefully. I prefer to use callbacks rather
than having WM_TIMER be posted. The reason I choose callbacks over WM_TIMER
is that the callback will always be called no matter how many messages the
window is pumping. The WM_TIMER message is a low priority message. If your
message queue is full or really busy, all of your WM_TIMER messages are
ignored because they are of less priority than most other window messages
(virtually all but WM_PAINT). There is also less overhead in calling a
function directly rather than posting a windows message and waiting for it
to be seen by your message loop. I am not saying do not use WM_TIMER, but
if it is anything critical, I would not trust the WM_TIMER method over the
callback method because under certain situations your WM_TIMER message will
never be received.
Do not use hardwired numbers for timer IDs. Always use a #define.
But in general, you should consider using WM_TIMER messages instead of callbacks. Life
becomes a great deal simpler.
The answer is that it is legal to reset the timer interval in any handler. The problem is
that the callback has to be a static method, and consequently cannot access the CWnd.
Using an OnTimer handler makes this problem go away, and is the preferred way of handling
timer events.
As far as I can tell, there is no advantage to using timer callbacks, and considerable
disadvantage.
joe
On Tue, 1 Jun 2004 10:06:04 -0700, "bruce" <anon...@discussions.microsoft.com> wrote:
>Hi,
>
>New to MFC and C++, and timer syntax is giving me fits. Here is what I am trying to do. From one function (bottom of the 3 listed below) I would like to set a timer for a specific amount of time. Compiler is happy.
>Then, from within the Timer Callback routine, I want to set another timer (second routine shown below), using the exact same syntax, but I get the compiler error:
>
> CWnd::SetTimer : illegal call of non-static member function
>
>Also, if I want to reset a timer for another period of time, is it done by just calling SetTimer again, with the same parameters, from within the Callback function (and passing the Callback function iteself as a parameter? I.e., in the PeriodicTimerCallback function, below, could I replace "do some stuff" wit this line?
>
>Any suggestions about what I might be doing wrong would be gladly accepted
>
> UINT StartUpTimer = CWnd::SetTimer(998, 5000, PeriodicTimerCallback);
>
>
>
>
>void CALLBACK EXPORT PeriodicTimerCallback( HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
>{
> .. do some stuff
>}
>
>
>void CALLBACK EXPORT OneShotTimerCallback( HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
>{
> ...
>===========> following line throws compiler error
> UINT StartUpTimer = CWnd::SetTimer(998, 5000, PeriodicTimerCallback);
> ....
>}
>
>And in calling routine, I have this ....
>
> // And, set the timer ....
> UINT StartUpTimer = CWnd::SetTimer(999, SetTimeInMilliSeconds, OneShotTimerCallback);
>
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
"Trevor" <tre...@nospam.com> wrote in message
news:eoDIfgBS...@TK2MSFTNGP10.phx.gbl...
From the SetTimer documentation:
Remarks
An application can process WM_TIMER messages by including a WM_TIMER case statement in the
window procedure or by specifying a TimerProc callback function when creating the timer.
When you specify a TimerProc callback function, the default window procedure calls the
callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in
the calling thread, even when you use TimerProc instead of processing WM_TIMER.
The overhead issue is irrelevant and should not even enter such a discussion.
joe
Joseph M. Newcomer [MVP]
[ ... ]
> You should make this decision carefully. I prefer to use callbacks rather
> than having WM_TIMER be posted. The reason I choose callbacks over WM_TIMER
> is that the callback will always be called no matter how many messages the
> window is pumping.
Not true -- the callback function is invoked from a WM_TIMER handler
in DefWindowProc/DefFrameProc.
--
Later,
Jerry.
The universe is a figment of its own imagination.