SAMPLE: Using a TimerProc Function in MFC Application
ID: Q130866
|
The information in this article applies to:
-
The Microsoft Foundation Classes (MFC), included with:
-
Microsoft Visual C++ for Windows, 16-bit edition, versions 1.0, 1.5, 1.51, 1.52
-
Microsoft Visual C++, 32-bit Editions, versions 1.0, 2.0, 2.1, 4.0
SUMMARY
The TMRPROC sample is designed to demonstrate how to use the SetTimer() API
in an MFC Application in such a way that the TimerProc() callback function
(a member of a C++ class) is used instead of handling WM_TIMER messages.
There are two makefiles included:
- TMRPROC.MAK, generated by Visual C++ version 1.5.
- TMRPRC32.MAK, generated by Visual C++ version 2.0.
MORE INFORMATION
The following file is available for download from the Microsoft Software
Library:
~ TMRPROC.EXE
For more information about downloading files from the Microsoft Software
Library, please see the following article in the Microsoft Knowledge Base:
Q119591
How to Obtain Microsoft Support Files from Online Services
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.
REFERENCES
MSDN Technical Articles, C/C++ Articles, "Calling All Members: Member
Functions As Callbacks," by Dale Rogerson.
Additional query words:
kbfile tmrproc settimer
Keywords : kbMFC
Version : 1.00 1.50 1.51 1.52 | 1.00 2.00
Platform : NT WINDOWS
Issue type :
Last Reviewed: July 26, 1999