MORE INFORMATION
The
following file is available for download from the Microsoft Download
Center:
For
additional information about how to download Microsoft Support files, click the
following article number to view the article in the Microsoft Knowledge Base:
119591 How to Obtain Microsoft Support Files from Online Services
Microsoft scanned this file for viruses. Microsoft used the most
current virus-detection software that was available on the date that the file
was posted. The file is stored on security-enhanced servers that help to
prevent any unauthorized changes to the file.
NOTE: When extracting files from TMRPROC.EXE, be sure to use
the -d option to create subdirectories.
The challenge of using
callback functions as C++ class members can be approached in several different
ways, depending on the circumstances surrounding the callback. In "Calling All
Members:..." (see References below), four different approaches are mentioned.
They are:
- Not accessing any class members from within the static
callback.
- Storing the "this" pointer to the object in a static
member.
- Passing the "this" pointer to the callback function via a
parameter supplied by APIs that use callbacks.
- Storing a list of "this" pointers mapped to the list of
objects servicing the callback in a static structure.
The TMRPROC sample application illustrates the second and
fourth cases. These are the most likely scenarios MFC Doc/View/UI type
applications encounter. Not accessing any members from a callback is quite
limiting, and passing the "this" pointer in a callback-supplied parameter is
dependent on the API. For these reasons, the sample does not address the first
and third cases.
TMRPROC.CPP and .H
Storing the "this" pointer to the object in a static member is
demonstrated in the CWinApp-derived class, CTmrprocApp.
There is no
window associated with this class, so the output used to indicate the timer
event is done via OutputDebugString(). The pThis variable is a static member
variable that is initialized in the constructor to contain the "this" pointer
for the class. The TimerProc() callback is simply a static member function of
type "void CALLBACK EXPORT." It is static, so no "this" pointer is passed in.
For this reason, the pThis member variable is used to store the CTmrprocApp's
"this" pointer. Whenever TimerProc() gets called, the current instance of
CTmrprocApp can be referenced through the CTmrprocApp::pThis member.
This is the simplest case. There are three functions added to the CTmrprocApp
class to accomplish this objective - TimerProc(), CTmrprocApp::OnAppsettimer(),
and CTmrprocApp::OnAppkilltimer(). The later two are the menu handlers that
allow the user to start and stop the timer.
TMRPRVW.CPP and .H
Storing a list of "this" pointers mapped to the list of objects
servicing the callback in a static structure is implemented in the view class,
CTmrprocView.
In this case, a little more work is required, but not
much. Because a timer needs to be set for each instance of the view class, a
scheme must be implemented to associate each timer ID with a corresponding view
object. The view object is identified by its "this" pointer and the timer by
its timer ID (passed back from SetTimer()). The view class associates these and
stores them in a CMapWordToPtr static member variable. This way, when each
view's TimerProc() is called, it can first look up its "this" pointer in the
pointer/ID map, and then update its own members.
There are several
functions needed to start, stop, and reset the count on the timer. The count is
just a running count of the number of times TimerProc() has been called for the
current view. The following are the start, stop, and reset functions:
CTmrprocView::OnTimerStart() - Start timer in current view.
CTmrprocView::OnTimerStop() - Stop timer in current view.
CTmrprocView::OnTimerReset() - Reset count for current view.
The following are some "all" type functions that can be used to
start, stop, and reset the timer for each view:
CTmrprocView::OnTimerAllStart() - Start timers for all views.
CTmrprocView::OnTimerAllStop() - Stop timers for all views.
CTmrprocView::OnTimerAllReset() - Reset timer count for all views.