The question I want to ask is:
(1) If I interact with clipboard by Clipboard class, what should be in "Embed Source" and "MetaFilePict" streams?
(2) If I interact with clipboard by COM interface IDataObject, what should I do with the handle in "Embed Source" and "MetaFilePict"?
(3) Is there better methods to implement OLE (either client or server will help me) in C#?
More details:
I am seeking for an implementation of OLE Server in C# (extern Windows APIs and other methods that work on x86 are all OK for me, as long as they can be in one C# project). I can not find any examples of OLE that does not involve MFC. So I first tried a little bit.
My first step is to see what other OLE servers do in order to put their data into the clipboard. I have tried 2 methods to interact with clipboard: NET Clipboard class which gives me three Streams as described later, and IDataObject interface returned by OleGetClipboard which gives me pointers.
I found that Origin puts three data entries: Object Descriptor, Embed Source and MetaFilePict. They appear to be Stream. If I read all bytes from the three Streams, put them back to a new DataObject and put the DataObject to clipboard again, I am able to paste the original object in, for example, Word, which means the contents of the three Streams are enough for an OLE container to paste.
What I find further is that Object Descriptor contains the OBJECTDESCRIPTOR structure with guid of the data class and some names, and I am able to instantiate the object and convert it to an IOLEObject. But I don't know what should be in the other two stream, Embed Source and MetaFilePict. From my understanding, Embed Source should contain data that is passed to IOLEObject (probably by InitFromData) after creating it, but I did not succeed in doing so. And reagrding MetaFilePict, it seems that without this entry, the other two can not work properly (paste in Word end up with nothing if only Object Descriptor and Embed Source exist). But again, I don't know what is in it. It seems that it begins with an ASCII string (in my case it is "CPYA 4.2878 724#") and does not look like a WMF file.
If I use COM object IDataObject (in either System.Runtime.InteropServices.ComTypes or Microsoft.VisualStudio.OLE.Interop namespace), I can get HMETAFILEPICT from it, but I don't know how to use the handle. PlayMetaFile does not work on it.
EDIT
In MFC, the example uses OleCreateFromData to create the object directly from the IDataObject got from clipboard. This should also work in C#. But this is only the implementation of client. I will try to find out how to implement a server.