Palette Management for ActiveX ObjectsPalette Management for ActiveX Objects*
*Contents  *Index  *Topic Contents
*Previous Topic: Packaging ActiveX Controls
*Next Topic: Registering an ActiveX Object as the Player for a Media Type

Palette Management for ActiveX Objects

This document describes palette management for ActiveX objects, specifically ActiveX Controls and Active Document Objects. The palette management rules described herein allow multiple controls inside a form or an HTML page to display correctly, while still leaving enough flexibility to allow a control to demand palette control. In general, containers are responsible for palette management, and contained objects (for example, controls) should only realize their palettes in the background.

arrowg.gifPalette Management for ActiveX Controls and Containers

arrowg.gifPalette Management for Active Document Objects

Palette Management for ActiveX Controls and Containers

This section describes how ActiveX controls and containers should manage the palette.

Palette selection

Because there may be more than one control on a page or form, it is up to the container to choose a common palette, and every control should realize its palette in the background. Anything else would result in chaos as each control realized its palette while painting. The display would flicker madly and most controls would look awful.

Ultimately it is the container's responsibility to choose the common palette. Some containers may use the UI active object's palette; others may compute the palette at run-time.

Ambient palette property

The container makes its palette available to contained controls through an ambient property: DISPID_AMBIENT_PALETTE. This property is defined as part of the OLE Controls 96 specification and is implemented by Microsoft Internet Explorer. Controls can receive the value of this ambient initially by implementing IOleObject::SetClientSite or IObjectWithSite::SetSite, then querying the container client site for IDispatch, and finally calling IDispatch::Invoke on the property to obtain its value. Afterwards, controls can receive notification of changes to this property by implementing: IOleControl::OnAmbientPropertyChange().

Containers should realize the ambient palette before calling this function or IViewObject2::Draw(). Older containers that do not implement this property will typically iterate through their controls, forwarding the WM_QUERYNEWPALETTE message until a control returns TRUE (indicating it has realized a palette). Containers that implement DISPID_AMBIENT_PALETTE should never send WM_QUERYNEWPALETTE to their controls.

Palette change notification

Palette-aware controls that need to be notified of changes to the ambient palette should implement IOleControl::OnAmbientPropertyChange and handle DISPID_AMBIENT_PALETTE and DISPID_UNKNOWN. DISPID_UNKNOWN is sent when the values of more than one ambient property changes. When this happens, controls should explicitly check for a changed palette.

Older containers that do not define an ambient palette will send WM_PALETTECHANGED messages. Controls are encouraged to handle this message as well.

Note that controls can still realize a different palette (in the background). The ambient palette property is useful only if a control needs to optimize its display to the palette of the container. If this is not necessary, the control should ignore the ambient palette property.

IViewObject2::GetColorSet

All palette-aware controls should implement IViewObject2::GetColorSet if they want to specify a palette preference. Containers can use the return value to determine if a control is palette-aware. Containers can also use the color information returned to choose what palette to realize.
E_NOTIMPL The control is not palette-aware.
S_FALSE The control is palette-aware but does not have a palette at this time.
S_OK The control is palette-aware and has returned its palette to the container.

It should be noted that the container does not have to call IViewObject2::GetColorSet. The container can determine its palette independently of its controls.

Realizing the palette

Older OLE guidelines allowed the UI active object to realize its own palette in the foreground. Revised guidelines disallow this practice.

Controls should realize their palette in the foreground only when receiving a WM_QUERYNEWPALETTE message. In every other situation, the control must realize its palette in the background. Containers that implement DISPID_AMBIENT_PALETTE will never send this message.

Summary:

Palette Management for Active Document Objects

The following sections describe issues related to palette management by OLE Document Objects. In general, the palette management scheme for document objects is the same as the scheme used for controls, except that document objects do not receive ambient properties from their container.

Responsibilities of the document object

Palette management for document objects is similar to palette management for controls. The following are the responsibilities of the document object:

The only difference between the responsibilities of controls and document objects is that document objects do not handle the DISPID_AMBIENT_PALETTE property.

Single document case

In the most common cases, a DocObject container will activate only one DocObject at a time. In such a situation, it is acceptable that the activated DocObject should have complete control over the palette, which includes managing palette issues for any controls or content within that document.

The DocObject container in this case has nothing to do with palettes and need not be concerned with palette issues. It should leave palette handling up to the DocObject— in other words, it should forward all Windows® palette management messages on to the DocObject.

The following is example code for the window procedure of the document object host:

case WM_PALETTECHANGED:
case WM_QUERYNEWPALETTE:
{
    HWND hwnd;
    IOleWindow *pOleWindow;
    if (pDocObj && SUCCEEDED(pDocObj->QueryInterface(IID_IOleWindow, 
            (LPVOID*)&pOleWindow))) {
        LRESULT lres = 0;
        if (SUCCEEDED(pOleWindow->GetWindow(&hwnd))) {
            lres = SendMessage(hwnd, uMsg, wParam, lParam);
        }
        pOleWindow->Release();
        return lres;
    }
    break;
}

Multiple DocObject case

In rare cases, a DocObject container may be able to activate more than one DocObject at a time within multiple container frames. While this user interface is discouraged at this time, it can be achieved.

However, no palette-management solution exists for this scenario because there is currently no protocol for communicating palettes between a DocObject and its container. Therefore, the container cannot create a palette suitable to all DocObjects that it has activated.

Because of this, the activated DocObject in the foreground has control over the palette and should use foreground palette rendering. Other activated DocObjects in the background use background palette rendering. The DocObject container itself does not participate in palette management at all.


Up Top of Page
© 1997 Microsoft Corporation. All rights reserved. Terms of Use.