Compartir a través de


[Sample of Apr 2nd] Creating an in-process ATL COM Server

 

Homepage image
Sample of the Day RSS Feed

Sample Download: https://code.msdn.microsoft.com/ATLDllCOMServer-09df00e4

Today’s code sample demonstrate how to use Active Template Library (ATL) wizards in Visual Studio 2010 to create an in-process COM server.

imageYou can find more code samples that demonstrate the most typical programming scenarios by using Microsoft All-In-One Code Framework Sample Browser or Sample Browser Visual Studio extension. They give you the flexibility to search samples, download samples on demand, manage the downloaded samples in a centralized place, and automatically be notified about sample updates. If it is the first time that you hear about Microsoft All-In-One Code Framework, please watch the introduction video on Microsoft Showcase, or read the introduction on our homepage https://1code.codeplex.com/.

 

Introduction

The ATLDllCOMServer sample demonstrates how to use Acitve Template Library (ATL) wizards in Visual Studio 2008 to generate an in-process COM server. ATL is designed to simplify the process of creating efficient, flexible, lightweight COM components. ATLDllCOMServer exposes an ATL STA simple object with properties, methods, and events:

  Program ID: ATLDllCOMServer.SimpleObject

  CLSID_SimpleObject: 92FCF37F-F6C7-4F8A-AA09-1A14BA118084

  IID_ISimpleObject: 830F85D0-91B9-406D-A273-BC33133DD44B

  DIID__ISimpleObjectEvents: 87AD6FBC-8735-407C-9758-C80B48C78E7C

  LIBID_ATLDllCOMServerLib: 9B23EFED-A0C1-46B6-A903-218206447F3E

  AppID: 9DD18FED-55F6-4741-AF25-798B90C4AED5

 

Using the code 

The component exposes the following properties, methods and events:

 // With both get and put accessor methods 
FLOAT FloatProperty  
 // HelloWorld returns a BSTR "HelloWorld" 
HRESULT HelloWorld([out,retval] BSTR* pRet); 
// GetProcessThreadID outputs the running process ID and thread ID 
HRESULT GetProcessThreadID([out] LONG* pdwProcessId, [out] LONG* pdwThreadId); 
 // FloatPropertyChanging is fired before new value is set to the  
// FloatProperty property. The [in, out] parameter Cancel allows the  
// client to cancel the change of FloatProperty. 
void FloatPropertyChanging( 
  [in] FLOAT NewValue, [in, out] VARIANT_BOOL* Cancel); 

The majority of codes in the sample are generated by Visual Studio. You can find the detailed steps of creating such a COM server in the Creation section of this document.

Build:

To build ATLDllCOMServer, please run Visual Studio as administrator because  the component needs to be registered into HKCR.

Deployment:

A. Setup

Regsvr32.exe ATLDllCOMServer.dll

B. Cleanup

Regsvr32.exe /u ATLDllCOMServer.dll 

 

To Create the Project

A. Creating the project

Step1. Create a Visual C++ / ATL / ATL Project named ATLDllCOMServer in Visual Studio 2008.

Step2. In the page "Application Settings" of ATL Project Wizard, select the server type as Dynamic-link library (DLL), and allow merging of proxy/stub code.

B. Adding an ATL Simple Object

Step1. In Solution Explorer, add a new ATL / ATL Simple Object class to the project.

Step2. In ATL Simple Object Wizard, specify the short name as SimpleObject, and select the threading model as Apartment (corresponding to STA), select Interface as Dual that supports both IDispatch (late binding) and vtable binding (early binding). Last, select the Connection points check box. This creates the _ISimpleObjectEvents interface in the file ATLDllCOMServer.idl. The Connection points option is the prerequisite for the component to supporting events.

C. Adding Properties to the ATL Simple Object

Step1. In Class View, find the interface ISimpleObject. Right-click it and select Add / Add Property in the menu.

Step2. In the Add Property Wizard, specify the property type as FLOAT and set the property name as FloatProperty. Select both Get function and Put function. SimpleObject therefore exposes FloatProperty with the get&put accessormethods: get_FloatProperty, put_FloatProperty.

Step3. Add a float field, m_fField, to the class CSimpleObject:

 protected: 
    // Used by FloatProperty 
    float m_fField; 

Implement the get&put accessor methods of FloatProperty to access m_fField

 STDMETHODIMP CSimpleObject::get_FloatProperty(FLOAT* pVal) 
{ 
    *pVal = m_fField; 
    return S_OK; 
} 
 
 
STDMETHODIMP CSimpleObject::put_FloatProperty(FLOAT newVal) 
{ 
    m_fField = newVal; 
    return S_OK; 
} 

D. Adding Methods to the ATL Simple Object

Step1. In Class View, find the interface ISimpleObject. Right-click it and select Add / Add Method on the shortcut menu.

Step2. In the Add Method Wizard, specify the method name as HelloWorld. Add a parameter whose parameter attributes = retval, parameter type = BSTR*, and parameter name = pRet.

Step3. Write the body of HelloWorld as this:

 STDMETHODIMP CSimpleObject::HelloWorld(BSTR* pRet) 
{ 
    // Allocate memory for the string:  
    *pRet = ::SysAllocString(L"HelloWorld"); 
    if (pRet == NULL) 
        return E_OUTOFMEMORY; 
 
 
    // The client is now responsible for freeing pbstr 
    return S_OK; 
} 

With the almost same steps, the method GetProcessThreadID is added to get the executing process ID and thread ID.

HRESULT GetProcessThreadID([out] LONG* pdwProcessId, [out] LONG* pdwThreadId);

E. Adding Events to the ATL Simple Object

The Connection points option in B/Step2 is the prerequisite for the component to supporting events.

Step1. In Class View, expand ATLDllCOMServer / ATLDllCOMServerLib to display _ISimpleObjectEvents.

Step2. Right-click _ISimpleObjectEvents. On the shortcut menu, click Add, and then click Add Method.

Step3. Select a Return Type of void, enter FloatPropertyChanging in the Method name box, and add an [in] parameter FLOAT NewValue, and an [in, out]  parameter VARIANT_BOOL* Cancel. After clicking Finish, _ISimpleObjectEvents dispinterface in the ATLDllCOMServer.idl file should look like this:

 dispinterface _ISimpleObjectEvents 
{ 
    properties: 
    methods: 
        [id(1), helpstring("method FloatPropertyChanging")] void  
        FloatPropertyChanging( 
        [in] FLOAT NewValue, [in,out] VARIANT_BOOL* Cancel); 
}; 
 

Step4. Generate the type library by rebuilding the project or by right-clicking the ATLDllCOMServer.idl file in Solution Explorer and clicking Compile on the shortcut menu. Please note: We must compile the IDL file BEFORE setting up a connection point.

Step5. Use the Implement Connection Point Wizard to implement the Connection Point interface: In Class View, right-click the component's implementation class CSimpleObject. On the shortcut menu, click Add, and then click Add Connection Point. Select _ISimpleObjectEvents from the Source Interfaces list and double-click it to add it to the Implement connection points column. Click Finish. A proxy class for the connection point will be generated (ie. CProxy_ISimpleObjectEvents in this example) in the file _ISimpleObjectEvents_CP.h. This also creates a function with the name Fire_[eventname] that can be called to raise events in the client.

Step6. Fire the event in put_FloatProperty:

 STDMETHODIMP CSimpleObject::put_FloatProperty(FLOAT newVal) 
{ 
    // Fire the event, FloatPropertyChanging 
    VARIANT_BOOL cancel = VARIANT_FALSE;  
    Fire_FloatPropertyChanging(newVal, &cancel); 
 
 
    if (cancel == VARIANT_FALSE) 
    { 
        m_fField = newVal;    // Save the new value 
    } // else, do nothing 
    return S_OK; 
} 
  

 

More Information

ATL Tutorial

An ATL Component in C++ that fires COM events By Neville Dastur

KB: AtlEvnt.exe sample shows how to creates ATL sinks by using the ATL IDispEventImpl and IDispEventSimpleImpl classes

KB: How to develop an in-process COM component