Re: CWnd::SetTimer, limited global resource.
On Sat, 20 Oct 2007 20:57:43 -0700, "David Ching"
<dc@remove-this.dcsoft.com> wrote:
"Giovanni Dicanio" <giovanni.dicanio@invalid.it> wrote in message
news:%23GiFqJ2EIHA.4772@TK2MSFTNGP02.phx.gbl...
Hi Peter,
I believe that a quality code must check the result of each operation
(like timer creation), and not assume that the operation will be always
successful.
The trouble is, what to do if something so basic as the timer cannot be
created? You can't set a timer to retry, for example! ;)
I think it is very easy to go overboard and try to recover from all manner
of highly unlikely problems like this, where, if they were to occur, Windows
is so screwed up anyway, that it will likely crash, or be manually rebooted
soon anyway. That's why I don't believe it a good use of programmer's time
to blindly be too rigorous about things like this; it is only justified if
if the cost of failure is too high, or if the cost in terms of programmer
time and additional code bloat is not excessive.
-- David
Under old Windows the timers were limited to 16 or 32 instances. I
think it was only 16, which was extremely limited and made for some
interesting problems for applications that wanted to use a lot of
timers for polling. You were supposed to do this:
idTimer = SetTimer(hWnd, 1, wTimerRate, NULL);
if (!idTimer) {
MessageBox(hWnd, "Not enough Timers!",
"myApp", MB_OK | MB_ICONSTOP);
DestroyWindow(hWnd);
return (FALSE);
}
Since the return value was and still is the ID of the timer, you
should ALWAYS get the return value so you can use it later when
calling KillTimer. Failure to capture a return value from a function
that returns its error state is bad coding style.
I just tried an old version of "PlyEyes" by Paul L. Yao & Malcolm
Austin, the code from which the above snippet came. My version can
spawn multiple copies of itself and I was up to 180 windows under
Windows XP when I decided to quit spawning more of them. Suffice to
say the number of timers is nearly unlimited and likely won't fail.
This is NOT the same as saying it CANNOT fail.
Any function that can fail, will fail. The function will always fail
when you didn't write code to catch the failure.
Since the equivalent MFC version incurs no programmer or code size
overhead I would consider it inexcusable not to plan for it.
void CMainFrame::OnStartTimer()
{
idTimer = SetTimer(nIDEvent, wTimerRate, NULL);
if (!idTimer) {
... // timer failed
}
}
void CMainFrame::OnStopTimer()
{
KillTimer(idTimer);
}
I should also point out the MSDN example doesn't show proper response
to a timer failure. No program should silently malfunction because
some programmer didn't consider it a good use of his time to catch a
failure from a class as simple as this one.