ATL-based ActiveX COM objects (including Automation objects
and ActiveX controls) typically fire events from the same thread in which they
were created.
Sometimes it is desirable to start secondary threads in
the COM object that fire events to the container. ATLCPImplMT.h provides an
enhanced implementation of the ATL
IConnectionPointImpl class,
IConnectionPointImplMT, that provides this capability.
Because
IConnectionPointImplMT uses the Global Interface Table, it requires Windows NT 4.0
Service Pack 3 or later, or Windows 95 (or later) with DCOM version 1.1 or
later.
The
following file is available for download from the Microsoft Download
Center:
Collapse this imageExpand this image
Download the ATLCPImplMT.exe package now.
(http://download.microsoft.com/download/a/5/5/a552e657-1ecb-453d-9bae-17d0db333337/atlcpimplmt.exe)
Release Date: Apr-26-2001
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
(http://support.microsoft.com/kb/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.
The ATLCPImplMT.EXE (or ATLCPImplMT.hqx) file contains
the following files:
Collapse this tableExpand this table
Using ATLCPImplMT.h in Your ATL Project
Notes- The following steps must be performed on files containing
implementations of proxy classes generated through the Implement Connection
Point Wizard. These classes are named CProxy{EventInterfaceName} by convention, and your ATL COM class would derive
from them. For additional information, see the following Microsoft Web page:
- Because the Connection Point Wizard overwrites the
generated proxy classes every time it is invoked, these steps must be repeated
at that point.
- Copy the file ATLCPImplMT.h to your project
folder.
- Add the following #include statement near the top of the
wizard-generated files:
- Derive the proxy class, CProxy{EventInterfaceName}, from IConnectionPointImplMT, instead of IConnectionPointImpl. IConnectionPointImplMT has the same set of parameters. For example:
- If you are using Visual Studio 6.0, use the following code:
// Derive from IConnectionPointImplMT, instead of IConnectionPointImpl:
// template <class T>
// class CProxy_IEvntFirerEvents : public IConnectionPointImpl<T, &DIID__IEvntFirerEvents, CComDynamicUnkArray>
template <class T>
class CProxy_IEvntFirerEvents : public IConnectionPointImplMT<T, &DIID__IEvntFirerEvents, CComDynamicUnkArray>
- If you are using Visual Studio .NET, use the following code:
// Derive from IConnectionPointImplMT, instead of IConnectionPointImpl:
// template<class T>
// class CProxy_IEvntFirerEvents : public IConnectionPointImpl<T, &__uuidof(_IEvntFirerEvents), CComDynamicUnkArray>
template <class T>
class CProxy_NicEvents : public IConnectionPointImplMT<T, &__uuidof(_IEvntFirerEvents), CComDynamicUnkArray>
- For each generated function (named Fire_{EventName}) within the proxy class: Comment out the following
lines within the generated for loop:
- If you are using Visual Studio 6.0, use the following code:
// pT->Lock();
// CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
// pT->Unlock();
Insert the following lines in their place:
CComPtr<IUnknown> sp;
sp.Attach (GetInterfaceAt(nConnectionIndex));
- If you are using Visual Studio .NET, use the following code:
// pT->Lock();
// CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
// pT->Unlock();
Insert the following lines in their place: CComPtr<IUnknown> punkConnection;
punkConnection.Attach (GetInterfaceAt(iConnection));
- The Fire_{EventName} functions can now be called from any other COM
thread (in the same apartment, or a different apartment) that has access to the
object in question.
Procedure to Use ATLCPImplMT.h in a sample project
- Follow Steps 1 through 7 in the "Steps to Create an
ATL Project with Visual C++" section in the following Microsoft Knowledge Base
article:
196026
(http://support.microsoft.com/kb/196026/
)
PRB: Firing event in second Thread
causes IPF or GPF
- Add the following code to the MyAtl.cpp file. In the code
below, the event is being fired through the worker thread in the multi-threaded
apartment (MTA), not through the thread in the main single-threaded apartment
(STA):
DWORD WINAPI justDoIt(LPVOID lpParameter)
{
// Initialize COM,
// MTA worker thread:
HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
CMyAtl *myAtl = (CMyAtl*)lpParameter;
long result;
for (int i = 1; i <= myAtl->m_number; ++i)
result = i * 2;
myAtl->Fire_TaskFinished(result);
::CoUninitialize ();
return 0;
}
- Follow steps 9 and 10 in the "Steps to Create an
ATL Project with Visual C++" section in article Q196026.
- Follow the steps outlined in this article in the "Using ATLCPImplMT.h Within Your ATL Project" section to add support for IConnectionPointImplMT.
- Build the ATL project, and the control will be registered
automatically.
- Follow the steps outlined under the "Steps to
Create the Visual Basic 6.0 Project" heading in article Q196026. Notice that when you
click the CommandButton, unlike in article Q196026, the event firing works
correctly.
For additional information, click the following article numbers to view the articles in the Microsoft Knowledge Base:
157437
(http://support.microsoft.com/kb/157437/
)
Fireev.exe fires events from a
second thread
196026
(http://support.microsoft.com/kb/196026/
)
PRB: Event in second thread causes IPF or GPF