Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SetTimer() & callback handler

216 views
Skip to first unread message

kevin_waite

unread,
Apr 21, 2009, 3:52:09 AM4/21/09
to
Newbie here, I need some help/guidance with the
following:

My main class is MomPC

I have a static non-class CALLBACK hander called: btn_timer()

btn_timer() is defined identically to TIMERPROC

I can use SetTimer() successfully with the static btn_timer()
as the 4th parm/CALLBACK to SetTimer().

However, when the handler runs (timer expired) btn_timer()
runs but does not have access to my main class instance
of MomPC -- booooooo.

If I make btn_timer() as a method with MomPC -- then I do
not know how to cast &MomPC::btn_timer() into (TIMERPROC)
successfully -- this may be impossible -- I just do not know.
If this can be done -- this would likely solve my problem.

The common solution to getting the callback handler to get
access to a class is to define the event handler and callback
handler initialization is to define a user pionter and pass "this"
during
the setup --- SetTimer doesn't have a user pointer parameter
to use for this purpose....... I can only think to add one global
as a pointer to my main class -- surely there is a better way,
no?

When there is a timer callback set for timer expirations --
will SetTimer() also be putting WM_TIMER
message in the window's message box? I mean, does having
the callback handler inplace remove the WM_TIMER
messages -- this is an either/or?

Thanks in advance.

Sincerely,
Kevin Waite

Giovanni Dicanio

unread,
Apr 21, 2009, 4:13:26 AM4/21/09
to

"kevin_waite" <kevin00...@gmail.com> ha scritto nel messaggio
news:80e8e35b-432b-4662...@y7g2000yqa.googlegroups.com...

> I have a static non-class CALLBACK hander called: btn_timer()
>
> btn_timer() is defined identically to TIMERPROC
>
> I can use SetTimer() successfully with the static btn_timer()
> as the 4th parm/CALLBACK to SetTimer().
>
> However, when the handler runs (timer expired) btn_timer()
> runs but does not have access to my main class instance
> of MomPC -- booooooo.

I would use a different paradigma, that does not require a "static
non-class" callback handler.

You can have a class derived from CWnd (for example a dialog-box). CWnd has
a method called SetTimer(), that you can use to create the timer. For
example, you can call it in your OnInitDialog() method:

// Create the timer
SetTimer(
1, // timer ID
1000, // time out value, in milliseconds
NULL, // no callback procedure to handle timing events
);

(In addition, you may want to check the return value of SetTimer to detect
some error.)

After the timer is created, you can handle the WM_TIMER message in your
dialog-box class, e.g.

void CYourDialog::OnTimer( UINT nIDEvent )
{
... do something here

CDialog::OnTimer( nIDEvent );
}

OnTimer() is a method of CYourDialog class, so you have access to all other
methods and data members of that class (without requiring passing a pointer
to 'this').

HTH,
Giovanni

Mihai N.

unread,
Apr 21, 2009, 5:02:22 AM4/21/09
to
> the setup --- SetTimer doesn't have a user pointer parameter
> to use for this purpose....... I can only think to add one global
> as a pointer to my main class -- surely there is a better way,
> no?

UINT_PTR SetTimer(
HWND hWnd,
UINT_PTR nIDEvent,
UINT uElapse,
TIMERPROC lpTimerFunc
);

The documentation is confusing, but I think you can use nIDEvent
for that. I know I did it in some projects, without any troubles
(but maybe it was a misuse?)

--
Mihai Nita [Microsoft MVP, Visual C++]
http://www.mihai-nita.net
------------------------------------------
Replace _year_ with _ to get the real email

BobF

unread,
Apr 21, 2009, 8:59:31 AM4/21/09
to

Something I've used:

For example ...

#include <windows.h>
.
.
HANDLE hTimer;
.
.
VOID CALLBACK ProcessTimer(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
// lpParam contains pointer to effect class in this example
// do something
}

.
// create the timer. perhaps in startProcess()
if (!CreateTimerQueueTimer(&hTimer, NULL,
(WAITORTIMERCALLBACK)ProcessTimer, this, 100, 100, 0))
// error creating timer
.
// delete the timer. perhaps in stopProcess()
DeleteTimerQueueTimer(NULL, hTimer, NULL);

Joseph M. Newcomer

unread,
Apr 21, 2009, 9:45:30 AM4/21/09
to
See below...

On Tue, 21 Apr 2009 00:52:09 -0700 (PDT), kevin_waite <kevin00...@gmail.com> wrote:

>Newbie here, I need some help/guidance with the
>following:
>
>My main class is MomPC
>
>I have a static non-class CALLBACK hander called: btn_timer()
>
>btn_timer() is defined identically to TIMERPROC
>
>I can use SetTimer() successfully with the static btn_timer()
>as the 4th parm/CALLBACK to SetTimer().

****
SetTimer will callbacks is almost always a Really Bad Idea. Assume it is a mistake and
proceed from there. Put a WM_TIMER handler in, instead. If there is a reason you believe
this will not work, then it is actually the same reason callbacks don't work.
****


>
>However, when the handler runs (timer expired) btn_timer()
>runs but does not have access to my main class instance
>of MomPC -- booooooo.

****
Yep. The main reason for not ever wanting to use timer callbacks!
****


>
>If I make btn_timer() as a method with MomPC -- then I do
>not know how to cast &MomPC::btn_timer() into (TIMERPROC)
>successfully -- this may be impossible -- I just do not know.
>If this can be done -- this would likely solve my problem.

****
Don't even try to use callbacks. Use WM_TIMER/OnTimer to handle it.
****


>
>The common solution to getting the callback handler to get
>access to a class is to define the event handler and callback
>handler initialization is to define a user pionter and pass "this"
>during
>the setup --- SetTimer doesn't have a user pointer parameter
>to use for this purpose....... I can only think to add one global
>as a pointer to my main class -- surely there is a better way,
>no?

*****
SetTimer was badly designed, and we are years overdue in having SetTimerEx that does
something intelligent. Solution: Don't use SetTimer with a callback
*****


>
>When there is a timer callback set for timer expirations --
>will SetTimer() also be putting WM_TIMER
>message in the window's message box? I mean, does having
>the callback handler inplace remove the WM_TIMER
>messages -- this is an either/or?

*****
Yes. The two are mutually exclusive. Do not use callbacks. They gain you nothing, and
only make your life miserable.
joe
****


>
>Thanks in advance.
>
>Sincerely,
>Kevin Waite

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

kevin_waite

unread,
Apr 22, 2009, 2:55:36 AM4/22/09
to
Thanks Giovanni, Mihai, BobF, Joseph, Scott, and David,
I have gotten my button timeout timer working perfectly, I did it both
ways, the static callback way with the IdEvent being a pointer to my
class and by figuring out how to add the needed code to the
slightly ugly MESSAGE_MAP logic -- the later took a bit of time --
but I found enough info helper threads online to figure it out -- I
have had
next to zero luck in using the VS Class wizard for such things only
because I don't know how to use it.
Looking and compairing both ways of dealing with timer expiration,
I will go forward with the WM_TIMER message way, which seems to be
the better way.

regards,
Kevin

0 new messages