17    Uniform Data Transfer

COM provides a standard mechanism for transferring data between applications. This mechanism is the data object, which is simply any COM object that implements the IDataObject() interface. Some data objects, such as a piece of text copied to the clipboard, have IDataObject() as their sole interface. Others, such as compound document objects, expose several interfaces, of which IDataObject() is simply one. Data objects are fundamental to the working of compound documents, although they also have widespread application outside the COM technology.

By exchanging pointers to a data object, providers and consumers of data can manage data transfers in a uniform manner, regardless of the format of the data, the type of medium used to transfer the data, or the target device on which it is to be rendered. You can include support in your application for basic clipboard transfers, drag and drop transfers, and COM compound document transfers with a single implementation of IDataObject(). Having done that, the amount of code required to accommodate the special semantics of each protocol is minimal.

17.1    Data Transfer Interfaces

The IDataObject() interface provides consumers of data with methods for getting and setting an object's data, determining which formats the object supports, and registering for and receiving notifications when data in the object changes. When obtaining data, a caller can specify the format in which it wants to render the data. The source of the data, however, determines the storage medium, which it returns in an out parameter provided by the caller.

By itself, IDataObject() supplies all the tools you need to implement Microsoft® Windows® clipboard transfers or compound document transfers in your applications. If you also want to support drag and drop transfers, you need to implement the IDropSource and IDropTarget interfacesalong with IDataObject().

The IDataObject() interface combined with COM clipboard APIs provide all the capabilities of the Microsoft® Win32® clipboard APIs. Using both the platform's clipboard APIs and COM's is usually redundant and unnecessary. Suppliers of data that support either drag and drop transfers or COM compound documents must implement the IDataObject() interface. If your application supports only clipboard transfers now, but you intend to add drag and drop or compound documents in later releases, you may want to implement IDataObject() and the COM clipboard APIs now in order to minimize the amount of time spent recoding and debugging later. You may also want to implement IDataObject() in order to utilize transfer media other than global memory.

17.2    Data Formats and Transfer Media

Most platforms, including Windows, define a standard protocol for transferring data between applications, based on a set of functions called the clipboard. Applications using these functions can share data even if their native data formats are wildly different. Generally, these clipboards have two significant shortcomings that COM has overcome.

First, data descriptions use only a format identifier, such as the single 16-bit clipboard format identifier on Windows, which means the clipboard can only describe the structure of its data, that is, the ordering of the bits. It can report, ``I have a bitmap'' or ``I have some text,'' but it cannot specify the target devices for which the data is composed, which views or aspects of itself the data can provide, or which storage media are best suited for its transfer. For example, it cannot report, ``I have a string of text that is stored in global memory and formatted for presentation either on screen or on a printer'' or ``I have a thumbnail sketch bitmap rendered for a 100 dpi dot-matrix printer and stored as a disk file.''

Second, all data transfers using the clipboard generally occur through global memory. Using global memory is reasonably efficient for small amounts of data but horribly inefficient for large amounts, such as a 20 MB multimedia object. Global memory is slow for a large data object, whose size requires considerable swapping to virtual memory on disk. In cases where the data being exchanged is going to reside mostly on disk anyway, forcing it through this virtual-memory bottleneck is highly inefficient. A better way would skip global memory entirely and simply transfer the data directly to disk.

To alleviate these problems, COM introduces two new data structures: FORMATETC and STGMEDIUM.

17.2.1    The FORMATETC Structure

The FORMATETC structure is a generalized clipboard format, enhanced to encompass a target device, an aspect or view of the data, and a storage medium. A data consumer, such as a COM container application, passes the FORMATETC structure as an argument in calls to IDataObjectto indicate the type of data it wants from a data source, such as a compound document object. The source uses the FORMATETC structure to describe what formats it can provide. FORMATETC can describe virtually any data, including other objects such as monikers. A container can ask one of its embedded objects to list its data formats by calling IDataObject::EnumFormatetc(), which returns an enumerator object that implements the IEnumFormatEtc interface. Instead of replying merely that it has ``text and a bitmap,'' the object can provide a detailed description of the data, including the device (normally screen or printer) for which it is rendered, the aspect to be presented to the user (full contents, thumbnail, icon, or formatted for printing), and the storage medium containing the data (global memory, disk file, storage object, or stream). This ability to tightly describe data will, in time, result in higher quality printer and screen output as well as more efficiency in data browsing, where a thumbnail sketch is much faster to retrieve and display than a fully detailed rendering.

The following table lists fields of the FORMATETC data structure and the information they specify:

Table 17-1:  FORMATETC Structure Fields

Field Specifies
cfFormat The format in which the data is to be rendered, which can be a standard clipboard format, a proprietary format, or a COM format.
ptd A DVTARGETDEVICE structure, which contains enough information about a Windows target device, such as a screen or printer, so that a handle to its device context (hDC) can be created using the Windows CreateDC function.
dwAspect The aspect or view of the data to be rendered; can be the full contents, a thumbnail sketch, an icon, or formatted for printing.
lindex The part of the aspect that is of interest; for the present, the value must be -1, indicating that the entire view is of interest.
tymed The data's storage medium, which can be global memory, disk file, or an instance of one of COM's structured-storage interfaces.

17.2.2    The STGMEDIUM Structure

Just as the FORMATETC structure is an enhancement of the Windows clipboard format identifier, so the STGMEDIUM structure is an improvement of the global memory handle used to transfer the data. The STGMEDIUM structure includes a flag, tymed, which indicates the medium to be used, and a union comprising pointers and a handle for getting whichever medium is specified in tymed.

The STGMEDIUM structure enables both data sources and consumers to choose the most efficient exchange medium on a per-rendering basis. If the data is so big that it should be kept on disk, the data source can indicate a disk-based medium in its preferred format, only using global memory as a backup if that's the only medium the consumer understands. Being able to use the best medium for exchanges as the default improves overall performance of data exchange between applications. For example, if some of the data to be transferred is already on disk, the source application can move or copy it to a new destination, either in the same application or in some other, without having first to load the data into global memory. At the receiving end, the consumer of the data does not have to write it back to disk.

17.3    Data Notification

Objects that consume data from an external source sometimes need to be informed when data in that source changes. For example, a stock ticker tape viewer that relies on data in some spreadsheet needs to be notified when that data changes so it can update its display. Similarly, a compound document needs information about data changes in its embedded objects so that it can update its data caches. In cases such as this, where dynamic updating of data is desirable, sources of data require some mechanism of notifying data consumers of changes as they occur without obligating the consumers to drop everything in order to update their data. Ideally, having been notified that a change has occurred in the data source, a consuming object can ask for an updated copy at its leisure.

COM's mechanism for handling asynchronous notifications of this type is an object called an advise sink, which is simply any COM object that implements an interface called IAdviseSink(). Consumers of data implement the IAdviseSink(). They register to receive notifications by handing a pointer to the data object of interest.

The IAdviseSink() interfaces exposes the following methods for receiving asynchronous notifications:

Table 17-2:  IAdviseSink Asynchronous Notification Methods

Method Notifies the Advise Sink that
OnDataChange Calling object's data has changed.
OnViewChange Instructions for drawing the calling object have changed.
OnRename Calling object's moniker has changed.
OnSave Calling object has been saved to persistent storage.
OnClose Calling object has been closed.

As the table indicates, the IAdviseSink() interface exposes methods for notifying the advise sink of events other than changes in the calling object's data. The calling object can also notify the sink when the way in which it draws itself changes, or it is renamed, saved, or closed. These other notifications are used mainly or entirely in the context of compound documents, although the notification mechanism is identical.

In order to take advantage of the advise sink, a data source must implement IDataObject::DAdvise, IDataObject::DUnadvise(), and IDataObject::EnumDAdvise. A data consumer calls the DAdvise mothod to notify a data object that it wishes to be notified when the object's data changes. The consuming object calls the DUnadvise method to tear down this connection. Any interested party can call the EnumAdvise method to learn the number of objects having an advisory connection with a data object.

When data changes at the source, the data object calls IAdviseSink::OnDataChange() on all data consumers that have registered to receive notifications. To keep track of advisory connections and manage the dispatch of notifications, data sources rely on an object called a data advise holder. You can create your own data advise holder by implementing the IDataAdviseHolder() interface. Or, you can let COM do it for you by calling the helper function CreateDataAdviseHolder.

17.4    Uniform Data Transfer Interface Descriptions

17.4.1    IAdviseSink

The IAdviseSink() interface enables containers and other objects to receive notifications of data changes, view changes, and compound-document changes occurring in objects of interest. Container applications, for example, require such notifications to keep cached presentations of their linked and embedded objects up-to-date. Calls to IAdviseSink() methods are asynchronous, so the call is sent and then the next instruction is executed without waiting for the call's return. For an advisory connection to exist, the object that is to receive notifications must implement IAdviseSink(), and the objects in which it is interested must use IDataObject::DAdvise(). As shown in the following table, an object that has implemented an advise sink registers its interest in receiving certain types of notifications by calling the appropriate method.

17.4.1.1    Methods

Call This Method To Register for These Notifications
IDataObject::DAdvise() When a document's data changes.

When an event occurs that applies to a registered notification type, the object application calls the appropriate IAdviseSink() method. For example, when an embedded object closes, it calls the IAdviseSink::OnClose() method to notify its container. These notifications are asynchronous, occurring after the events that trigger them.

17.4.1.1.1    When to Implement

Objects, such as container applications and compound documents, implement IAdviseSink() to receive notification of changes in data, presentation, name, or state of their linked and embedded objects. Implementers register for one or more types of notification, depending on their needs. Notifications of changes to an embedded object originate in the server and flow to the container by way of the object handler. If the object is a linked object, the OLE link object intercepts the notifications from the object handler and notifies the container directly. All containers, the object handler, and the OLE link object register for OLE notifications. The typical container also registers for view notifications. Data notifications are usually sent to the OLE link object and object handler.

17.4.1.1.2    When to Use

Servers call the methods of IAdviseSink() to notify objects with which they have an advisory connection of changes in an object's data, view, name, or state.

17.4.1.1.3    Notes

OLE does not permit synchronous calls in the implementation of asynchronous methods, so you cannot make synchronous calls within any of the the IAdviseSink() interface's methods. For example, an implementation of IAdviseSink::OnDataChange() cannot contain a call to IDataObject::GetData().

Table 17-3:  IAdviseSink Methods in Vtable Order

IUnknown() Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments reference count.
Release() Decrements reference count.

Table 17-4:  IAdviseSink Methods

IAdviseSink() Methods Description
OnDataChange Advises that data has changed.
OnViewChange Advises that view of object has changed.
OnRename Advises that name of object has changed.
OnSave Advises that object has been saved to disk.
OnClose Advises that object has been closed.

17.4.1.1.4    See Also

IAdviseSink2, IDataAdviseHolder()  

IAdviseSink::OnClose()

NAME

IAdviseSink::OnClose() - Called by the server to notify all registered advisory sinks that the object has changed from the running to the loaded state.

Synopsis

#include <objidl.h>

Void OnClose(
         );

Description

OnClose notification indicates that an object is making the transition from the running to the loaded state, so its container can take appropriate measures to ensure orderly shutdown. For example, an object handler must release its pointer to the object.

If the object that is closing is the last open object supported by its OLE server application, the application can also shut down. In the case of a link object, the notification that the object is closing should always be interpreted to mean that the connection to the link source has broken.  

IAdviseSink::OnDataChange()

NAME

IAdviseSink::OnDataChange() - Called by the server to notify a data object's currently registered advise sinks that data in the object has changed.

Synopsis

#include <objidl.h>

void OnDataChange(
        FORMATETC * pFormatetc,
        STGMEDIUM * pStgmed );

Description

Object handlers and containers of link objects implement IAdviseSink::OnDataChange() to take appropriate steps when notified that data in the object has changed. They also must call IDataObject::DAdvise() to set up advisory connections with the objects in whose data they are interested. (See IDataObject::DAdvise() for more information on how to specify an advisory connection for data objects.)

Containers that take advantage of OLE's caching support do not need to register for data-change notifications, because the information necessary to update the container's presentation of the object, including any changes in its data, are maintained in the object's cache.

Notes to Implementors

If you implement IAdviseSink::OnDataChange() for a container, remember that this method is asynchronous and that making synchronous calls within asynchronous methods is not valid. Therefore, you cannot call IDataObject::GetData() to obtain the data you need to update your object. Instead, you either post an internal message, or invalidate the rectangle for the changed data by calling InvalidateRect and waiting for a WM_PAINT message, at which point you are free to get the data and update the object.

The data itself, which is valid only for the duration of the call, is passed using the storage medium pointed to by pStgmed. Since the caller owns the medium, the advise sink should not free it. Also, if pStgmed points to an IStorage() or IStream() interface, the sink must not increment the reference count.

Parameters

pFormatetc

[in] Pointer to the FORMATETC structure, which describes the format, target device, rendering, and storage information of the calling data object.

pStgmed

[in] Pointer to the STGMEDIUM structure, which defines the storage medium (global memory, disk file, storage object, stream object, GDI object, or undefined) and ownership of that medium for the calling data object.

See Also

IDataObject::DAdvise()  

IAdviseSink::OnRename()

NAME

IAdviseSink::OnRename() - Called by the server to notify all registered advisory sinks that the object has been renamed.

Synopsis

#include <objidl.h>

Void OnRename(
        IMoniker * pmk );

Description

OLE link objects normally implement IAdviseSink::OnRename() to receive notification of a change in the name of a link source or its container. The object serving as the link source calls OnRename and passes its new full moniker to the object handler, which forwards the notification to the link object. In response, the link object must update its moniker. The link object, in turn, forwards the notification to its own container.

Parameters

pmk

[in] Pointer to the IMoniker() interface on the new full moniker of the object.

 

IAdviseSink::OnSave()

NAME

IAdviseSink::OnSave() - Called by the server to notify all registered advisory sinks that the object has been saved.

Synopsis

#include <objidl.h>

Void OnSave(
         );

Description

Object handlers and link objects normally implement IAdviseSink::OnSave() to receive notifications of when an object is saved to disk, either to its original storage (through a Save operation) or to new storage (through a Save As operation). Object Handlers and link objects register to be notified when an object is saved for the purpose of updating their caches, but then only if the advise flag passed during registration specifies ADVFCACHE_ONSAVE. Object handlers and link objects forward these notifications to their containers.  

IAdviseSink::OnViewChange()

NAME

IAdviseSink::OnViewChange() - Notifies an object's registered advise sinks that its view has changed.

Synopsis

#include <objidl.h>

Void OnViewChange(
        DWORD dwAspect,
        LONG lindex );

Description

Even though DVASPECT values are individual flag bits, dwAspect may represent only one value. That is, dwAspect cannot contain the result of an OR operation combining two or more DVASPECT values. The lindex member represents the part of the aspect that is of interest. The value of lindex depends on the value of dwAspect. If dwAspect is either DVASPECT_THUMBNAIL or DVASPECT_ICON, lindex is ignored. If dwAspect is DVASPECT_CONTENT, lindex must be -1, which indicates that the entire view is of interest and is the only value that is currently valid.

Parameters

dwAspect

[in] The aspect, or view, of the object. Contains a value taken from the enumeration, DVASPECT.

lindex

[in] The portion of the view that has changed. Currently only -1 is valid.

17.4.2    IDataAdviseHolder

The IDataAdviseHolder() interface contains methods that create and manage advisory connections between a data object and one or more advise sinks. Its methods are intended to be used to implement the advisory methods of IDataObject(). IDataAdviseHolder() is implemented on an advise holder object. Its methods establish and delete data advisory connections and send notification of change in data from a data object to an object that requires this notification, such as a COM container, which must contain an advise sink.

Advise sinks are objects that require notification of change in the data the object contains and implement the IAdviseSink() interface. Advise sinks are also usually associated with OLE compound document containers.

When to Implement

Typically, you use the COM-provided implementation of IDataAdviseHolder() to simplify your implementation of the DAdvise, DUnadvise, and EnumDAdvise methods in the IDataObject() interface, and to send notification of data change as appropriate. It would be necessary to implement IDataAdviseHolder() only in the case where there may be a need for a custom data advise holder object, whose methods are to be used to implement the IDataObject() methods in a set of servers.

When to Use

Your implementation of the advisory methods of IDataObject() can call the methods in IDataAdviseHolder(). The first time you receive a call to IDataObject::DAdvise(), call the function CreateDataAdviseHolder to create an instance of the COM-provided advise holder and get a pointer to its IDataAdviseHolder() interface. Then, in implementing the IDataObject() interface on the data object, you delegate implementations of the DAdvise, DUnadvise, and EnumDAdvise methods to the corresponding methods in IDataAdviseHolder().

When the data of interest to an advise sink actually changes, you call IDataAdviseHolder::SendOnDataChange() from the data object to carry out the necessary notifications.

Table 17-5:  IDataAdviseHolder Methods in VTable Order

IUnknown Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments reference count.
Release() Decrements reference count.

Table 17-6:  IDataAdviseHolder Methods

IDataAdviseHolder() Methods Description
Advise Creates a connection between an advise sink and a data object so the advise sink can receive notification of change in the data object.
Unadvise Destroys a notification connection previously set up with the Advise method.
EnumAdvise Returns an object that can be used to enumerate the current advisory connections.
SendOnDataChange Sends a change notification back to each advise sink that is currently being managed.

See Also

IDataObject(), IAdviseSink()  

IDataAdviseHolder::Advise()

NAME

IDataAdviseHolder::Advise() - Creates a connection between an advise sink and a data object for receiving notifications.

Synopsis

#include <objidl.h>

HRESULT Advise(
        IDataObject * pDataObject,
        FORMATETC * pFormatetc,
        DWORD advf,
        IAdviseSink * pAdvSink,
        DWORD * pdwConnection );

Description

Through the connection established through this method, the advisory sink can receive future notifications in a call to IAdviseSink::OnDataChange().

An object issues a call to IDataObject::DAdvise() to request notification on changes to the format, medium, or target device of interest. This data is specified in the pFormatetc parameter. The DAdvise method is usually implemented to call IDataAdviseHolder::Advise() to delegate the task of setting up and tracking a connection to the advise holder. When the format, medium, or target device in question changes, the data object calls IDataAdviseHolder::SendOnDataChange() to send the necessary notifications.

The established connection can be deleted by passing the value in pdwConnection in a call to IDataAdviseHolder::Unadvise().

Parameters

pDataObject

[in] Pointer to the IDataObject() interface on the data object for which notifications are requested. If data in this object changes, a notification is sent to the advise sinks that have requested notification.

pFormatetc

[in] Pointer to the specified format, medium, and target device that is of interest to the advise sink requesting notification. For example, one sink may want to know only when the bitmap representation of the data in the data object changes. Another sink may be interested in only the metafile format of the same object. Each advise sink is notified when the data of interest changes. This data is passed back to the advise sink when notification occurs.

advf

[in] Contains a group of flags for controlling the advisory connection. Valid values are from the enumeration ADVF. However, only some of the possible ADVF values are relevant for this method. The following table briefly describes the relevant values; a more detailed description can be found in the description of the ADVF enumeration.

1.  IDataAdviseHolder::Advise ADVF Values

ADVF Value Description
ADVF_NODATA Asks that no data be sent along with the notification.
ADVF_ONLYONCE Causes the advisory connection to be destroyed after the first notification is sent. An implicit call to IDataAdviseHolder::Unadvise() is made on behalf of the caller to remove the connection.
ADVF_PRIMEFIRST Causes an initial notification to be sent regardless of whether or not data has changed from its current state.
ADVF_DATAONSTOP When specified with ADVF_NODATA, this flag causes a last notification with the data included to be sent before the data object is destroyed. When ADVF_NODATA is not specified, this flag has no effect.

pAdvSink

[in] Pointer to the IAdviseSink() interface on the advisory sink that receives the change notification.

pdwConnection

[out] Pointer to a DWORD token that identifies this connection. The calling object can later delete the advisory connection by passing this token to IDataAdviseHolder::Unadvise(). If this value is zero, the connection was not established.

Return Values

This method supports the standard return value E_INVALIDARG, as well as the following:

S_OK

The advisory connection was created.

See Also

ADVF, CreateDataAdviseHolder, FORMATETC, IDataAdviseHolder::Unadvise(), IDataObject::DAdvise()  

IDataAdviseHolder::EnumAdvise()

NAME

IDataAdviseHolder::EnumAdvise() - Returns a pointer to an IEnumStatdata interface on an enumeration object that can be used to enumerate the current advisory connections.

Synopsis

#include <objidl.h>

HRESULT EnumAdvise(
        IEnumSTATDATA ** ppenumAdvise );

Description

This method must supply a pointer to an implementation of the IEnumSTATDATA() interface, one of the standard enumerator interfaces that contain the Next, Reset, Clone, and Skip methods, on an enumerator object. Its methods allow you to enumerate the data stored in an array of STATDATA structures. You get a pointer to the COM implementation of IDataAdviseHolder() through a call to CreateDataAdviseHolder, and then call IDataAdviseHolder::EnumAdvise() to implement IDataObject::EnumDAdvise().

Adding more advisory connections while the enumerator object is active has an undefined effect on the enumeration that results from this method.

Parameters

ppenumAdvise

[out] Indirect pointer to the IEnumStatdata interface on the new enumerator object. If this value is NULL, there are no connections to advise sinks at this time.

Return Values

This method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The enumerator object is successfully instantiated or there are no connections.

See Also

IEnumXXXX, IEnumSTATDATA(), IDataObject::EnumDAdvise()  

IDataAdviseHolder::SendOnDataChange()

NAME

IDataAdviseHolder::SendOnDataChange() - Sends notifications to each advise sink for which there is a connection established by calling the IAdviseSink::OnDataChange() method for each advise sink currently being handled by this instance of the advise holder object.

Synopsis

#include <objidl.h>

HRESULT SendOnDataChange(
        IDataObject * pDataObject,
        DWORD dwReserved,
        DWORD advf );

Description

The data object must call this method when it detects a change that would be of interest to an advise sink that has previously requested notification.

Most notifications include the actual data with them. The only exception is if the ADVF_NODATA flag was previously specified when the connection was initially set up in the IDataAdviseHolder::Advise() method.

Before calling the IAdviseSink::OnDataChange() method for each advise sink, this method obtains the actual data by calling the IDataObject::GetData() method through the pointer specified in the pDataObject parameter.

Parameters

pDataObject

[in] Pointer to the IDataObject() interface on the data object in which the data has just changed. This pointer is used in subsequent calls to IAdviseSink::OnDataChange().

dwReserved

[in] Reserved for future use; must be zero.

advf

[in] Container for advise flags that specify how the call to IAdviseSink::OnDataChange() is made. These flag values are from the enumeration ADVF. Typically, the value for advf is NULL. The only exception occurs when the data object is shutting down and must send a final notification that includes the actual data to sinks that have specified ADVF_DATAONSTOP and ADVF_NODATA in their call to IDataObject::DAdvise(). In this case, advf contains ADVF_DATAONSTOP.

Return Values

This method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The call to IAdviseSink::OnDataChange() was made.

See Also

ADVF, IAdviseSink::OnDataChange()  

IDataAdviseHolder::Unadvise()

NAME

IDataAdviseHolder::Unadvise() - Removes a connection between a data object and an advisory sink that was set up through a previous call to IDataAdviseHolder::Advise(). IDataAdviseHolder::Unadvise() is typically called in the implementation of IDataObject::DUnadvise().

Synopsis

#include <objidl.h>

HRESULT Unadvise(
        DWORD dwConnection );

Parameters

dwConnection

[in] DWORD token that specifies the connection to remove. This value was returned by IDataAdviseHolder::Advise() when the connection was originally established.

Return Values

S_OK

The specified connection was successfully deleted.

OLE_E_NOCONNECTION

The specified dwConnection is not a valid connection.

See Also

IDataAdviseHolder::Advise(), IDataObject::DUnadvise()

17.4.3    IDataObject

The IDataObject() interface specifies methods that enable data transfer and notification of changes in data. Data transfer methods specify the format of the transferred data along with the medium through which the data is to be transferred. Optionally, the data can be rendered for a specific target device. In addition to methods for retrieving and storing data, the IDataObject() interface specifies methods for enumerating available formats and managing connections to advisory sinks for handling change notifications.

The term ``data object'' is used to mean any object that supports an implementation of the IDataObject() interface. Implementations vary, depending on what the data object is required to do; in some data objects, the implementation of certain methods not supported by the object could simply be the return of E_NOTIMPL. For example, some data objects do not allow callers to send them data. Other data objects do not support advisory connections and change notifications. However, for those data objects that do support change notifications, COM provides an object called a data advise holder. An interface pointer to this holder is available through a call to the helper function CreateDataAdviseHolder. A data object can have multiple connections, each with its own set of attributes. The COM data advise holder simplifies the task of managing these connections and sending the appropriate notifications.

When to Implement

Implement the IDataObject() interface if you are developing a container or server application that is capable of transferring data. For example, if your application allows its data to be pasted or dropped into another application, you must implement the IDataObject() interface. COM compound document object servers that support objects that can be embedded or linked must implement IDataObject().

COM provides implementations in its default object handler and its cache.

When to Use

Any object that can receive data calls the methods in the IDataObject() interface.

When you call the data transfer methods in the IDataObject() interface, you specify a format, a medium, and, optionally, a target device for which the data should be rendered. Objects, such as containers, that want to be notified through their advise sinks when the data in the data object changes call the IDataObject() advisory methods to set up an advisory connection through which notifications can be sent.

Table 17-7:  IDataObject Methods in VTable Order

IUnknown Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments reference count.
Release() Decrements reference count.

Table 17-8:  IDataObject Methods

IDataObject() Methods Description
GetData Renders the data described in a FORMATETC structure and transfers it through the STGMEDIUM structure.
GetDataHere Renders the data described in a FORMATETC structure and transfers it through the STGMEDIUM structure allocated by the caller.
QueryGetData Determines whether the data object is capable of rendering the data described in the FORMATETC structure.
GetCanonicalFormatEtc Provides a potentially different but logically equivalent FORMATETC structure.
SetData Provides the source data object with data described by a FORMATETC structure and an STGMEDIUM structure.
EnumFormatEtc Creates and returns a pointer to an object to enumerate the FORMATETC supported by the data object.
DAdvise Creates a connection between a data object and an advise sink so the advise sink can receive notifications of changes in the data object.
DUnadvise Destroys a notification previously set up with the DAdvise method.
EnumDAdvise Creates and returns a pointer to an object to enumerate the current advisory connections.

 

IDataObject::DAdvise()

NAME

IDataObject::DAdvise() - Called by an object supporting an advise sink to create a connection between a data object and the advise sink. This enables the advise sink to be notified of changes in the data of the object.

Synopsis

#include <objidl.h>

HRESULT DAdvise(
        FORMATETC * pFormatetc,
        DWORD advf,
        IAdviseSink * pAdvSink,
        DWORD * pdwConnection );

Description

IDataObject::DAdvise() creates a change notification connection between a data object and the caller. The caller provides an advisory sink to which the notifications can be sent when the object's data changes.

Objects used simply for data transfer typically do not support advisory notifications and return OLE_E_ADVISENOTSUPPORTED from IDataObject::DAdvise().

Notes to Callers

The object supporting the advise sink calls IDataObject::DAdvise() to set up the connection, specifying the format, aspect, medium, and/or target device of interest in the FORMATETC structure passed in. If the data object does not support one or more of the requested attributes or the sending of notifications at all, it can refuse the connection by returning OLE_E_ADVISENOTSUPPORTED.

Containers of linked objects can set up advisory connections directly with the bound link source or indirectly through the standard COM link object that manages the connection. Connections set up with the bound link source are not automatically deleted. The container must explicitly call IDataObject::DUnAdvise() on the bound link source to delete an advisory connection. Connections set up through the COM link object are destroyed when the link object is deleted.

The COM default link object creates a ``wildcard advise'' with the link source so COM can maintain the time of last change. This advise is specifically used to note the time that anything changed. COM ignores all data formats that may have changed, noting only the time of last change. To allow wildcard advises, set the FORMATETC members as follows before calling IDataObject::DAdvise:

cf == 0; 
ptd == NULL; 
dwAspect ==-1; 
lindex == -1 
tymed == -1;

The advise flags should also include ADVF_NODATA. Wildcard advises from COM should always be accepted by applications.

Notes to Implementers

To simplify the implementation of DAdvise and the other notification methods in IDataObject() (DUnadvise and EnumAdvise) that supports notification, COM provides an advise holder object that manages the registration and sending of notifications. To get a pointer to this object, call the helper function CreateDataAdviseHolder on the first invocation of DAdvise. This supplies a pointer to the object's IDataAdviseHolder() interface. Then, delegate the call to the IDataAdviseHolder::Advise() method in the data advise holder, which creates, and subsequently manages, the requested connection.

Parameters

pFormatetc

[in] Pointer to a FORMATETC structure that defines the format, target device, aspect, and medium that will be used for future notifications. For example, one sink may want to know only when the bitmap representation of the data in the the data object changes. Another sink may be interested in only the metafile format of the same object. Each advise sink is notified when the data of interest changes. This data is passed back to the advise sink when notification occurs.

advf

[in] DWORD that specifies a group of flags for controlling the advisory connection. Valid values are from the enumeration ADVF. However, only some of the possible ADVF values are relevant for this method. The following table briefly describes the relevant values. Refer to ADVF for a more detailed description.

1.  IDataObject::DAdvise ADVF Values

ADVF Value Description
ADVF_NODATA Asks the data object to avoid sending data with the notifications. Typically data is sent. This flag is a way to override the default behavior. When ADVF_NODATA is used, the TYMED member of the STGMEDIUM structure that is passed to OnDataChange will usually contain TYMED_NULL. The caller can then retrieve the data with a subsequent IDataObject::GetData() call.
ADVF_ONLYONCE Causes the advisory connection to be destroyed after the first change notification is sent. An implicit call to IDataObject::DUnadvise() is made on behalf of the caller to remove the connection.
ADVF_PRIMEFIRST Asks for an additional initial notification. The combination of ADVF_ONLYONCE and ADVF_PRIMEFIRST provides, in effect, an asynchronous IDataObject::GetData() call.
ADVF_DATAONSTOP When specified with ADVF_NODATA, this flag causes a last notification with the data included to to be sent before the data object is destroyed. If used without ADVF_NODATA, IDataObject::DAdvise can be implemented in one of the following ways: (1) the ADVF_DATAONSTOP can be ignored; (2) the object can behave as if ADVF_NODATA was specified; (3) a change notification is sent only in the shutdown case. Data changes prior to shutdown do not cause a notification to be sent.

pAdvSink

[in] Pointer to the IAdviseSink() interface on the advisory sink that will receive the change notification.

pdwConnection

[out] Pointer to a DWORD token that identifies this connection. You can use this token later to delete the advisory connection (by passing it to IDataObject::DUnadvise()). If this value is zero, the connection was not established.

Return Values

This method supports the standard return values E_INVALIDARG, E_UNEXPECTED, and E_OUTOFMEMORY, as well as the following:

S_OK

The advisory connection was created.

E_NOTIMPL

This method is not implemented on the data object.

DV_E_LINDEX

Invalid value for lindex; currently, only -1 is supported.

DV_E_FORMATETC

Invalid value for pFormatetc.

OLE_E_ADVISENOTSUPPORTED

The data object does not support change notification.

See Also

ADVF, FORMATETC, CreateDataAdviseHolder, IDataAdviseHolder - OLE implementation>, IAdviseSink::OnDataChange(), IDataObject::DUnAdvise()  

IDataObject::DUnadvise()

NAME

IDataObject::DUnadvise() - Destroys a notification connection that had been previously set up.

Synopsis

#include <objidl.h>

HRESULT DUnadvise(
        DWORD dwConnection );

Description

This methods destroys a notification created with a call to the IDataObject::DAdvise() method.

If the advisory connection being deleted was initially set up by delegating the IDataObject::DAdvise() call to IDataAdviseHolder::Advise(), you must delegate this call to IDataAdviseHolder::Unadvise() to delete it.

Parameters

dwConnection

[in] DWORD token that specifies the connection to remove. Use the value returned by IDataObject::DAdvise() when the connection was originally established.

Return Values

S_OK

The specified connection was successfully deleted.

OLE_E_NOCONNECTION

The specified dwConnection is not a valid connection.

OLE_E_ADVISENOTSUPPORTED

This IDataObject() implementation does not support notification.

See Also

IDataObject::DAdvise(), IDataAdviseHolder::Unadvise()  

IDataObject::EnumDAdvise()

NAME

IDataObject::EnumDAdvise() - Creates an object that can be used to enumerate the current advisory connections.

Synopsis

#include <objidl.h>

HRESULT EnumDAdvise(
        IEnumSTATDATA ** ppenumAdvise );

Description

The enumerator object created by this method implements the IEnumSTATDATA() interface, one of the standard enumerator interfaces that contain the Next, Reset, Clone, and Skip methods. IEnumSTATDATA() permits the enumeration of the data stored in an array of STATDATA structures. Each of these structures provides information on a single advisory connection, and includes FORMATETC and ADVF information, as well as the pointer to the advise sink and the token representing the connection.

Notes to Callers

After getting a pointer through this method, the data object can call the appropriate enumeration methods. While the enumeration is in progress, the effect of adding more advisory connections on the subsequent enumeration is undefined.

Notes to Implementers

It is recommended that you use the COM data advise holder object to handle advisory connections. With the pointer obtained through a call to CreateDataAdviseHolder, implementing IDataObject::EnumDAdvise() becomes a simple matter of delegating the call to IDataAdviseHolder::EnumAdvise(). This creates the enumerator and supplies the pointer to the COM implementation of IEnumSTATDATA(). At that point, you can call its methods to enumerate the current advisory connections.

Parameters

ppenumAdvise

[out] Indirect pointer to the IEnumSTATDATA() interface on the new enumerator object. If the supplied value is NULL, there are no connections to advise sinks at this time.

Return Values

This method supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The enumerator object is successfully instantiated or there are no connections.

OLE_E_ADVISENOTSUPPORTED

Advisory notifications are not supported by this object.

See Also

IEnumSTATDATA(), IDataAdviseHolder::EnumAdvise()  

IDataObject::EnumFormatEtc()

NAME

IDataObject::EnumFormatEtc() - Creates an object for enumerating the FORMATETC structures for a data object. These structures are used in calls to IDataObject::GetData() or IDataObject::SetData().

Synopsis

#include <objidl.h>

HRESULT EnumFormatEtc(
        DWORD dwDirection,
        IEnumFORMATETC ** ppenumFormatetc );

Description

IDataObject::EnumFormatEtc() creates an enumerator object that can be used to determine all of the ways the data object can describe data in a FORMATETC structure, and supplies a pointer to its IEnumFORMATETC() interface. This is one of the standard enumerator interfaces.

The DATADIR enumeration has the following contents:

typedef enum tag DATADIR {
     DATADIR_GET = 1,
     DATADIR_SET = 2,
 } DATADIR;

Notes to Callers

Having obtained the pointer, the caller can enumerate the FORMATETC structures by calling the enumeration methods of IEnumFORMATETC(). Because the formats can change over time, there is no guarantee that an enumerated format is currently supported because the formats can change over time. Accordingly, applications should treat the enumeration as a hint of the format types that can be passed. The caller is responsible for calling IEnumFormatEtc::Release when it is finished with the enumeration.

IDataObject::EnumFormatEtc() is called when one of the following actions occurs:

Notes to Implementers

Formats can be registered statically in the registry or dynamically during object initialization. If an object has an unchanging list of formats and these formats are registered in the registry, COM provides an implementation of a FORMATETC enumeration object that can enumerate formats registered under a specific CLSID in the registry. A pointer to its IEnumFORMATETC() interface is available through a call to the helper function OleRegEnumFormatEtc. In this situation, therefore, you can implement the EnumFormatEtc method simply with a call to this function.

EXE applications can effectively do the same thing by implementing the method to return the value OLE_S_USEREG. This return value instructs the default object handler to call OleRegEnumFormatEtc. Object applications that are implemented as DLL object applications cannot return OLE_S_USEREG, so must call OleRegEnumFormatEtc directly.

Private formats can be enumerated for OLE 1 objects, if they are registered with the RequestDataFormats or SetDataFormats keys in the registry. Also, private formats can be enumerated for COM objects (all versions after OLE 1), if they are registered with the GetDataFormats or SetDataFormats keys.

For OLE 1 objects whose servers do not have RequestDataFormats or SetDataFormats information registered in the registry, a call to IDataObject::EnumFormatEtc() passing DATADIR_GET only enumerates the Native and Metafile formats, regardless of whether they support these formats or others. Calling EnumFormatEtc passing DATADIR_SET on such objects only enumerates Native, regardless of whether the object supports being set with other formats.

The FORMATETC structure returned by the enumeration usually indicates a NULL target device (ptd). This is appropriate because, unlike the other members of FORMATETC, the target device does not participate in the object's decision as to whether it can accept or provide the data in either a SetData or GetData call.

The TYMED member of FORMATETC often indicates that more than one kind of storage medium is acceptable. You should always mask and test for this by using a Boolean OR operator.

Parameters

dwDirection

[in] Direction of the data through a value from the enumeration DATADIR (see Description).

The value DATADIR_GET enumerates the formats that can be passed in to a call to IDataObject::GetData(). The value DATADIR_SET enumerates those formats that can be passed in to a call to IDataObject::SetData().

ppenumFormatetc

[out] Indirect pointer to the IEnumFORMATETC() interface on the new enumerator object.

Return Values

This method supports the standard return values E_INVALIDARG and E_OUTOFMEMORY, as well as the following:

S_OK

Enumerator object was successfully created.

E_NOTIMPL

The direction specified by dwDirection is not supported.

OLE_S_USEREG

Requests that COM enumerate the formats from the registry.

See Also

FORMATETC, IEnumFormatEtc, IDataObject::SetData(), IDataObject::GetData()  

IDataObject::GetCanonicalFormatEtc()

NAME

IDataObject::GetCanonicalFormatEtc() - Provides a standard FORMATETC structure that is logically equivalent to one that is more complex. You use this method to determine whether two different FORMATETC structures would return the same data, removing the need for duplicate rendering.

Synopsis

#include <objidl.h>

HRESULT GetCanonicalFormatEtc(
        FORMATETC * pFormatetcIn,
        FORMATETC * pFormatetcOut );

Description

If a data object can supply exactly the same data for more than one requested FORMATETC structure, IDataObject::GetCanonicalFormatEtc() can supply a ``canonical'', or standard FORMATETC that gives the same rendering as a set of more complicated FORMATETC structures. For example, it is common for the data returned to be insensitive to the target device specified in any one of a set of otherwise similar FORMATETC structures.

Notes to Callers

A call to this method can determine whether two calls to IDataObject::GetData() on a data object, specifying two different FORMATETC structures, would actually produce the same renderings, thus eliminating the need for the second call and improving performance. If the call to GetCanonicalFormatEtc results in a canonical format being written to the pFormatetcOut parameter, the caller then uses that structure in a subsequent call to IDataObject::GetData().

Notes to Implementers

Conceptually, it is possible to think of FORMATETC structures in groups defined by a canonical FORMATETC that provides the same results as each of the group members. In constructing the canonical FORMATETC, you should make sure it contains the most general information possible that still produces a specific rendering.

For data objects that never provide device-specific renderings, the simplest implementation of this method is to copy the input FORMATETC to the output FORMATETC, store a NULL in the ptd field of the output FORMATETC, and return DATA_S_SAMEFORMATETC.

Parameters

pFormatetcIn

[in] Pointer to the FORMATETC structure that defines the format, medium, and target device that the caller would like to use to retrieve data in a subsequent call such as IDataObject::GetData(). The TYMED member is not significant in this case and should be ignored.

pFormatetcOut

[out] Pointer to a FORMATETC structure that contains the most general information possible for a specific rendering, making it canonically equivalent to pFormatetcIn. The caller must allocate this structure and the GetCanonicalFormatEtc method must fill in the data. To retrieve data in a subsequent call like IDataObject::GetData(), the caller uses the supplied value of pFormatetcOut, unless the value supplied is NULL. This value is NULL if the method returns DATA_S_SAMEFORMATETC. The TYMED member is not significant in this case and should be ignored.

Return Values

This method supports the standard return values E_INVALIDARG, E_UNEXPECTED, and E_OUTOFMEMORY, as well as the following:

S_OK

The returned FORMATETC structure is different from the one that was passed.

DATA_S_SAMEFORMATETC

The FORMATETC structures are the same and NULL is returned in pFormatetcOut.

DV_E_LINDEX

Invalid value for lindex; currently, only -1 is supported.

DV_E_FORMATETC

Invalid value for pFormatetc.

OLE_E_NOTRUNNING

Object application is not running.

See Also

IDataObject::GetData(), FORMATETC  

IDataObject::GetData()

NAME

IDataObject::GetData() - Called by a data consumer to obtain data from a source data object. The GetData method renders the data described in the specified FORMATETC structure and transfers it through the specified STGMEDIUM structure. The caller then assumes responsibility for releasing the STGMEDIUM structure.

Synopsis

#include <objidl.h>

HRESULT GetData(
        FORMATETC * pFormatetc,
        STGMEDIUM * pmedium );

Description

A data consumer calls IDataObject::GetData() to retrieve data from a data object, conveyed through a storage medium (defined through the STGMEDIUM structure).

Notes to Callers

You can specify more than one acceptable TYMED medium with the Boolean OR operator. IDataObject::GetData() must choose from the OR'd values the medium that best represents the data, do the allocation, and indicate responsibility for releasing the medium.

Data transferred across a stream extends from position zero of the stream pointer through to the position immediately before the current stream pointer (that is, the stream pointer position upon exit).

Notes to Implementers

IDataObject::GetData() must check all fields in the FORMATETC structure. It is important that IDataObject::GetData() render the requested aspect and, if possible, use the requested medium. If the data object cannot comply with the information specified in the FORMATETC, the method should return DV_E_FORMATETC. If an attempt to allocate the medium fails, the method should return STG_E_MEDIUMFULL. It is important to fill in all of the fields in the STGMEDIUM structure.

Although the caller can specify more than one medium for returning the data, IDataObject::GetData() can supply only one medium. If the initial transfer fails with the selected medium, this method can be implemented to try one of the other media specified before returning an error.

Parameters

pFormatetc

[in] Pointer to the FORMATETC structure that defines the format, medium, and target device to use when passing the data. It is possible to specify more than one medium by using the Boolean OR operator, allowing the method to choose the best medium among those specified.

pmedium

[out] Pointer to the STGMEDIUMstructure that indicates the storage medium containing the returned data through its tymed member, and the responsibility for releasing the medium through the value of its punkOuter member. If punkForRelease is NULL, the receiver of the medium is responsible for releasing it; otherwise, punkForRelease points to the IUnknown() on the appropriate object so its Release() method can be called. The medium must be allocated and filled in by IDataObject::GetData().

Return Values

This method supports the standard return values E_INVALIDARG, E_UNEXPECTED, and E_OUTOFMEMORY, as well as the following:

S_OK

Data was successfully retrieved and placed in the storage medium provided.

DV_E_LINDEX

Invalid value for lindex; currently, only -1 is supported.

DV_E_FORMATETC

Invalid value for pFormatetc.

DV_E_TYMED

Invalid tymed value.

DV_E_DVASPECT

Invalid dwAspect value.

OLE_E_NOTRUNNING

Object application is not running.

STG_E_MEDIUMFULL

An error occurred when allocating the medium.

See Also

IDataObject::GetDataHere(), IDataObject::SetData(), FORMATETC, STGMEDIUM  

IDataObject::GetDataHere()

NAME

IDataObject::GetDataHere() - Called by a data consumer to obtain data from a source data object. This method differs from the GetData method in that the caller must allocate and free the specified storage medium.

Synopsis

#include <objidl.h>

HRESULT GetDataHere(
        FORMATETC * pFormatetc,
        STGMEDIUM * pmedium );

Description

The IDataObject::GetDataHere() method is similar to IDataObject::GetData(), except that the caller must both allocate and free the medium specified in pmedium. GetDataHere renders the data described in a FORMATETC structure and copies the data into that caller-provided STGMEDIUM structure. For example, if the medium is TYMED_HGLOBAL, this method cannot resize the medium or allocate a new hGlobal.

Some media are not appropriate in a call to GetDataHere, including GDI types such as metafiles. The GetDataHere method cannot put data into a caller-provided metafile. In general, the only storage media it is necessary to support in this method are TYMED_ISTORAGE, TYMED_ISTREAM, and TYMED_FILE.

When the transfer medium is a stream, COM makes assumptions about where the data is being returned and the position of the stream's seek pointer. In a GetData call, the data returned is from stream position zero through just before the current seek pointer of the stream (that is, the position on exit). For GetDataHere, the data returned is from the stream position on entry through just before the position on exit.

Parameters

pFormatetc

[in] Pointer to the FORMATETC structure that defines the format, medium, and target device to use when passing the data. Only one medium can be specified in TYMED, and only the following TYMED values are valid: TYMED_STORAGE, TYMED_STREAM, TYMED_HGLOBAL, or TYMED_FILE.

pmedium

[out] Pointer to the STGMEDIUM structure that defines the storage medium containing the data being transferred. The medium must be allocated by the caller and filled in by IDataObject::GetDataHere(). The caller must also free the medium. The implementation of this method must always supply a value of NULL for the punkForRelease member of the STGMEDIUM structure to which this parameter points.

Return Values

This method supports the standard return values E_INVALIDARG, E_UNEXPECTED, and E_OUTOFMEMORY, as well as the following:

S_OK

Data was successfully retrieved and placed in the storage medium provided.

DV_E_LINDEX

Invalid value for lindex; currently, only -1 is supported.

DV_E_FORMATETC

Invalid value for pFormatetc.

DV_E_TYMED

Invalid tymed value.

DV_E_DVASPECT

Invalid dwAspect value.

OLE_E_NOTRUNNING

Object application is not running.

STG_E_MEDIUMFULL

The medium provided by the caller is not large enough to contain the data.

See Also

IDataObject::GetData(), FORMATETC, STGMEDIUM  

IDataObject::QueryGetData()

NAME

IDataObject::QueryGetData() - Determines whether the data object is capable of rendering the data described in the FORMATETC structure. Objects attempting a paste or drop operation can call this method before calling IDataObject::GetData() to get an indication of whether the operation may be successful.

Synopsis

#include <objidl.h>

HRESULT QueryGetData(
        FORMATETC * pFormatetc );

Description

The client of a data object calls IDataObject::QueryGetData() to determine whether passing the specified FORMATETC structure to a subsequent call to IDataObject::GetData() is likely to be successful. A successful return from this method does not necessarily ensure the success of the subsequent paste or drop operation.

Parameters

pFormatetc

[in] Pointer to the FORMATETC structure defining the format, medium, and target device to use for the query.

Return Values

This method supports the standard return values E_INVALIDARG, E_UNEXPECTED, and E_OUTOFMEMORY, as well as the following:

S_OK

Subsequent call to IDataObject::GetData() would probably be successful.

DV_E_LINDEX

Invalid value for lindex; currently, only -1 is supported.

DV_E_FORMATETC

Invalid value for pFormatetc.

DV_E_TYMED

Invalid tymed value.

DV_E_DVASPECT

Invalid dwAspect value.

OLE_E_NOTRUNNING

Object application is not running.

See Also

IDataObject::GetData(), FORMATETC  

IDataObject::SetData()

NAME

IDataObject::SetData() - Called by an object containing a data source to transfer data to the object that implements this method.

Synopsis

#include <objidl.h>

HRESULT SetData(
        FORMATETC * pFormatetc,
        STGMEDIUM * pmedium,
        BOOL fRelease );

Description

IDataObject::SetData() allows another object to attempt to send data to the implementing data object. A data object implements this method if it supports receiving data from another object. If it does not support this, it should be implemented to return E_NOTIMPL.

The caller allocates the storage medium indicated by the pmedium, in which the data is passed. The data object called does not take ownership of the data until it has successfully received it and no error code is returned. The value of the fRelease parameter indicates the ownership of the medium after the call returns. FALSE indicates the caller still owns the medium, and the data object only has the use of it during the call; TRUE indicates that the data object now owns it and must release it when it is no longer needed.

The type of medium (TYMED) specified in the pformatetc and pmedium parameters must be the same. For example, one cannot be an hGlobal (global handle) and the other a stream.

Parameters

pFormatetc

[in] Pointer to the FORMATETC structure defining the format used by the data object when interpreting the data contained in the storage medium.

pmedium

[in] Pointer to the STGMEDIUM structure defining the storage medium in which the data is being passed.

fRelease

[in] If TRUE, the data object called, which implements IDataObject::SetData(), owns the storage medium after the call returns. This means it must free the medium after it has been used by calling the ReleaseStgMedium() function. If FALSE, the caller retains ownership of the storage medium and the data object called uses the storage medium for the duration of the call only.

Return Values

This method supports the standard return values E_FAIL, E_INVALIDARG, E_UNEXPECTED, and E_OUTOFMEMORY, as well as the following:

S_OK

Data was successfully transferred.

E_NOTIMPL

This method is not implemented for the data object.

DV_E_LINDEX

Invalid value for lindex; currently, only -1 is supported.

DV_E_FORMATETC

Invalid value for pFormatetc.

DV_E_TYMED

Invalid tymed value.

DV_E_DVASPECT

Invalid dwAspect value.

OLE_E_NOTRUNNING

Object application is not running.

See Also

IDataObject::GetData(), FORMATETC, STGMEDIUM

17.4.4    IEnumFORMATETC

The IEnumFORMATETC() interface is used to enumerate an array of FORMATETC structures. IEnumFORMATETC() has the same methods as all enumerator interfaces: Next, Skip, Reset, and Clone. For general information on these methods, refer to IEnumXXXX().

When to Implement

IEnumFORMATETC() must be implemented by all data objects to support calls to IDataObject::EnumFormatEtc(), which supplies a pointer to the enumerator's IEnumFORMATETC() interface. If the data object supports a different set of FORMATETC information depending on the direction of the data (whether a call is intended for the SetData or GetDatamethod of IDataObject()), the implementation of IEnumFORMATETC() must be able to operate on both.

The order of formats enumerated through the IEnumFORMATETC() object should be the same as the order that the formats would be in when placed on the clipboard. Typically, this order starts with private data formats and ends with presentation formats such as CF_METAFILEPICT.

When to Use

Call the methods of IEnumFORMATETC() when you need to enumerate the FORMATETC structures defining the formats and media supported by a given data object. This is necessary in most data transfer operations, such as clipboard and drag-and-drop, so the object on the other end of the data transfer can determine whether the appropriate format and media for the data is supported.

The prototypes of the methods are as follows:

#include <objidl.h>

HRESULT Next(
        ULONG celt,
        FORMATETC * rgelt,
        ULONG * pceltFetched );

#include <objidl.h>

HRESULT Skip(
        ULONG celt );

#include <objidl.h>

HRESULT Reset(
        void );

#include <objidl.h>

HRESULT Clone(
        IEnumFORMATETC ** ppenum );

See Also

FORMATETC, IEnumXXXX

17.4.5    IEnumSTATDATA

The IEnumSTATDATA() interface is used to enumerate through an array of STATDATA structures, which contain advisory connection information for a data object. IEnumSTATDATA() has the same methods as all enumerator interfaces: Next, Skip, Reset, and Clone. For general information on these methods, refer to IEnumXXXX().

When to Implement

IEnumSTATDATA() is implemented to enumerate advisory connections. Most applications will not implement this directly, but will use the COM-provided implementation. Pointers to this implementation are available in two ways:

When to Use

Containers usually call methods that return a pointer to IEnumSTATDATA() so the container can use its methods to enumerate the existing advisory connections, and use this information to instruct an object to release each of its advisory connections prior to closing down. IDataObject::EnumDAdvise() and IDataAdviseHolder::EnumAdvise() methods supply a pointer to IEnumSTATDATA().

The prototypes of the methods are as follows:

#include <objidl.h>

HRESULT Next(
        ULONG celt,
        STATDATA * rgelt,
        ULONG * pceltFetched );

#include <objidl.h>

HRESULT Skip(
        ULONG celt );

#include <objidl.h>

HRESULT Reset(
        void );

#include <objidl.h>

HRESULT Clone(
        IEnumSTATDATA ** ppenum );

See Also

STATDATA, IEnumXXXX, IDataObject::EnumDAdvise(), IDataAdviseHolder::EnumAdvise()

17.5    Uniform Data Transfer API Descriptions

 

CreateDataAdviseHolder()

NAME

CreateDataAdviseHolder() - Supplies a pointer to the COM implementation of IDataAdviseHolder() on the data advise holder object.

Synopsis

#include <objbase.h>

WINOLEAPI CreateDataAdviseHolder(
        IDataAdviseHolder ** ppDAHolder );

Description

Call CreateDataAdviseHolder in your implementation of IDataObject::DAdvise() to get a pointer to the COM implementation of IDataAdviseHolder() interface. With this pointer, you can then complete the implementation of IDataObject::DAdvise() by calling the IDataAdviseHolder::Advise() method, which creates an advisory connection between the calling object and the data object.

Parameters

ppDAHolder

[out] Address of IDataAdviseHolder* pointer variable that receives the interface pointer to the new advise holder object.

Return Values

This function supports the standard return value E_OUTOFMEMORY, as well as the following:

S_OK

The advise holder object has been instantiated and the pointer supplied.

See Also

IDataAdviseHolder()  

CreateFormatEnumerator()

NAME

CreateFormatEnumerator() - Creates an object that implements IEnumFORMATETC() over a static array of FORMATETC structures.

Synopsis

#include <objbase.h>

HRESULT CreateFormatEnumerator(
        UINT cfmtetc,
        FORMATETC * rgfmtetc,
        IenumFORMATETC ** ppenumfmtetc );

Description

The CreateFormatEnumerator function creates an enumerator object that implements IEnumFORMATETC() over a static array of FORMATETC structures. The cfmtetc parameter specifies the number of these structures. With the pointer, you can call the standard enumeration methods to enumerate the structures, as described in the IEnumXXX reference.

Parameters

cfmtetc

[in] Number of FORMATETC structures in the static array specified by the rgfmtetc parameter. The cfmtetc parameter cannot be zero.

rgfmtetc

[in] Pointer to a static array of FORMATETC structures.

ppenumfmtetc

[out] Address of IEnumFORMATETC* pointer variable that receives the interface pointer to the enumerator object.

Return Values

S_OK

The operation was successful.

E_INVALIDARG

One or more parameters are invalid.

 

ReleaseStgMedium()

NAME

ReleaseStgMedium() - Frees the specified storage medium.

Synopsis

#include <ole2.h>

void ReleaseStgMedium((
        STGMEDIUM * pmedium );

Description

The ReleaseStgMedium function calls the appropriate method or function to release the specified storage medium. Use this function during data transfer operations where storage medium structures are parameters, such as IDataObject::GetData() or IDataObject::SetData(). In addition to identifying the type of the storage medium, this structure specifies the appropriate IUnknown::Release() method for releasing the storage medium when it is no longer needed.

It is common to pass a STGMEDIUM from one body of code to another, such as in IDataObject::GetData(), in which the one called can allocate a medium and return it to the caller. ReleaseStgMedium() permits flexibility in whether the receiving body of code owns the medium, or whether the original provider of the medium still owns it, in which case the receiving code needs to inform the provider that it can free the medium.

When the original provider of the medium is responsible for freeing the medium, the provider calls ReleaseStgMedium(), specifying the medium and the appropriate IUnknown() pointer as the punkForRelease structure member. Depending on the type of storage medium being freed, one of the following actions is taken, followed by a call to the Release() method on the specified IUnknown() pointer:

1.  ReleaseStgMedium Actions

Medium ReleaseStgMedium() Action
TYMED_HGLOBAL None.
TYMED_GDI None.
TYMED_ENHMF None.
TYMED_MFPICT None.
TYMED_FILE Frees the file name string using standard memory management mechanisms.
TYMED_ISTREAM Calls IStream::Release().
TYMED_ISTORAGE Calls IStorage::Release().

The provider indicates that the receiver of the medium is responsible for freeing the medium by specifying NULL for the punkForRelease structure member. Then the receiver calls ReleaseStgMedium(), which makes a call as described in the following table depending on the type of storage medium being freed:

2.  ReleaseStgMedium Calls by Storage Medium

Medium ReleaseStgMedium() Action
TYMED_HGLOBAL Calls the Win32 GlobalFree function on the handle.
TYMED_GDI Calls the Win32 DeleteObject function on the handle.
TYMED_ENHMF Deletes the enhanced metafile.
TYMED_MFPICT The hMF that it contains is deleted with the Win32 DeleteMetaFile function; then the handle itself is passed to GlobalFree.
TYMED_FILE Frees the disk file by deleting it. Frees the file name string by using the standard memory management paradigm.
TYMED_ISTREAM Calls IStream::Release.
TYMED_ISTORAGE Calls IStorage::Release.

In either case, after the call to ReleaseStgMedium(), the specified storage medium is invalid and can no longer be used.

Parameters

pmedium

[in] Pointer to the storage medium that is to be freed.

Return Values

None.

See Also

STGMEDIUM structure

17.6    Uniform Data Transfer Structure Descriptions

17.6.1    DVASPECTINFO

The DVASPECTINFO structure is used in the IViewObject::Draw method to optimize rendering of an inactive object by making more efficient use of the GDI. The pvAspect parameter in IViewObject::Draw points to this structure. It is defined as follows:

typedef struct STRUCT tagDVASPECTINFO 
{
    UNIT  cb;
    DWORD  dwFlags;
} DVASPECTINFO;

Members

cb

Size of the structure in bytes. The size includes this member as well as the dwFlags member.

dwFlags

A value taken from the DVASPECTINFOFLAG enumeration.

See Also

DVASPECTINFOFLAG

17.6.2    DVEXTENTINFO

The DVEXTENTINFO structure is used in IViewObjectEx::GetNaturalExtent.

typedef struct tagDVEXTENTINFO 
{ 
    ULONG cb; 
    DWORD dwExtentMode; 
    SIZEL sizelProposed; 
} DVEXTENTINFO;

Members

cb

Size of the structure in bytes. The size includes this member as well as the dwExtentMode and sizelProposed members.

dwExtentMode

Indicates whether the sizing mode is content or integral sizing. See the DVEXTENTMODE enumeration for these values.

sizelProposed

Specifies the proposed size in content sizing or the preferred size in integral sizing.

See Also

DVEXTENTMODE

17.6.3    DVTARGETDEVICE

Use the DVTARGETDEVICE structure to specify information about the target device for which data is being composed. DVTARGETDEVICE contains enough information about a Windows target device so a handle to a device context (hDC) can be created using the Windows CreateDC function.

typedef struct tagDVTARGETDEVICE 
{ 
    DWORD tdSize; 
    WORD  tdDriverNameOffset; 
    WORD  tdDeviceNameOffset; 
    WORD  tdPortNameOffset; 
    WORD  tdExtDevmodeOffset; 
    BYTE  tdData[1]; 
} DVTARGETDEVICE;

Members

tdSize

Size, in bytes, of the DVTARGETDEVICE structure. The initial size is included so the structure can be copied more easily.

tdDriverNameOffset

Offset, in bytes, from the beginning of the structure to the device driver name, which is stored as a NULL-terminated string in the tdData buffer.

tdDeviceNameOffset

Offset, in bytes, from the beginning of the structure to the device name, which is stored as a NULL-terminated string in the tdData buffer. This value can be zero to indicate no device name.

tdPortNameOffset

Offset, in bytes, from the beginning of the structure to the port name, which is stored as a NULL-terminated string in the tdData buffer. This value can be zero to indicate no port name.

tdExtDevmodeOffset

Offset, in bytes, from the beginning of the structure to the DEVMODE structure retrieved by calling ExtDeviceMode.

tdData

Aray of bytes containing data for the target device. It is not necessary to include empty strings in tdData (for names where the offset value is zero).

Description

Some OLE 1 client applications incorrectly construct target devices by allocating too few bytes in the DEVMODE structure for the OLETARGETDEVICE. They typically only supply the number of bytes in the DEVMODE.dmSize member. The number of bytes to be allocated should be the sum of DEVMODE.dmSize + DEVMODE.dmDriverExtra. When a call is made to the CreateDC function with an incorrect target device, the printer driver tries to access the additional bytes and unpredictable results can occur. To protect against a crash and make the additional bytes available, COM pads the size of COM target devices created from OLE 1 target devices.

See Also

FORMATETC, IEnumFORMATETC(), IViewObject, OleConvertOLESTREAMToIStorage

17.6.4    FORMATETC

The FORMATETC structure is a generalized Clipboard format. It is enhanced to encompass a target device, the aspect or view of the data, and a storage medium indicator. Where one might expect to find a Clipboard format, COM uses a FORMATETC data structure instead. This structure is used as a parameter in COM functions and methods that require data format information.

<Defined in the IEnumFORMATETC() interface.>

typedef struct tagFORMATETC 
{ 
    CLIPFORMAT      cfFormat; 
    DVTARGETDEVICE  *ptd; 
    DWORD           dwAspect; 
    LONG            lindex; 
    DWORD           tymed; 
} FORMATETC, *LPFORMATETC;

Members

cfFormat

Particular clipboard format of interest. There are three types of formats recognized by COM:

ptd

Pointer to a DVTARGETDEVICE structure containing information about the target device for which the data is being composed. A NULL value is used whenever the specified data format is independent of the target device or when the caller doesn't care what device is used. In the latter case, if the data requires a target device, the object should pick an appropriate default device (often the display for visual components). Data obtained from an object with a NULL target device, such as most metafiles, is independent of the target device. The resulting data is usually the same as it would be if the user chose the Save As command from the File menu and selected an interchange format.

dwAspect

One of the DVASPECT enumeration constants that indicate how much detail should be contained in the rendering. A single clipboard format can support multiple aspects or views of the object. Most data and presentation transfer and caching methods pass aspect information. For example, a caller might request an object's iconic picture, using the metafile clipboard format to retrieve it. Note that only one DVASPECT value can be used in dwAspect. That is, dwAspect cannot be the result of a BOOLEAN OR operation on several DVASPECT values.

lindex

Part of the aspect when the data must be split across page boundaries. The most common value is -1, which identifies all of the data. For the aspects DVASPECT_THUMBNAIL and DVASPECT_ICON, lindex is ignored.

tymed

One of the TYMED enumeration constants which indicate the type of storage medium used to transfer the object's data. Data can be transferred using whatever medium makes sense for the object. For example, data can be passed using global memory, a disk file, or structured storage objects. For more information, see the TYMED enumeration.

Description

The FORMATETC structure is used by methods in the data transfer and presentation interfaces as a parameter specifying the data being transferred. For example, the IDataObject::GetData() method uses the FORMATETC structure to indicate exactly what kind of data the caller is requesting.

See Also

DVASPECT, IDataAdviseHolder(), IDataObject(), IEnumFORMATETC(), STATDATA, STGMEDIUM, TYMED

17.6.5    STATDATA

The STATDATA structure is the data structure used to specify each advisory connection. It is used for enumerating current advisory connections. It holds data returned by the IEnumSTATDATA() enumerator. This enumerator interface is returned by IDataObject:DAdvise. Each advisory connection is specified by a unique STATDATA structure.

<Defined in com.h.>

typedef struct tagSTATDATA 
{ 
    FORMATETC     formatetc; 
    DWORD         grfAdvf; 
    IAdviseSink*  pAdvSink; 
    DWORD         dwConnection; 
} STATDATA;

Members

formatetc

The FORMATETC structure for the data of interest to the advise sink. The advise sink receives notification of changes to the data specified by this FORMATETC structure.

grfAdvf

The ADVF enumeration value that determines when the advisory sink is notified of changes in the data.

pAdvSink

The pointer for the IAdviseSink() interface that will receive change notifications.

dwConnection

The token that uniquely identifies the advisory connection. This token is returned by the method that sets up the advisory connection.

See Also

IEnumSTATDATA()

17.6.6    STGMEDIUM

The STGMEDIUM structure is a generalized global memory handle used for data transfer operations by the IAdviseSink() and IDataObject() interfaces.

<Defined in the IAdviseSink() interface (advsnk.idl).>

typedef struct tagSTGMEDIUM 
{ 
    DWORD tymed; 
    [switch_type(DWORD), switch_is((DWORD) tymed)] 
    union { 
        [case(TYMED_GDI)]      HBITMAP        hBitmap; 
        [case(TYMED_MFPICT)]   HMETAFILEPICT  hMetafilePict; 
        [case(TYMED_ENHMF)]    HENHMETAFILE   hEnhMetaFile; 
        [case(TYMED_HGLOBAL)]  HGLOBAL        hGlobal; 
        [case(TYMED_FILE)]     LPWSTR         lpszFileName; 
        [case(TYMED_ISTREAM)]  IStream        *pstm; 
        [case(TYMED_ISTORAGE)] IStorage       *pstg; 
        [default] ; 
    }; 
    [unique] IUnknown *pUnkForRelease; 
} STGMEDIUM; 
typedef STGMEDIUM *LPSTGMEDIUM;

Members

tymed

Type of storage medium. The marshaling and unmarshaling routines use this value to determine which union member was used. This value must be one of the elements of the TYMED enumeration.

union member

Handle, string, or interface pointer that the receiving process can use to access the data being transferred. If tymed is TYMED_NULL, the union member is undefined; otherwise, it is one of the following:

hBitmap

Bitmap handle. The tymed member is TYMED_GDI.

hMetafilePict

Metafile handle. The tymed member is TYMED_MFPICT.

hEnhMetaFile

Enhanced metafile handle. The tymed member is TYMED_ENHMF.

hGlobal

Global memory handle. The tymed member is TYMED_HGLOBAL.

lpszFileName

Pointer to the path of a disk file that contains the data. The tymed member is TYMED_FILE.

pstm

Pointer to an IStream() interface. The tymed member is TYMED_ISTREAM.

pstg

Pointer to an IStorage() interface. The tymed member is TYMED_ISTORAGE.

pUnkForRelease

Pointer to an interface instance that allows the sending process to control the way the storage is released when the receiving process calls the ReleaseStgMedium() function. If pUnkForRelease is NULL, ReleaseStgMedium() uses default procedures to release the storage; otherwise, ReleaseStgMedium() uses the specified IUnknown() interface.

See Also

FORMATETC, IAdviseSink(), IDataObject(), ReleaseStgMedium()

17.7    Uniform Data Transfer Enumeration Descriptions

17.7.1    ADVF

The ADVF enumeration values are flags used by a container object to specify the requested behavior when setting up an advise sink or a caching connection with an object. These values have different meanings, depending on the type of connection in which they are used, and each interface uses its own subset of the flags.

typedef enum tagADVF 
{ 
    ADVF_NODATA            = 1, 
    ADVF_ONLYONCE          = 2, 
    ADVF_PRIMEFIRST        = 4, 
    ADVFCACHE_NOHANDLER    = 8, 
    ADVFCACHE_FORCEBUILTIN = 16, 
    ADVFCACHE_ONSAVE       = 32,
    ADVF_DATAONSTOP        = 64
} ADVF;

Elements

ADVF_NODATA

For data advisory connections (IDataObject::DAdvise() or IDataAdviseHolder::Advise()), this flag requests the data object not to send data when it calls IAdviseSink::OnDataChange(). The recipient of the change notification can later request the data by calling IDataObject::GetData(). The data object can honor the request by passing TYMED_NULL in the STGMEDIUM parameter, or it can provide the data anyway. For example, the data object might have multiple advisory connections, not all of which specified ADVF_NODATA, in which case the object might send the same notification to all connections. Regardless of the container's request, its IAdviseSink() implementation must check the STGMEDIUM parameter because it is responsible for releasing the medium if it is not TYMED_NULL.

ADVF_NODATA is not a valid flag for view advisory connections (IViewObject::SetAdvise) and it returns E_INVALIDARG.

ADVF_PRIMEFIRST

Requests that the object not wait for the data or view to change before making an initial call to IAdviseSink::OnDataChange() (for data or view advisory connections) or updating the cache (for cache connections). Used with ADVF_ONLYONCE, this parameter provides an asynchronous GetData call.

ADVF_ONLYONCE

Requests that the object make only one change notification or cache update before deleting the connection.

ADVF_ONLYONCE automatically deletes the advisory connection after sending one data or view notification. The advisory sink receives only one IAdviseSink() call. A nonzero connection identifier is returned if the connection is established, so the caller can use it to delete the connection prior to the first change notification.

For data change notifications, the combination of ADVF_ONLYONCE and ADVF_PRIMEFIRST provides, in effect, an asynchronous IDataObject::GetData() call.

When used with caching, ADVF_ONLYONCE updates the cache one time only, on receipt of the first OnDataChange notification. After the update is complete, the advisory connection between the object and the cache is disconnected. The source object for the advisory connection calls the IAdviseSink::Release() method.

ADVF_DATAONSTOP

For data advisory connections, assures accessibility to data. This flag indicates that when the data object is closing, it should call IAdviseSink::OnDataChange(), providing data with the call. Typically, this value is used in combination with ADVF_NODATA. Without this value, by the time an OnDataChange call without data reaches the sink, the source might have completed its shutdown and the data might not be accessible. Sinks that specify this value should accept data provided in OnDataChange if it is being passed, because they may not get another chance to retrieve it.

For cache connections, this flag indicates that the object should update the cache as part of object closure.

ADVF_DATAONSTOP is not a valid flag for view advisory connections.

ADVFCACHE_NOHANDLER

Synonym for ADVFCACHE_FORCEBUILTIN, which is used more often.

ADVFCACHE_FORCEBUILTIN

This value is used by DLL object applications and object handlers that perform the drawing of their objects. ADVFCACHE_FORCEBUILTIN instructs COM to cache presentation data to ensure that there is a presentation in the cache. This value is not a valid flag for data or view advisory connections. For cache connections, this flag caches data that requires only code shipped with COM (or the underlying operating system) to be present in order to produce it with IDataObject::GetData() or IViewObject::Draw. By specifying this value, the container can ensure that the data can be retrieved even when the object or handler code is not available.

ADVFCACHE_ONSAVE

For cache connections, this flag updates the cached representation only when the object containing the cache is saved. The cache is also updated when the COM object transitions from the running state back to the loaded state (because a subsequent save operation would require rerunning the object). This value is not a valid flag for data or view advisory connections.

Description

For a data or view advisory connection, the container uses the ADVF constants when setting up a connection between an IAdviseSink() instance and and either an IDataObject() or IViewObject instance. These connections are set up using the IDataObject::DAdvise(), IDataAdviseHolder::Advise(), or IViewObject::SetAdvise methods.

These constants are also used in the advf member of the STATDATA structure. This structure is used by IEnumSTATDATA() to describe the enumerated connections, and the advf member indicates the flags that were specified when the advisory or cache connection was established. When STATDATA is used for an IOleObject::EnumAdvise enumerator, the advf member is indeterminate.

See Also

IDataAdviseHolder(), IDataObject(), IEnumSTATDATA()

17.7.2    DATADIR

The DATADIR enumeration values specify the direction of the data flow in the dwDirection parameter of the IDataObject::EnumFormatEtc() method. This determines the formats that the resulting enumerator can enumerate.

typedef enum tagDATADIR 
{ 
    DATADIR_GET            = 1, 
    DATADIR_SET            = 2 
} DATADIR;

Elements

DATADIR_GET

Requests that IDataObject::EnumFormatEtc() supply an enumerator for the formats that can be specified in IDataObject::GetData().

DATADIR_SET

Requests that IDataObject::EnumFormatEtc() supply an enumerator for the formats that can be specified in IDataObject::SetData().

See Also

IDataObject()

17.7.3    DVASPECT

The DVASPECT enumeration values specify the desired data or view aspect of the object when drawing or getting data.

typedef enum tagDVASPECT 
{ 
    DVASPECT_CONTENT    = 1, 
    DVASPECT_THUMBNAIL  = 2, 
    DVASPECT_ICON       = 4, 
    DVASPECT_DOCPRINT   = 8 
} DVASPECT;

Elements

DVASPECT_CONTENT

Provides a representation of an object so it can be displayed as an embedded object inside of a container. This value is typically specified for compound document objects. The presentation can be provided for the screen or printer.

DVASPECT_THUMBNAIL

Provides a thumbnail representation of an object so it can be displayed in a browsing tool. The thumbnail is approximately a 120 by 120 pixel, 16-color (recommended) device-independent bitmap potentially wrapped in a metafile.

DVASPECT_ICON

Provides an iconic representation of an object.

DVASPECT_DOCPRINT

Provides a representation of the object on the screen as though it were printed to a printer using the Print command from the File menu. The described data may represent a sequence of pages.

Description

Values of this enumeration are used to define the dwAspect field of the FORMATETC structure. Only one DVASPECT value can be used to specify a single presentation aspect in a FORMATETC structure. The FORMATETC structure is used in many COM functions and interface methods that require information on data presentation.

See Also

IAdviseSink(), IDataObject(), FORMATETC

17.7.4    DVASPECT2

The DVASPECT2 enumeration value is used in IViewObject::Draw to specify new drawing aspects used to optimize the drawing process.

typedef enum tagDVASPECT2 
{ 
    DVASPECT_OPAQUE         = 16, 
    DVASPECT_TRANSPARENT    = 32 
} DVASPECT2;

Elements

DVASPECT_OPAQUE

Represents the opaque, easy to clip parts of an object. Objects may or may not support this aspect.

DVASPECT_TRANSPARENT

Represents the transparent or irregular parts of on object, typically parts that are expensive or impossible to clip out. Objects may or may not support this aspect.

Description

To support drawing optimizations to reduce flicker, an object needs to be able to draw and return information about three separate aspects of itself:

DVASPECT_CONTENT

Same as before. Specifies the entire content of an object. All objects should support this aspect.

DVASPECT_OPAQUE

Represents the opaque, easy to clip parts of an object. Objects may or may not support this aspect.

DVASPECT_TRANSPARENT

Represents the transparent or irregular parts of on object, typically parts that are expensive or impossible to clip out. Objects may or may not support this aspect.

The container can determine which of these drawing aspects an object supports by calling the new method IViewObjectEx::GetViewStatus. Individual bits return information about which aspects are supported. If an object does not support the IViewObjectEx interface, it is assumed to support only DVASPECT_CONTENT.

Depending on which aspects are supported, the container can ask the object to draw itself during the front to back pass only, the back to front pass only, or both. The various possible cases are:

Even when DVASPECT_OPAQUE and DVASPECT_TRANSPARENT are supported, the container is free to use these aspects or not. In particular, if it is painting in an offscreen bitmap and consequently is unconcerned about flicker, the container may use DVASPECT_CONTENT and a one-pass drawing only. However, in a two-pass drawing, if the container uses DVASPECT_OPAQUE during the front to back pass, then it must use DVASPECT_TRANSPARENT during the back to front pass to complete the rendering of the object.

17.7.5    DVASPECTINFOFLAG

The DVASPECTINFOFLAG enumeration value is used in the DVASPECTINFO structure to indicate whether an object can support optimized drawing of itself.

typedef enum tagDVASPECTINFOFLAG 
{ 
    DVASPECTINFOFLAG_CANOPTIMIZE    = 1 
} DVASPECTINFOFLAG;

Elements

DVASPECTINFOFLAG_CANOPTIMIZE

If TRUE, indicates that the object can support optimized rendering of itself. Since most objects on a form share the same font, background color, and border types, leaving these values in the device context allows the next object to use them without having to re-select them. Specifically, the object can leave the font, brush, and pen selected on return from the IViewObject::Draw method instead of deselecting these from the device context. The container then must deselect these values at the end of the overall drawing process. The object can also leave other drawing state changes in the device context, such as the background color, the text color, raster operation code, the current point, the line drawing, and the poly fill mode. The object cannot change state values unless other objects are capable of restoring them. For example, the object cannot leave a changed mode, transformation value, selected bitmap, clip region, or metafile.

See Also

DVASPECTINFO

17.7.6    STATFLAG

The STATFLAG enumeration values indicate whether the method should try to return a name in the pwcsName member of the STATSTG structure. The values are used in the ILockBytes::Stat(), IStorage::Stat(), and IStream::Stat() methods to save memory when the pwcsName member is not needed.

Defined in the IOLETypes pseudo-interface (oletyp.idl).

typedef enum tagSTATFLAG 
{ 
    STATFLAG_DEFAULT    = 0, 
    STATFLAG_NONAME     = 1 
} STATFLAG;

Elements

STATFLAG_DEFAULT

Requests that the statistics include the pwcsName member of the STATSTG structure.

STATFLAG_NONAME

Requests that the statistics not include the pwcsName member of the STATSTG structure. If the name is omitted, there is no need for the Stat methods to allocate and free memory for the string value for the name and the method can save an Alloc and Free operation.

See Also

ILockBytes::Stat(), IStorage::Stat(), IStream::Stat()

17.7.7    TYMED

The TYMED enumeration values indicate the type of storage medium being used in a data transfer. They are used in the STGMEDIUM or FORMATETC structures.

typedef [transmit_as(long)] enum tagTYMED 
{ 
    TYMED_HGLOBAL     = 1, 
    TYMED_FILE        = 2, 
    TYMED_ISTREAM     = 4, 
    TYMED_ISTORAGE    = 8, 
    TYMED_GDI         = 16, 
    TYMED_MFPICT      = 32, 
    TYMED_ENHMF       = 64, 
    TYMED_NULL        = 0 
} TYMED;

Elements

TYMED_HGLOBAL

The storage medium is a global memory handle (HGLOBAL). Allocate the global handle with the GMEM_SHARE flag. If the STGMEDIUM punkForRelease member is NULL, the destination process should use GlobalFree to release the memory.

TYMED_FILE

The storage medium is a disk file identified by a path. If the STGMEDIUM punkForRelease member is NULL, the destination process should use OpenFile to delete the file.

TYMED_ISTREAM

The storage medium is a stream object identified by an IStream() pointer. Use IStream::Read() to read the data. If the STGMEDIUM punkForRelease member is NULL, the destination process should use IStream::Release() to release the stream component.

TYMED_ISTORAGE

The storage medium is a storage component identified by an IStorage() pointer. The data is in the streams and storages contained by this IStorage() instance. If the STGMEDIUM punkForRelease member is NULL, the destination process should use IStorage::Release() to release the storage component.

TYMED_GDI

The storage medium is a GDI component (HBITMAP). If the STGMEDIUM punkForRelease member is NULL, the destination process should use DeleteObject to delete the bitmap.

TYMED_MFPICT

The storage medium is a metafile (HMETAFILE). If the STGMEDIUM punkForRelease member is NULL, the destination process should use DeleteMetaFile to delete the bitmap.

TYMED_ENHMF

The storage medium is an enhanced metafile. If the STGMEDIUM punkForRelease member is NULL, the destination process should use DeleteEnhMetaFile to delete the bitmap.

TYMED_NULL

No data is being passed.

Description

During data transfer operations, a storage medium is specified. This medium must be released after the data transfer operation. The provider of the medium indicates its choice of ownership scenarios in the value it provides in the STGMEDIUM structure. A NULL value for the IUNKNOWN field indicates that the receiving body of code owns and can free the medium. A non-NULL pointer specifies that ReleaseStgMedium() can always be called to free the medium.

See Also

FORMATETC, IAdviseSink(), IDataObject(), ReleaseStgMedium(), STGMEDIUM