Step 2: Set up the Registration File

To register an object built with the framework, you use a generated registration (.rgs) file.

The framework includes a set of macros to allow easy access and modification to the registry keys. The registration macros were designed to be used on .rgs files that have been modified with the associated macro variables.

The CComDesignerBase class and all derived classes take a pointer to an array of REGENTRY structures. At registration time, the framework's registration mechanism accesses these REGENTRY structures to update the designer registration information. The REGENTRY structures provide a readable way to store registration data and a simple way to modify that data.

The registration macros enable you to specify the following:

The macros wrap around a static REGENTRY array that is accessed by the ATL registration mechanism at registration time. The REGENTRY macros and the REGENTRY array constitute a registration map that supplies designer registration information.

Registration Map

The registration map is defined in the implementation file of the designer class; because it is static, putting it in a header file would result in multiple definitions. You must use the DECLARE_REGISTRATION_MAP() macro to forward-declare it, and pass it as a template parameter to the CComDesignerBase class, as in the following example:

DECLARE_REGISTRATION_MAP(RegEntryArray)
class(CShapesDsr)
CComDesignerBase(CShapesDsr,RegEntryArray)
{
…
};

Use the BEGIN_DESIGNER_REGISTRATION_MAP and END_DESIGNER_REGISTRATION_MAP macros at the beginning and end of the map. Within the map, specify the individual macros that supply the ActiveX designer features and registration criteria your designer requires. See Registration Macros for descriptions of the individual macros.

The following is a sample registration map:

//=======================================================
// Designer registration map : this map sets registration
// keys in the .rgs file of this object.
//=======================================================

BEGIN_DESIGNER_REGISTRATION_MAP(CShapesDsr,RegEntryArray) 
   REQUIRED_DESIGNERFEATURES_ENTRY(DESIGNERFEATURE_CANBEPUBLIC)
   REQUIRED_DESIGNERFEATURES_ENTRY(DESIGNERFEATURE_CANCREATE)
   REQUIRED_DESIGNERFEATURES_ENTRY(DESIGNERFEATURE_NOTIFYBEFORERUN)
   REQUIRED_DESIGNERFEATURES_ENTRY(DESIGNERFEATURE_NOTIFYAFTERRUN)
   REQUIRED_DESIGNERFEATURES_ENTRY(DESIGNERFEATURE_STARTUPINFO)
   REQUIRED_DESIGNERFEATURES_ENTRY(DESIGNERFEATURE_REGISTRATION)
   MISCSTATUS_ENTRY(OLEMISC_SETCLIENTSITEFIRST)
   MISCSTATUS_ENTRY(OLEMISC_ACTIVATEWHENVISIBLE)
   MISCSTATUS_ENTRY(OLEMISC_RECOMPOSEONRESIZE)
   MISCSTATUS_ENTRY(OLEMISC_CANTLINKINSIDE)
   MISCSTATUS_ENTRY(OLEMISC_INSIDEOUT)
   MISCSTATUS_ENTRY(OLEMISC_INVISIBLEATRUNTIME)
   TOOLBOXITEMCT_ENTRY(3)
   TOOLBOXSTARTID_ENTRY(301)
   TOOLBOXNAMEID_ENTRY(IDS_TOOLBOXSET)
   INSTANCECLSID_ENTRY(&CLSID_ShapesInstCtl)
   TYPELIBID_ENTRY(&LIBID_SHAPESLIBLib)
END_DESIGNER_REGISTRATION_MAP()   

Contents of the Registration (.RGS) File

The default contents of the .RGS file have to be modified to work with the registration macros. For every macro you use, you must create an appropriate .RGS file substitution macro (otherwise, you might get an exception at registration time). The following example shows the partial contents of an .RGS file that uses substitution macros :

ForceRemove {E67C7A0A-B7A7-11D1-B091-006008BDB845} = s 'ShapesDsr Class'
      {
         ProgID = s 'ShapesDsr.ShapesDsr.1'
         VersionIndependentProgID = s ShapesDsr.ShapesDsr'
         ForceRemove 'Programmable'
         ForceRemove 'DesignerFeatures'
         {
            val Required = d '%REQUIREDDESIGNERFEATURES%'
            val Optional = d ‘%OPTIONALDESIGNERFEATURES%’
         }
         ForceRemove 'DesignerToolbox'
         {
            val ItemCount = d '%ITEMCT%'
            val ItemStartID = d '%STARTID%'
            val NameID = d '%NAMEID%'
            val ResourcePath = s '%MODULE%'
         }
         ForceRemove 'Implemented Categories'
         {
            {4EB304D0-7555-11CF-A0C2-00AA0062BE57}
         }
         InprocServer32 = s '%MODULE%'
         {
            val ThreadingModel = s 'Apartment'
         }
         'Instance CLSID' = s '%INSTANCECLSID%'
         ForceRemove 'Control'
         ForceRemove 'Programmable'
         ForceRemove 'Insertable'
         ForceRemove 'ToolboxBitmap32' = s '%MODULE%, 1'
         'MiscStatus' = s '0'
         {
             '1' = s '%MISCSTATUS%'
         }
         'TypeLib' = s '%TYPELIBID%'
         'Version' = s '1.0'
      }

Registry Update Macro

To use the registration features provided by CComDesignerBase, your derived designer class must override the CComDesignerBase::UpdateRegistry method.

The REGISTER_DESIGNER_FEATURES() macro provides an implementation of UpdateRegistry() that calls the CComDesignerBase::UpdateDesignerFeatures() method. UpdateDesignerFeatures gathers registration information from the REGENTRY map and uses this information to populate the registry.