## Palette Management for ActiveX Objects

Note: This document is an early release of the final specification. It is meant to specify and accompany software that is still in development. Some of the information in this documentation may be inaccurate or may not be an accurate representation of the functionality of the final specification or software. Microsoft assumes no responsibility for any damages that might occur either directly or indirectly from these inaccuracies. Microsoft may have trademarks, copyrights, patents or pending patent applications, or other intellectual property rights covering subject matter in this document. The furnishing of this document does not give you a license to these trademarks, copyrights, patents, or other intellectual property rights.

### Introduction

This document describes palette management for ActiveX Objects, specifically ActiveX Controls and ActiveX Document Objects. The palette management rules below allow multiple controls inside a form or in 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 (e.g. controls) should only realize their palettes in the background.

### 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 paleete 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.

How the container chooses the common palette is up to the implementor of the container. Some containers may use the UI active object's palette, others may compute the palette at runtime. Microsoft Internet Explorer 3.0 will either use a default halftone palette, or use the UI active object's palette. This policy may change in future versions of Microsoft Internet Explorer.

#### Ambient palette property

The container should make its palette available as an ambient property: DISPID_AMBIENT_PALETTE. This property is defined in OLE Controls documentation and will be implemented by Microsoft Internet Explorer 3.0 and other Microsoft OLE containers. Controls can receive notification of changes to this property by implementing: IOleControl::OnAmbientPropertyChange()

Containers should realize the ambient palette in the foreground 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).

Newer containers that implement DISPID_AMBIENT_PALETTE should never send WM_QUERYNEWPALETTE to their controls.

#### Palette change notification

Palette aware controls that wish to be notified of changes to the ambient palette should implement IOleControl::OnAmbientPropertyChange() and handle DISPID_AMBIENT_PALETTE and DISPID_UNKNOWN. The DISPID_UNKNOWN change can be sent when more than one property changes. When this happens, controls should explicitly check for a changed palette.

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

Note: controls can still realize a different palette (in the background). The ambient palette property is only useful if a control wishes 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 wish to specify a palette preference. Containers can use the return value to determine if a control is palette aware. Containers may 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 may determine it's palette independently of its controls.

#### Realizing the palette

Current OLE guidelines allow the UI active object to realize its own palette in the foreground. Under the new guidelines, this is no longer the case.

Controls should only realize their palette in the foreground when receiving 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

- Containers determine the palette
- Containers may choose to implement DISPID_AMBIENT_PALETTE
- Containers must realize the ambient palette before calling IViewObject2::Draw() or IOleControl::OnAmbientPropertyChange()
- Controls must always realize their palette in the background. The only exception is when receiving the WM_QUERYNEWPALETTE message.
- Controls should implement IViewObject2::GetColorSet() if they care to tell the container about their palette preferences.
- Controls should implement IOleControl::OnAmbientPropertyChange() if they wish to be notified about changes in the ambient palette property in order to optimize their display to the container's palette.

### Palette Management for ActiveX 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.

#### The 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:

- Document objects should implement IViewObject2::GetColorSet if interested in notifying the container about the palette they wish to display with. This is exactly the same as the corresponding responsibility for Controls (above).
- Document objects should realize their palette in the background unless when handling WM_QUERYNEWPALETTE messages (forwarded from the container). Again, this is exactly the same as the corresponding responsibility for Controls (above).

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

#### Single Documnet Case

In the most common cases, a DocObject container will only activate 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.

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 is still possible to achieve.

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.

© 1996 Microsoft Corporation