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.
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 interfaces
along 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.
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
.
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
IDataObject
to 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:
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. |
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.
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:
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
.
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.
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.
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.
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.
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()
.
|
Description
|
QueryInterface()
|
Returns pointers to supported interfaces. |
AddRef()
|
Increments reference count. |
Release()
|
Decrements reference count. |
|
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. |
IAdviseSink2
,
IDataAdviseHolder()
- Called by the server to notify all registered advisory sinks that the object
has
changed from the running to the loaded state.
IAdviseSink::OnClose()
Void OnClose(
#include <objidl.h>
);
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.
- Called by the server to notify a data object's currently registered
advise sinks
that data in the object has changed.
IAdviseSink::OnDataChange()
void OnDataChange(
#include <objidl.h>
FORMATETC * pFormatetc,
STGMEDIUM * pStgmed
);
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.
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.
[in] Pointer to the
FORMATETC
structure, which describes the format, target
device, rendering, and storage
information of the calling data object.
[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.
- Called by the server to notify all registered advisory sinks that
the
object has been renamed.
IAdviseSink::OnRename()
Void OnRename(
#include <objidl.h>
IMoniker * pmk
);
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.
[in] Pointer to the
IMoniker()
interface
on the new
full moniker of the object.
- Called by the server to notify all registered advisory sinks that the
object has been saved.
IAdviseSink::OnSave()
Void OnSave(
#include <objidl.h>
);
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.
- Notifies an object's registered advise sinks that its view has
changed.
IAdviseSink::OnViewChange()
Void OnViewChange(
#include <objidl.h>
DWORD dwAspect,
LONG lindex
);
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.
[in] The aspect, or view, of the object.
Contains a value
taken from
the enumeration,
DVASPECT
.
[in] The portion of the view that has changed. Currently only -1 is valid.
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.
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.
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.
IUnknown Methods
|
Description
|
QueryInterface()
|
Returns pointers to supported interfaces. |
AddRef()
|
Increments reference count. |
Release()
|
Decrements reference count. |
|
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. |
- Creates a connection between an advise sink and a data object
for receiving notifications.
IDataAdviseHolder::Advise()
HRESULT Advise(
#include <objidl.h>
IDataObject * pDataObject,
FORMATETC * pFormatetc,
DWORD advf,
IAdviseSink * pAdvSink,
DWORD * pdwConnection
);
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()
.
[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.
[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.
[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.
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.
This method supports the standard return value
E_INVALIDARG
, as well as
the following:
S_OK
The advisory connection was created.
ADVF
,
CreateDataAdviseHolder
,
FORMATETC
,
IDataAdviseHolder::Unadvise()
,
IDataObject::DAdvise()
- Returns a pointer to an IEnumStatdata interface on an enumeration
object that can be used to enumerate the current advisory connections.
IDataAdviseHolder::EnumAdvise()
HRESULT EnumAdvise(
#include <objidl.h>
IEnumSTATDATA ** ppenumAdvise
);
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.
[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.
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.
IEnum
XXXX,
IEnumSTATDATA()
,
IDataObject::EnumDAdvise()
- Sends notifications to each advise sink for which there is a connection
established by calling the
IDataAdviseHolder::SendOnDataChange()
IAdviseSink::OnDataChange()
method for each advise sink currently being handled by this instance of the
advise holder object.
HRESULT SendOnDataChange(
#include <objidl.h>
IDataObject * pDataObject,
DWORD dwReserved,
DWORD advf
);
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.
[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()
.
[in] Reserved for future use; must be zero.
[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
.
This method supports the standard return value
E_OUTOFMEMORY
, as well as
the following:
S_OK
The call to
IAdviseSink::OnDataChange()
was made.
ADVF
,
IAdviseSink::OnDataChange()
- Removes a connection between a data object and an advisory sink
that was set up through a previous call to
IDataAdviseHolder::Unadvise()
IDataAdviseHolder::Advise()
.
IDataAdviseHolder::Unadvise()
is typically
called in the implementation of
IDataObject::DUnadvise()
.
HRESULT Unadvise(
#include <objidl.h>
DWORD dwConnection
);
[in]
DWORD
token that specifies the connection
to
remove.
This value was returned by
IDataAdviseHolder::Advise()
when the connection was originally established.
S_OK
The specified connection was successfully deleted.
OLE_E_NOCONNECTION
The specified dwConnection is not a valid connection.
IDataAdviseHolder::Advise()
,
IDataObject::DUnadvise()
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.
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.
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.
IUnknown Methods
|
Description
|
QueryInterface()
|
Returns pointers to supported interfaces. |
AddRef()
|
Increments reference count. |
Release()
|
Decrements reference count. |
|
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. |
- 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.
IDataObject::DAdvise()
HRESULT DAdvise(
#include <objidl.h>
FORMATETC * pFormatetc,
DWORD advf,
IAdviseSink * pAdvSink,
DWORD * pdwConnection
);
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()
.
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.
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.
[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.
[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.
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. |
[in] Pointer to the
IAdviseSink()
interface
on the
advisory sink
that will receive the change notification.
[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.
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.
ADVF
,
FORMATETC
,
CreateDataAdviseHolder
,
IDataAdviseHolder - OLE
implementation>
,
IAdviseSink::OnDataChange()
,
IDataObject::DUnAdvise()
- Destroys a notification connection that had been previously set
up.
IDataObject::DUnadvise()
HRESULT DUnadvise(
#include <objidl.h>
DWORD dwConnection
);
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.
[in]
DWORD
token that specifies the connection
to
remove.
Use the value returned by
IDataObject::DAdvise()
when the connection was originally established.
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.
IDataObject::DAdvise()
,
IDataAdviseHolder::Unadvise()
- Creates an object that can be used to enumerate the current advisory
connections.
IDataObject::EnumDAdvise()
HRESULT EnumDAdvise(
#include <objidl.h>
IEnumSTATDATA ** ppenumAdvise
);
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.
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.
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.
[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.
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.
IEnumSTATDATA()
,
IDataAdviseHolder::EnumAdvise()
- Creates an object for enumerating the FORMATETC structures for
a data object.
These structures are used in calls to
IDataObject::EnumFormatEtc()
IDataObject::GetData()
or
IDataObject::SetData()
.
HRESULT EnumFormatEtc(
#include <objidl.h>
DWORD dwDirection,
IEnumFORMATETC ** ppenumFormatetc
);
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;
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:
An application calls
OleSetClipboard
.
COM
must determine
what data to place on the Clipboard and whether it is necessary to put COM
1
compatibility formats on the Clipboard.
Data is being pasted from the Clipboard or dropped. An application uses the first acceptable format.
The Paste Special dialog box is displayed.
The target application
builds
the list of formats from the
FORMATETC
entries.
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.
[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()
.
[out] Indirect pointer to the
IEnumFORMATETC()
interface
on the new enumerator object.
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.
FORMATETC
,
IEnumFormatEtc
,
IDataObject::SetData()
,
IDataObject::GetData()
- Provides a standard
IDataObject::GetCanonicalFormatEtc()
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.
HRESULT GetCanonicalFormatEtc(
#include <objidl.h>
FORMATETC * pFormatetcIn,
FORMATETC * pFormatetcOut
);
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.
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()
.
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
.
[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.
[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.
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.
IDataObject::GetData()
,
FORMATETC
- Called by a data consumer to obtain data from a source data object.
The
IDataObject::GetData()
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.
HRESULT GetData(
#include <objidl.h>
FORMATETC * pFormatetc,
STGMEDIUM * pmedium
);
A data consumer calls
IDataObject::GetData()
to retrieve
data from
a data object, conveyed through a storage medium (defined through the
STGMEDIUM
structure).
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).
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.
[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.
[out] Pointer to the
STGMEDIUM
structure
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()
.
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.
IDataObject::GetDataHere()
,
IDataObject::SetData()
,
FORMATETC
,
STGMEDIUM
- 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.
IDataObject::GetDataHere()
HRESULT GetDataHere(
#include <objidl.h>
FORMATETC * pFormatetc,
STGMEDIUM * pmedium
);
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.
[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
.
[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.
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.
IDataObject::GetData()
,
FORMATETC
,
STGMEDIUM
- Determines whether the data object is capable of rendering the
data described in the
IDataObject::QueryGetData()
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.
HRESULT QueryGetData(
#include <objidl.h>
FORMATETC * pFormatetc
);
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.
[in] Pointer to the
FORMATETC
structure
defining
the format, medium, and target device to use for the query.
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.
IDataObject::GetData()
,
FORMATETC
- Called by an object containing a data source to transfer data to the object
that implements this method.
IDataObject::SetData()
HRESULT SetData(
#include <objidl.h>
FORMATETC * pFormatetc,
STGMEDIUM * pmedium,
BOOL fRelease
);
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.
[in] Pointer to the
FORMATETC
structure
defining
the format used by the data object when interpreting the data contained in
the storage medium.
[in] Pointer to the
STGMEDIUM
structure
defining
the storage medium in which the data is being passed.
[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.
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.
IDataObject::GetData()
,
FORMATETC
,
STGMEDIUM
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()
.
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
GetData
method 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
.
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:
HRESULT Next(
#include <objidl.h>
ULONG celt,
FORMATETC * rgelt,
ULONG * pceltFetched
);
HRESULT Skip(
#include <objidl.h>
ULONG celt
);
HRESULT Reset(
#include <objidl.h>
void
);
HRESULT Clone(
#include <objidl.h>
IEnumFORMATETC ** ppenum
);
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()
.
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:
In a data object, call
CreateDataAdviseHolder
to get a pointer to
the COM data advise holder object, and then, to implement
IDataObject::EnumDAdvise()
, call
IDataAdviseHolder::EnumAdvise()
,
which creates the enumeration object and supplies a pointer to the
implementation of
IEnumSTATDATA()
.
In a compound document object, call
CreateOLEAdviseHolder
to get a
pointer to the COM advise holder object.
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:
HRESULT Next(
#include <objidl.h>
ULONG celt,
STATDATA * rgelt,
ULONG * pceltFetched
);
HRESULT Skip(
#include <objidl.h>
ULONG celt
);
HRESULT Reset(
#include <objidl.h>
void
);
HRESULT Clone(
#include <objidl.h>
IEnumSTATDATA ** ppenum
);
STATDATA
,
IEnum
XXXX,
IDataObject::EnumDAdvise()
,
IDataAdviseHolder::EnumAdvise()
- Supplies a pointer to the COM implementation of
CreateDataAdviseHolder()
IDataAdviseHolder()
on the data advise holder object.
WINOLEAPI CreateDataAdviseHolder(
#include <objbase.h>
IDataAdviseHolder ** ppDAHolder
);
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.
[out] Address of
IDataAdviseHolder*
pointer
variable
that receives the
interface pointer to the new advise holder object.
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.
- Creates an object that implements
CreateFormatEnumerator()
IEnumFORMATETC()
over a static array of FORMATETC structures.
HRESULT CreateFormatEnumerator(
#include <objbase.h>
UINT cfmtetc,
FORMATETC * rgfmtetc,
IenumFORMATETC ** ppenumfmtetc
);
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
IEnum
XXX
reference.
[in] Number of
FORMATETC
structures in
the static
array specified by the
rgfmtetc
parameter.
The
cfmtetc
parameter cannot be zero.
[in] Pointer to a static array of
FORMATETC
structures.
[out] Address of
IEnumFORMATETC*
pointer
variable
that receives the interface pointer
to the enumerator object.
S_OK
The operation was successful.
E_INVALIDARG
One or more parameters are invalid.
- Frees the specified storage medium.
ReleaseStgMedium()
void ReleaseStgMedium((
#include <ole2.h>
STGMEDIUM * pmedium
);
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:
Medium
|
|
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:
Medium
|
|
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.
[in] Pointer to the storage medium that is to be freed.
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;
Size of the structure in bytes. The size includes this member as well as the dwFlags member.
A value taken from the
DVASPECTINFOFLAG
enumeration.
The
DVEXTENTINFO
structure is used in
IViewObjectEx::GetNaturalExtent
.
typedef struct tagDVEXTENTINFO { ULONG cb; DWORD dwExtentMode; SIZEL sizelProposed; } DVEXTENTINFO;
Size of the structure in bytes. The size includes this member as well as the dwExtentMode and sizelProposed members.
Indicates whether the sizing mode is content or integral sizing.
See
the
DVEXTENTMODE
enumeration for these values.
Specifies the proposed size in content sizing or the preferred size in integral sizing.
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;
Size, in bytes, of the
DVTARGETDEVICE
structure.
The initial size is included so the structure can be copied more easily.
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.
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.
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.
Offset, in bytes, from the beginning of the structure to the
DEVMODE
structure retrieved by calling
ExtDeviceMode
.
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).
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.
FORMATETC
,
IEnumFORMATETC()
,
IViewObject
,
OleConvertOLESTREAMToIStorage
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;
Particular clipboard format of interest. There are three types of formats recognized by COM:
Standard interchange formats, such as
CF_TEXT
.
Private application formats understood only by the application offering the format, or by other applications offering similar features.
COM formats, which are used to create linked or embedded objects.
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.
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.
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.
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.
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.
DVASPECT
,
IDataAdviseHolder()
,
IDataObject()
,
IEnumFORMATETC()
,
STATDATA
,
STGMEDIUM
,
TYMED
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.
typedef struct tagSTATDATA { FORMATETC formatetc; DWORD grfAdvf; IAdviseSink* pAdvSink; DWORD dwConnection; } STATDATA;
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.
The
ADVF
enumeration value that determines
when the
advisory sink is notified of changes in the data.
The pointer for the
IAdviseSink()
interface
that
will receive change notifications.
The token that uniquely identifies the advisory connection. This token is returned by the method that sets up the advisory connection.
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;
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.
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:
Bitmap handle.
The
tymed
member is
TYMED_GDI
.
Metafile handle.
The
tymed
member is
TYMED_MFPICT
.
Enhanced metafile handle.
The
tymed
member
is
TYMED_ENHMF
.
Global memory handle.
The
tymed
member
is
TYMED_HGLOBAL
.
Pointer to the path of a disk file that contains the data.
The
tymed
member is
TYMED_FILE
.
Pointer to an
IStream()
interface.
The
tymed
member is
TYMED_ISTREAM
.
Pointer to an
IStorage()
interface.
The
tymed
member is
TYMED_ISTORAGE
.
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.
FORMATETC
,
IAdviseSink()
,
IDataObject()
,
ReleaseStgMedium()
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;
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
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.
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.
IDataAdviseHolder()
,
IDataObject()
,
IEnumSTATDATA()
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;
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()
.
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;
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.
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.
IAdviseSink()
,
IDataObject()
,
FORMATETC
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;
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.
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:
Objects supporting only
DVASPECT_CONTENT
should be drawn during the back
to front pass, with all opaque parts of any overlapping object clipped out.
Since all objects should support this aspect, a container not concerned about
flickering--maybe because it is drawing in an offscreen bitmap--can
opt to
draw all objects that way and skip the front to back pass.
Objects supporting
DVASPECT_OPAQUE
may
be asked to draw this aspect during
the front to back pass.
The container is responsible for clipping out the
object's opaque regions (returned by
IViewObjectEx::GetRegion
)
before
painting any further object behind it.
Objects supporting
DVASPECT_TRANSPARENT
may be asked to draw this aspect
during the back to front pass.
The container is responsible for clipping out
opaque parts of overlapping objects before letting an object draw this
aspect.
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.
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;
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.
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;
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.
ILockBytes::Stat()
,
IStorage::Stat()
,
IStream::Stat()
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;
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.
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.
FORMATETC
,
IAdviseSink()
,
IDataObject()
,
ReleaseStgMedium()
,
STGMEDIUM