In addition to exposing properties to their containers, ActiveX controls can also talk to the container to get information about the environment in which they're operating. These properties, which are held and exposed by the container, are called ambient properties. Let's look at how the ambient properties mechanism works.
When the container creates a control, the container and the control exchange interfaces. For example, let's say the control implements an interface named IOleControl and the container implements an interface named IOleControlSite. The container uses IOleControl to talk to the control, and the control uses IOleControlSite to talk to the container. In addition to the standard OLE Document/OLE control interfaces, a container might implement a version of IDispatch, which exposes the ambient properties to the control.
Here's an example of how the control might use the container's ambient properties. Imagine that you want to make sure your control fits in perfectly with the container. To do that, you need to make sure the control's fill color matches the background of the container. One of the container's ambient properties is its background color. Your control would simply fetch the property from the container and use that as its fill color.
Of course, when you're developing the control, you don't want to deal with the container's ambient properties dispatch interface. (As a developer, you don't want to perform all the work involved in setting up calls to IDispatch::Invoke.) Fortunately, ATL provides two easy ways to access a container's ambient properties from a control. The first way is to call CComControlBase::GetAmbientProperty. Here's the function signature:
HRESULT GetAmbientProperty(DISPID dispid, VARIANT& var) |
GetAmbientProperty takes as its arguments the DISPID of the property you want to retrieve and a VARIANT in which to place the property. GetAmbientProperty does all the work of setting up and calling Invoke for you.
The second way is to use one of the wrapper functions that ATL conveniently implements for retrieving the various ambient properties. For example, if you want to get the container's background color, you could either call GetAmbientProperty and pass in DISPID_AMBIENT_BACKCOLOR as the dispatch ID or call GetAmbientBackColor. The advantage of using the wrapper functions is that they unpack the variants for you.
Table 10-2 illustrates the container's ambient properties you can access with ATL's CComControlBase class.
Table 10-2. ATL's Ambient Property Support.
Ambient Property | DISPID | Type | Accessor Function |
---|---|---|---|
Appearance | DISPID_AMBIENT- _APPEARANCE | Short | GetAmbientAppearance |
Background Color | DISPID_AMBIENT- _BACKCOLOR | OLE_COLOR | GetAmbientBackColor |
Display Name | DISPID_AMBIENT- _DISPLAYNAME | BSTR | GetAmbientDisplayName |
Font | DISPID_AMBIENT_FONT | IFont* | GetAmbientFont |
Font (dispatch version) | DISPID_AMBIENT_FONT | IFontDisp* | GetAmbientFontDisp |
Foreground Color | DISPID_AMBIENT- _FORECOLOR | OLE- _COLOR | GetAmbientForeColor |
Locality | DISPID_AMBIENT- _LOCALEID | LCID | GetAmbientLocaleID |
Scale Units | DISPID_AMBIENT- _SCALEUNITS | BSTR | GetAmbientScaleUnits |
Text Alignment | DISPID_AMBIENT- _TEXTALIGNMENT | short | GetAmbientTextAlign |
User Mode | DISPID_AMBIENT- _USERMODE | BOOL | GetAmbientUserMode |
UI Dead | DISPID_AMBIENT- _UIDEAD | BOOL | GetAmbientUIDead |
Show Grab Handles | DISPID_AMBIENT- _SHOWGRABHANDLES | BOOL | GetAmbientShowGrabHandles |
Show Hatching | DISPID_AMBIENT- _SHOWHATCHING | BOOL | GetAmbientShowHatching |
Message Reflection | DISPID_AMBIENT- _MESSAGEREFLECT | BOOL | GetAmbientMessageReflect |
Auto Clip | DISPID_AMBIENT- _AUTOCLIP | BOOL | GetAmbientAutoClip |
Display as Default | DISPID_AMBIENT- _DISPLAYASDEFAULT | BOOL | GetAmbientDisplayAsDefault |
Support Mnemonics | DISPID_AMBIENT- _SUPPORTSMNEMONICS | BOOL | GetAmbientSupportsMnemonics |
Palette | DISPID_AMBIENT- _PALETTE | BOOL | GetAmbientPalette |