Visual C++ SetTimer

Despite the fact that it’s now outdated and I’ll be getting Visual C++ .NET, I’m still going through my SAMs Teach Yourself Visual C++ 6 in 21 Days book anyway, because, well, it doesn’t matter for this thread.
Anyway, in the section about timers, for multiple timers it simply has you initialize different ID’s and use NULL for the last argment in SetTimer so that each timer calls WM_TIMER and then you simply check which ID is being called to decide which code to execute.
Today I went back to that program and tried something different. I created a new function OnTimer2(UINT nIDEvent) (The full title of the function is void CTimersDlg::OnTimer2(UINT nIDEvent)). I tried to make it so that the first timer still calls WM_TIMER, but the second timer calls my new function. However, I can’t seem to pass the address properly.
Actually, I may be making this thread too long and complicated, so I’ll try to simplify it.
Say I want to set up a second timer, at 1 millisecond intervals, and have it call my OnTimer2 function. OK, I go SetTimer(2, 1, what do I put for the third argment?)
Thanks.

I think what you need is to make your OnTimer2 function a callback function. Although you case it to a void pointer when using it as a parameter, the actual function needs to have the following return type and parameter list:

CALLBACK EXPORT* OnTimer2(HWND, UINT, UINT, DWORD)

Also, remember to make this a public function (seeing as it’s part of your CTimersDlg class). If it’s private or protected, it won’t be usable as a callback.

I’ve passing familiarity with this; I tend to use my own messaging classes, but I’ll take a shot, it’s not rocket science.

The original OnTimer function is probably overriding a virtual function (from CTimersDlg derived from CDialog derived from CWnd or somesuch) that’s looking for the WM_TIMER message. Your function overrode that function, so now that function gets WM_TIMER messages. Your OnTimer2 function isn’t overriding the base class function, so you never get notified.

Your OnTimer2 has to be in the base class and overridden, or you need to use a different method to solve this problem.

I’d suggest dispatching to a handler function from the OnTimer handler. Use the timerID (wParam) sent to OnTimer to identify the action to trigger. Use a switch{} to dispatch to the correct handler for that timer.

My recollection is that the explicit timer function is less reliable than just using the messaging, but I haven’t tested this since XP launched. IIRC, in Win98/etc, the timer function didn’t get called reliably. YMMV, I haven’t tested this sort of timer in a while.

The other EZ dispatch method is to use the timerID to identify the dispatch function that should be called.

The timerID can be any arbitrary number and doesn’t need to be unique except per-window. You could just define a generic timer-handler, define several routines of this sort, and then pass the appropriate routine’s function pointer as the timerID to SetTimer.

When called during OnTimer, retrieve the timerID, coerce it back to a function pointer, and call it.

If it’s part of a class, it probably needs to be static.

That too, ultrafilter. Forgot to mention it, thanks for doing so.

Thanks to everybody. The information was helpful, but still didn’t quiet work, so I looked up callback functions and SetTimer and finally came up with
This site
Which helped me figure it out.