Initializing from HTML
In the same way that you can initialize a Visual Basic ActiveX control, you can initialize an ATL control using the <PARAM> tags. When you include the <PARAM> tags as children of the <OBJECT> tags, Internet Explorer sends the data that you specify to the control when the control is first instantiated. For example, to specify an initial value for the Message property, you can insert a <PARAM> tag between the opening and closing object tags for the control. This HTML code looks like this:
This data is stored in a property bag object maintained by Internet Explorer. Internet Explorer will query the control for the IPersistPropertyBag interface. If the control returns a pointer to this interface, Internet Explorer calls the Load method of IPersistPropertyBag to instruct the control to load initialization data. When calling the Load method, Internet Explorer passes a pointer to IPropertyBag interface of its property bag object. The control then calls the Read method of the passed in IPropertyBag interface to retrieve the initialization data.
To make this work correctly in the AtlCtrl control, you need to follow a few steps. As usual, ATL provides a default implementation of IPersistPropertyBag named IPersistPropertyBagImpl. Add this template class to the end of the inheritance list. After adding the template class, the declaration of CAtlCtrl should look like this:
class ATL_NO_VTABLE CAtlCtrl :
public IPersistPropertyBagImpl<CAtlCtrl>
{
};
Add the IPersistPropertyBag interface to the COM map. After adding this interface, the COM map should look like this:
Implement the Load method, as shown in the next code fragment. You can add this method to the bottom of the class declaration. With Load, you can retrieve the initialization data that you specified on the Web page by using <PARAM> tags.
In the Load method, we first have to declare a variable of CComVariant. The CComVariant variable is similar to CComBSTR in that it's a wrapper class that provides greater functionality than the data type it contains. In this case, a CComVariant wraps a VARIANT type. This variable is needed to retrieve the values of the parameters specified using <PARAM> tags. (If you need more information about CComVariant, refer to MSDN.)
Next we call the Read method of the IPropertyBag interface that was passed into the Load method. The first parameter specifies the name of the property that we want to retrieve. This parameter tacks on the 'L' specifier that converts the ANSI string to an OLE string. Here we're reading the Message property from the property bag. The second parameter is a VARIANT that will contain the value of the Message property when this method returns. The third parameter is a pointer to IErrorLog interface that the Read method uses to report errors. This parameter can be NULL if we're not interested in error information. In this case, we simply pass the pointer to IErrorLog interface that we received from the argument of the Load method.
Then we check the return value of the Read method. If the call to Read succeeded and the type of the VARIANT that was returned is a BSTR (as indicated by vtVal.vt being equal to VT_BSTR), we set the m_bstrMessage data member to the BSTR value that is contained in the vtVal variable. Now, when the OnDraw method is initially called, the value that we specified for the Message property will be displayed on the Web page. In addition to setting the m_bstrMessage data member, we also set the m_fDirty data member to TRUE. The m_fDirty data member indicates that the property has been changed. Here's how m_fDirty is defined in the CAtlCtrl class:
BOOL m_fDirty;
We should also initialize m_fDirty in the CAtlCtrl constructor. The constructor will look like this: