Welcome: Hunan Intelligent Applications Tecgnology CO.,ltd.-HNIAT.com
Language: Chinese ∷  English

Basic knowledge

MFC common class: Timer

The previous section described the use of the CTime and CTimeSpan classes, and this section continues with time-related timers. Timers are not a class. The main consideration is that when talking about time, you can't talk about timers, so I will explain it after CTime and CTimeSpan.

       Timer Introduction

       Timers can help developers or users complete certain tasks on a regular basis. When using a timer, we can pass in time interval data to the system, and then the system will trigger a timing handler after each time interval to implement periodic automatic operations. For example, in a data acquisition system, we can set the timer collection interval to 1 hour for the timer, then the system will collect data every 1 hour, so that it can be accurately operated without human operation. .

       MFC timer

       In VS2010 programming, we can use the member function SetTimer provided by the CWnd class of MFC to implement the timer function, or we can use the Windows API function SetTimer to achieve. The two methods are actually similar, but there are also differences.

       The SetTimer member function of the CWnd class can only be called in the CWnd class or its derived classes, while the API function SetTimer does not have this limitation, which is an important difference. Because this tutorial is mainly about MFC programming, here I will focus on the use of MFC timers. The use of the API function SetTimer will be extended based on the MFC timers.

       The method of using MFC timer is given below step by step.

       1. Start the timer.

       To start the timer, you need to use the member function SetTimer of the CWnd class. The prototype of CWnd :: SetTimer is as follows:

       UINT_PTR SetTimer (
             UINT_PTR nIDEvent,
             UINT nElapse,
             void (CALLBACK * lpfnTimer
       ) (HWND,
          UINT,
          UINT_PTR,
          DWORD
       )
       );

       The parameter nIDEvent specifies a non-zero timer ID; the parameter nElapse specifies the interval time in milliseconds; the parameter lpfnTimer specifies the address of a callback function. If the parameter is NULL, the WM_TIMER message is sent to the application's message queue and is CWnd object processing. If the function succeeds, it returns a new timer ID. We can use this ID to destroy the timer through the KillTimer member function. If the function fails, it returns 0.

       Through the SetTimer member function we can see that there are two ways to handle timing events, one is through the message response function of the WM_TIMER message, and the other is through the callback function.

       If you want to start multiple timers, call the SetTimer member function multiple times. In addition, there can be timers with the same ID in different CWnds, and they do not conflict.

       2. Add a message processing function for the WM_TIMER message, or define a callback function.

       If the last parameter of the CWnd :: SetTimer function is NULL, the timer event is processed by the WM_TIMER message processing function. The method for adding a handler function for the WM_TIMER message is to find the class to add a timer in the Class View of the VS2010 project, right-click, select Properties, display its property page, and then click the Messages button on the property page toolbar. The list lists all the messages, finds the WM_TIMER message, and adds a message processing function. After adding, the following content will appear in the cpp file:

C ++ code
BEGIN_MESSAGE_MAP (CExample44Dlg, CDialogEx)
    ...
    ON_WM_TIMER ()
END_MESSAGE_MAP ()
  
void CExample44Dlg :: OnTimer (UINT_PTR nIDEvent)
{
    // TODO: Add your message handler code here and / or call default
  
    CDialogEx :: OnTimer (nIDEvent);
}
       Then you can do the corresponding processing in the OnTimer function. OnTimer parameter nIDEvent is the timer ID, that is, the timer ID specified in the SetTimer member function. If there are multiple timers, we can handle it as follows:

C ++ code
void CExample44Dlg :: OnTimer (UINT_PTR nIDEvent)
{
    // TODO: Add your message handler code here and / or call default
    switch (nIDEvent)
    {
    case 1:
        // If a timer message with ID 1 is received, the func1 function is called
        func1 ();
        break;
    case 2:
        // If the message of timer 2 is received, func2 function is called
        fun2 ();
       break;
    ...
    default:
        break;
    }
     
    CDialogEx :: OnTimer (nIDEvent);
}
       If the last parameter of the CWnd :: SetTimer function is not NULL, you need to define a callback function. The form of the callback function is as follows:

C ++ code
void CALLBACK EXPORT TimerProc (
  
HWND hWnd, // handle of CWnd that called SetTimer
  
UINT nMsg, // WM_TIMER
  
UINT nIDEvent // timer identification
  
DWORD dwTime // system time
  
);
       The parameter hWnd is the handle of the CWnd object that calls the SetTimer member function, that is, the handle of the window that owns this timer; the parameter nMsg is WM_TIMER, and it is always WM_TIMER; the parameter nIDEvent is the timer ID; the parameter dwTime is the number of milliseconds since the system was started That is, the return value of the GetTickCount function.

       Then the last parameter of the CWnd :: SetTimer function can be TimerProc.

       Note here that the name of the callback function is not necessarily TimerProc, and it can take other names, but the return value type, parameter type and number cannot be changed.

       Chicken Pecker gives an example of a callback function:

C ++ code
void CALLBACK EXPORT TimerProc (HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
{
   switch (nTimerid)
   {
   case 1:
         // Handle the event of the timer with ID 1
         func1 ();
         break;
   case 2:
         // Handle the event of the timer with ID 2
         func2 ();
         break;
   ...
   default:
        break;
   }
}
       The callback function is a global function, which needs to be written in front of where it is used, or written later and then declared before use.

       3. Destroy the timer.

       When the timer is no longer used, it can be destroyed. To kill a timer, use the KillTimer member function of the CWnd class. The prototype of the CWnd :: KillTimer function is as follows:

C ++ code
BOOL KillTimer (UINT_PTR nIDEvent);
       The parameter nIDEvent is the ID of the timer to be destroyed, which is the timer ID set when the CWnd :: SetTimer function is called. Returns TRUE if the timer is destroyed, or FALSE if the specified timer is not found.

       If you want to destroy multiple timers, call the KillTimer function multiple times and pass in the IDs of the timers to be destroyed.

       Using timers through Windows API functions

       If we do not use MFC timers, but use timers through Windows API functions, it is actually very similar. Let ’s briefly talk about the next steps.

       1. Start the timer.

       Use the API function SetTimer to start the timer. The prototype of the SetTimer function is as follows:

C ++ code
UINT_PTR SetTimer (
    HWND
            hWnd,
    UINT_PTR
            nIDEvent,
    UINT
            uElapse,
    TIMERPROC
            lpTimerFunc
);
       The parameter hWnd is the handle of the window associated with the timer; the parameter nIDEvent is a non-zero timer ID. If hWnd is equal to NULL and there is no timer with the ID nIDEvent, then the nIDEvent parameter is ignored and a new ID is generated. Timer, and if hWnd is not NULL, and the window specified by hWnd already has a timer with ID nIDEvent, then this existing timer is replaced by a new timer. Parameters uElapse and lpTimerFunc are the same as the CWnd :: SetTimer function.

       2. Add a message processing function for the WM_TIMER message, or define a callback function.

       If the last parameter is NULL when calling the SetTimer function, we need to add a handler function for the WM_TIMER message by ourselves. Note that the additional data wParam of the WM_TIMER message is the timer ID, lParam is the pointer to the callback function. Is NULL, then lParam is also NULL.

       If the last parameter of the SetTimer function is not NULL, we need to define a callback function. The definition of the callback function is the same as the MFC timer.

       3. Destroy the timer.

       The KillTimer API function is used to destroy the timer. The prototype is as follows:

C ++ code
BOOL KillTimer (HWND hWnd, UINT_PTR uIDEvent);
       The parameter hWnd is the handle of the window associated with the timer, and has the same value as the hWnd parameter of the SetTimer function when the timer is started; the parameter uIDEvent is the ID of the timer to be destroyed. If the parameter hWnd passed to SetTimer is valid, uIDEvent should be the same as the passed The parameter nIDEvent given to SetTimer is the same, and if the parameter hWnd of SetTimer is NULL, uIDEvent should be the timer ID returned by SetTimer. The function returns TRUE on success, otherwise FALSE.

       MFC timer application examples

       Chicken pecking meter shows an example of a timer. The function of this example is very simple. It uses two timers to periodically update the display content in the two edit boxes. The first edit box is refreshed every second from 1 to 10, then destroy the timer, refresh the second edit box every two seconds, refresh from 1 to 5, and then destroy the timer. Let's briefly talk about the next steps:

       1. Create a dialog-based project with the name "Example44".

       2.Automatic Health

CONTACT US

Contact: Manager Xu

Phone: 13907330718

Tel: 0731-22222718

Email: hniatcom@163.com

Add: Room 603, 6th Floor, Shifting Room, No. 2, Orbit Zhigu, No. 79 Liancheng Road, Shifeng District, Zhuzhou City, Hunan Province

Scan the qr codeClose
the qr code