Lesson 1
Using ATL to build in-process COM Server
The "Active Template Library (ATL)" provides a streamlined way to create "COM components" in C++.
To build an
in-process COM server using ATL, follow these steps:
Step 1: Set Up a New ATL COM Project
-
Open Visual Studio and create a new ATL Project:
- Select File → New → Project.
- Choose ATL Project.
- Name the project and specify a location.
- Click Create.
-
Configure ATL project settings:
- In the ATL Project Wizard, select Dynamic Link Library (DLL).
- Enable Support COM+ 1.0 (optional).
- Click Finish.
Step 2: Add a COM Object
- Right-click on the project in Solution Explorer.
- Select Add → Class.
- Choose ATL Simple Object.
-
Provide:
- Short Name (e.g.,
MyComObject
).
- Class Name:
CMyComObject
.
- Interface Name:
IMyComObject
.
- Click Finish.
Step 3: Implement the COM Interface
1. Modify the interface in the IDL file (`MyComObject.idl`):
[
object,
uuid(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX), // Generate a unique GUID
dual,
nonextensible,
pointer_default(unique)
]
interface IMyComObject : IDispatch
{
HRESULT MyMethod([out, retval] BSTR* result);
};
[
uuid(YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY), // Generate another unique GUID
version(1.0),
helpstring("My COM Server 1.0 Type Library")
]
library MyComServerLib
{
importlib("stdole32.tlb");
[
uuid(ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ) // Generate a new GUID
]
coclass MyComObject
{
[default] interface IMyComObject;
};
};
Implement the COM method in `MyComObject.h`:
class ATL_NO_VTABLE CMyComObject :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyComObject, &CLSID_MyComObject>,
public IDispatchImpl<IMyComObject, &IID_IMyComObject, &LIBID_MyComServerLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
CMyComObject() {}
DECLARE_REGISTRY_RESOURCEID(IDR_MYCOMOBJECT)
BEGIN_COM_MAP(CMyComObject)
COM_INTERFACE_ENTRY(IMyComObject)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
STDMETHOD(MyMethod)(BSTR* result)
{
if (!result) return E_POINTER;
*result = SysAllocString(L"Hello from ATL COM!");
return S_OK;
}
};
Step 4: Register the COM Server
- Build the project.
- Open the Developer Command Prompt as Administrator.
- Navigate to the output directory (where
MyComServer.dll
is located).
- Run:
regsvr32 MyComServer.dll
Step 5: Use the COM Object in a Client Application
Here’s how a client (e.g., a C++ application) can use the COM object:
#include <windows.h>
#include <atlbase.h>
#include <atlcomcli.h>
#include "MyComObject.h" // Generated header file
int main()
{
CoInitialize(NULL); // Initialize COM
CComPtr<IMyComObject> spMyCom;
HRESULT hr = spMyCom.CoCreateInstance(__uuidof(MyComObject));
if (SUCCEEDED(hr))
{
CComBSTR result;
if (SUCCEEDED(spMyCom->MyMethod(&result)))
{
wprintf(L"COM Method Result: %s\n", result);
}
}
CoUninitialize(); // Uninitialize COM
return 0;
}
Step 6: Unregister the COM Server (If Needed)
To unregister the DLL:
regsvr32 /u MyComServer.dll
Summary
- Used ATL to create an in-process COM server (
DLL
).
- Implemented a COM interface using ATL macros and structures.
- Registered the DLL using
regsvr32
.
- Used the COM object in a C++ client application.
Development Frameworks
Most of our time has been spent studying COM's core concepts. We are now moving towards a study of standard COM implementation practices. Most, if not all, COM developers use a development framework to support their development efforts. The most popular C++-based development frameworks are the Microsoft Foundation Classes (MFC) and the Active Template Library (ATL). ATL is the focus of our study. A development framework differs from a class library in that it defines the structure of an application or component. Developers add code by "hooking" the framework. In ATL this means that you provide an application-specific class that derives from classes in the framework,
and override virtual functions from the base classes. When the framework code calls these functions, the call is directed into your code.
Additionally, ATL requires specific data structures at the global and class levels. ATL makes it very easy to add these structures via a set of high-level macros. Visual C++ provides code-generators for ATL - an "App-Wizard" and an ATL-class tool. Using these a skeleton COM server and COM object can be created. You can simply fill in the methods generated by the tools. This allows you to concentrate on the details of developing application code, instead of worrying about all the COM and ATL code.
However, I highly recommend that you take the time to understand and differentiate between what the tools do and what ATL does.
In other words, analyze the code generated by the tools, try to develop a basic understanding of ATL's core classes and how they support COM.
I believe that these efforts will really pay-off when you need to customize and deploy advanced ATL-based COM solutions.
In modules 2 and 3, we studied core COM and implementation practice concepts. This module discusses how to use the active template library (ATL) to build an in-process server containing a COM object with two interfaces.
At the end of the module, you will be able to:
- Describe the role of the ATL framework
- Explain what ATL's core classes do
- Use the ATL COM-Wizard to generate an in-process COM server
- Add your own COM implementation classes into the ATL framework
- Add COM properties and methods into your COM objects
ATL is designed to simplify the process of creating efficient, flexible, lightweight controls. This module leads you through the creation of an ActiveX control, demonstrating many ATL and COM fundamentals.
COM Server

