forward from:
http://www.evget.com/articles/evget_780.html
In Window Programming, we often trigger certain code execution by relying on Timer. But in ATL's ActiveX programming, the usage of Timers is limited, below, I will talk about how to use Timers in ATL's ACTIVEX program based on development experience.
First, in order to optimize performance, the current ActiveX control is divided into two windows and windowless controls.
In the window control, the programming resources you have are almost different from ordinary Windows programming, while the timer is used. In ATL, you can create an ActiveX control with a window if you specify the Control base class CCOMControlbase's member M_BWindowonly to True in the Control Texture Function. Examples are as follows:
MyControl: myControl () {
m_bwindowonly = true;
}
This allows the timer to be set and used in the program with Settimer / KillTimer and responding to the WM_TIMER message.
When as an ATL programmer, we certainly do not give up each opportunity for each optimization program, let me introduce several ways to use the timer in the ACTIVEX control in the ATL:
The first type: use the callback function. In VC, due to the MFC and ATL packaging, we can ignore window handle parameters, create one and window associated timer. When there is no window handle, the settimer function that directly calls CWindow will give you an Assert dialog box. At this time, we have to return to the API to seek help. Since the API setTimer is created in addition to the window handle, it provides us with a callback function to respond to timing events so that we can bypass the resource-free control. Timer.
First, define a timer's callback function:
Void Callback TimerProc
HWND HWND, // Timer Message Window Handle
Uint message, // wm_timer message
UINT IDTIMER, / / Timer flag
DWORD DWTIME) // Current system starts timing
{
// Add your timer processing code here
}
Next, you can use Settimer to use the timer.
UResult = setTimer (null, // handle to main window
ID_TIMER, / / Timer ID
1000, // 1 second
(TimerProc); // callback function
The second: Usually we use the timer, often want to notify yourself at the timing incident, although the above method can, but there is a bit inconvenient in the passage of the parameters, here I use multithreaded to simulate the internship, As the programming style in the ATL, add some functions to the implementation class, usually use the template base class to expand, so the following base class is first defined:
//
//
//
// Multi-threaded analog timer
// Due to the window AtiCVX control, Timer cannot be used directly, and in order to ensure the accuracy and accuracy of the timed, it is used.
// No window can also use time to use Timer by callback procedure but accuracy cannot be guaranteed, so discharge
//
Template
Class CTimer
{
PUBLIC:
CTimer ()
{
m_btimeron = false;
}
HRESULT TIMERON (DWORD DWTIMERINTERVAL)
{
Derived * pderived = ((Derived *) this); m_dwtimerinterval = dwtimerinterVal;
If (m_btimeron) // is already started, just adjust the time division
Return S_OK;
m_btimeron = true;
m_dwtimerinterval = dwtiminterinterval;
m_pstream = NULL;
HRESULT HRES;
// Interface Collection
HRES = ComarshalinterthreadInterfaceInstream (* PIID, (T *) Pderived, & M_PStream);
// Create a thread and pass the THIS pointer
M_Hthread = CreateThread (NULL, 0, & _APARTMENT, (VOID *), 0, & M_DWTHREADID;
Return S_OK;
}
Void Timeroff ()
{
IF (m_btimer)
{
m_btimeron = false;
AtlwaitwithMessageloop (M_HTHREAD);
}
}
// Implement function
Private:
Static DWORD WINAPI _APARTMENT (Void * PV)
{
CTimer
PTHIS-> APARTMENT ();
Return 0;
}
DWORD APARTMENT ()
{
Coinitialize (NULL);
HRESULT HRES;
m_spt.release ();
// Interface Decades
IF (m_pstream)
HRES = COGETINTERFACEANDRELEASSTREAM (M_PSTREAM, * PIID, VOID **) & m_SPT);
While (m_btimeron)
{
Sleep (m_dwtiminterinter);
IF (! m_btimer)
Break;
m_spt-> turnter ();
}
m_spt.release ();
Couninitialize ();
Return 0;
}
// Attributes
PUBLIC:
DWORD M_DWTIMERINTERVAL;
// Implement attribute
Private:
Handle M_HTHREAD;
DWORD M_DWTHREADID;
LPSTREAM M_PSTREAM;
CComptr
Bool m_btimeron;
}
As can be seen from the base class, the ONTIMER interface function of the subclass is called when the thread function is timed. This way we can get the Timer call from the CTimer and define the ONTIMER interface in the subclass interface, and implement the interface function, and Timer is used to start and specify the time division, while Timeroff is used to turn off the timer . The code of the subclass is as follows:
//
// Class: CMYControl
// Function: Example ActiveX Control Implementation
//
Class ATL_NO_VTABLE CMYCONTROL:
// ... Other interfaces
/ / Analog timer support
Public Ctimer
{
PUBLIC:
STDMETHOD (ONTIMER) (VOID);
}
// Implement
StdMethodimp ccfuelwatchobj :: Ontimer (void)
{
/ / Time response code
}
Disclaimer: Method 2 Refer to the relevant information in MSDN. Postscript: In fact, there are many ways to use the timer in the ActiveX control, and there are only two kinds here. I originally thought that the function of using the timer in ATL is described in detail, but due to the interruption of the interruption, now Siyuan is exhausted, can only write these Le, if this article is for the first time to contact the ATL ActiveX control programming friends, then I am very grateful.