The document is archived and information here might be outdated


Creates a COM object, which can implement a COM interface.


The coclass C++ attribute places a coclass construct in the generated .idl file.

When defining a coclass, you can also specify the uuid, version, threading, vi_progid, and progid attributes. If any one of them is not specified, it will be generated.

If two header files contain classes with the coclass attribute and don't specify a GUID, the compiler will use the same GUID for both classes, and that will result in a MIDL error. Therefore, you should use the uuid attribute when you use coclass.

ATL Projects

When this attribute precedes a class or structure definition in an ATL project, it:

  • Injects code or data to support auto registration for the object.

  • Injects code or data to support a COM class factory for the object.

  • Injects code or data to implement IUnknown and make the object a COM-creatable object.

Specifically, the following base classes are added to the target object:

Finally, any dual interface that is not defined using embedded IDL is replaced with the corresponding IDispatchImpl class. If the dual interface is defined in embedded IDL, the particular interface in the base list is not modified.

The coclass attribute also makes the following functions available via injected code, or in the case of GetObjectCLSID, as a static method in the base class CComCoClass:

  • UpdateRegistry registers the class factories of the target class.

  • GetObjectCLSID, which is related to registration, can also be used to obtain the CLSID of the target class.

  • GetObjectFriendlyName by default returns a string of the format "<target class name> Object". If this function is already present, it is not added. Add this function to the target class to return a friendlier name than the one automatically generated.

  • GetProgID, which is related to registration, returns the string specified with the progid attribute.

  • GetVersionIndependentProgID has the same functionality as GetProgID, but it returns the string specified with vi_progid.

The following changes, which are related to the COM map, are made to the target class:

  • A COM map is added with entries for all interfaces the target class derives from and all entries specified by the COM Interface Entry Points attribute or those required by the aggregates attribute.

  • An OBJECT_ENTRY_AUTO macro is inserted into the COM map. This macro is similar to OBJECT_ENTRY in terms of functionality but does not need to be part of the COM map of the target class.

The name of the coclass generated in the .idl file for the class will have the same name as the class. For example, and referring to the following sample, to access the class ID for a coclass CMyClass, in a client through the MIDL-generated header file, use CLSID_CMyClass.

The following code shows how to use the coclass attribute:

// cpp_attr_ref_coclass1.cpp
// compile with: /LD
#include "unknwn.h"

[ object, uuid("00000000-0000-0000-0000-000000000001") ]
__interface I {
   HRESULT func();

[coclass, progid("MyCoClass.coclass.1"), vi_progid("MyCoClass.coclass"), 
appobject, uuid("9E66A294-4365-11D2-A997-00C04FA37DDB")]
class CMyClass : public I {};

The following sample shows how to override the default implementation of a function that appears in the code injected by the coclass attribute. See /Fx for more information on viewing injected code. Any base classes or interfaces that you use for a class will be appear in the injected code.   Further, if a class is included by default in the injected code and you explicitly specify that class as a base for your coclass, the attribute provider will use the form specified in your code.

// cpp_attr_ref_coclass2.cpp
// compile with: /LD
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include <atltypes.h>
#include <atlctl.h>
#include <atlhost.h>
#include <atlplus.h>


[object, uuid("00000000-0000-0000-0000-000000000000")]
__interface bb {};

[coclass, uuid("00000000-0000-0000-0000-000000000001")]
class CMyClass : public bb {
   // by adding the definition of UpdateRegistry to your code, 
   // the function will not be included in the injected code
   static HRESULT WINAPI UpdateRegistry(BOOL bRegister) {
      // you can add to the default implementation
      CRegistryVirtualMachine rvm;
      HRESULT hr;
      if (FAILED(hr = rvm.AddStandardReplacements()))
         return hr;
      rvm.AddReplacement(_T("FriendlyName"), GetObjectFriendlyName());
      return rvm.VMUpdateRegistry(GetOpCodes(), GetOpcodeStringVals(),
         GetOpcodeDWORDVals(), GetOpcodeBinaryVals(), bRegister);

Attribute Context

Applies to

class, struct



Required attributes


Invalid attributes


For more information about the attribute contexts, see Attribute Contexts.

© 2016 Microsoft