OLE Clipboard



ERDI Gergo asked me to talk about how the OLE clipboard works.

> And re: my original question, will we pass moniker strings on the
> clipboard, or IORs of currently running monikers?
> How is this working in COM-land?

The OLE clipboard stores an IDataObject interface pointer.  The two most
important methods of IDataObject are GetData and SetData.  The SetData
method takes a FORMATETC struct and a STGMEDIUM struct.  

FORMATETC tells "what and how" the data should be stored in the
clipboard, the STGMEDIUM actually contains the handle (or interface ptr)
to the data.

The "setting" code looks like:

// setup formatetc and stg_medium
data_object->SetData(&formatetc, &stg_medium, FALSE);
::OleSetClipboard(data_object);
data_object->Release();

The "getting" code looks like:

// setup formatetc
::OleGetClipboard(&data_object);
data_object->GetData(&formatetc, &stgmedium);
// do stuff with stgmedium data
::ReleaseStgMedium(&stgmedium);

The STGMEDIUM struct's pUnkForRelease (IUnknown ptr) member is how the
OLE clipboard manages the stored component's lifetime.

When you call ::OleSetClipboard on the component implementing
IDataObject, AddRef is called.  So calling data_object->Release() is not
actually deleting the clipboard data, only the local code's reference to
it.

ReleaseStgMedium either calls Release on the supplied STGMEDIUM's
pUnkForRelease member, or if pUnkForRelease is NULL, it frees the data
based on the STGMEDIUM's type member.

Note that the IDataObject pointer you get from ::OleGetClipboard is not
the same thing you set it to.  It is wrapped by another IDataObject
which allows for backwards compatibility with the old-school, in-memory
win32 clipboard.  Maybe something similar can be done with the X
clipboard?

MFC wraps the clipboard code in COleDataObject and COleDataSource to
make things slightly less ugly for clients.  IIRC, ATL also has a
IDataObjectImpl class.

I read through the threads on clipboard stuff, and here is how
IDataObject answers some of the concerns people have:

Jens Finke <jens eknif de>:
> As far as I understand this doesn't solve the problem of modifying the
> region after you copied it to the clipboard. With this solution the
> clipboard then stores the modified image, which isn't what you want.

The DAdvise method in IDataObject lets you set an IAdviseSink -- a way
of notifying clients when the data object changes.

martin <textshell t-online de>:
> - Some data is really huge (scanned images)
> => you don't want to copy those around more than
> needed.

Your implementation of the IDataObject determines how you want to handle
big data.

> - Multiple data formats

You set the type of the STGMEDIUM struct.  If it's something really
complex, you can use the ISTREAM type or whatever.  Monikers, however,
seem like alot cleaner way to go.

I don't know much at all about the X Clipboard, but if all it can do is
store a string, it won't work with moniker strings.  If the moniker
string in the X clipboard were to get overwritten with some other junk,
there'd be a dangling reference.

Monikers are a really cool way of making the STGMEDIUM type ugliness go
away, but they create a few more problems:

Michael Meeks <michael ximian dot com>:
> > Linking to unsaved data is meaningless, so I think this is a problem 
> > monikers could solve 100%.
> I think this is a problem that monikers 100% don't solve :-) ie.
> I do:
> create new sheet
> A1 = 3,
> copy A1
> A1 = 5

I guess it depends on whether you copied A1 the spreadsheet cell, or the
text inside A1.

Most of the OLE/ActiveX stuff gives the end user an option as to how to
insert their data.  So when I Insert/Object/Create from file in Word 2k,
I can choose a "Link to file" option.  Obviously if I choose linked, I
want the moniker, if it's not, I want an unlinked copy.

Michael Meeks <michael ximian dot com>:
> Yes, yes I know I'm just foisting the problem off onto the poor
> application developer - but frankly that's where it belongs :-)

Yes, it probably belongs there. The application developer knows what
kind of copying is most appropriate for the given app.

-- 
Nathan Cullen
furyu fuse net






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]