views:

225

answers:

2

I have a Excel addin that displays some structures on the worksheet. Users can copy the structures and paste them in another worksheet or another application which is handled by the Clipboard formats. When a user copies the structure, I convert the structure into a specific format and put it on the clipboard using the DataObject::SetData(). Please note that when a copy is initiated in Excel, it puts a number of formats on the clipboard (see image).

The problem is that there is a third party application that depends on the data on the clipboard(Copy from Excel and paste into this 3rd party app) but the funny thing is that I am not sure which format it depends on. I need to preserve the existing formats that Excel has put up there and also add my own format to it.

Currently when I use the Clipboard class in .NET (taking the DataObject and calling SetData inside it), all the other formats are replaced by new ones. I then tried to create a new DataObject, copy the existing format data to this data object and then set this data object in the Clipboard. This works fine but it takes time to copy the data.

 // Copying existing data in clipboard to our new DataObject
 IDataObject existingDataObject = Clipboard.GetDataObject();
 DataObject dataObject = new DataObject();

 string[] existingFormats = existingDataObject.GetFormats();
 foreach (string existingFormat in existingFormats)
        dataObject.SetData(existingFormat, existingDataObject.GetData(existingFormat));

I am looking for a solution to just access the existing DataObject and quietly add my own data to it without affecting other formats.

Excel Clipboard Formats - (Ignore the Native Format)

Clipboard Formats

A: 

I believe what you want to do should be possible and seeing as I also can't see how to get it done within .NET perhaps you have to PInvoke the WIN32API Clipboard methods yourself :-(

Mark Hurd
+1  A: 

You could create a wrapper class for the IDataObject that you get from the Windows clipboard to add your data. The idea is that the wrapper would know about your custom formats and delegate to the original, wrapped IDataObject for all other formats.

Here's a partial implementation showing the constructor and one of the IDataObject method implementations:

public class MyDataObject : IDataObject
{
    public MyDataObject(IDataObject inner, string format, Type type, object data)
    {
        m_inner = inner;
        m_format = format;
        m_type = type;
        m_data = data;
    }
    private IDataObject m_inner;
    private string m_format;
    private Type m_type;
    private object m_data;

    object IDataObject.GetData(string format)
    {
        // if my format, return the wrapper data
        if (format == m_format)
            return object;

        // otherwise, delegate to the wrapped data object which holds
        //  the other formats
        return m_inner.GetData(format);
    }

    // implement the rest of IDataObject similarly
    ...
}

One caveat: When retrieving the system clipboard IDataObject, you'll have to check if it's one of your wrapper objects. In that case, you don't want to keep wrapping your wrappers. Instead you'd want to either modify the data/format fields of the existing wrapper, or create a new wrapper for the original clipboard data object.

bbudge
If I put this Custom wrapper on the clipboard, the third-party application that depends on the Excel formats will not be able to understand it.
A9S6
I don't understand why the third party app won't be able to find its data. Doesn't it go through the IDataObject interface?
bbudge
+1: I got your point now. I will try this and see if it works with the third-party (It should). Thanks !!
A9S6