I understand that developers of 3rd party apps don't necessarily want me to access their clipboard data beyond, in the best case, a text summary like what I get when pasting from Word to Notepad. Nevertheless, suppose I want to grab the underlying clipboard contents and try to extract something useful for myself. How do I go about it? Does this involve messing with other processes' memory? Or trying to detect and extract properties from clipboard object using Reflection in dotnet? Or how would you approach this?
ETA: ok, for the less abstractly minded, let's consider an example: in Visual Studio forms designer I select a few widgets and do copy. Now I would like to parse the clipboard to find the names, locations and sizes of the widgets I just copied (I don't want to write plugins for visual studio etc, I want to specifically obtain info from clipboard). I know that this is theoretically possible simply because it is possible to copy-paste widgets (including their names, locations and other properties) between 2 instances of Visual Studio process.
Well, you can just read the data right out of System.Windows.Clipboard
. It's that simple!
You might need to work at some of the more esoteric data formats, but once the data is in the clipboard, you are free to read it. For Word you might find that the HTML format that it places in the clipboard quite amenable to your needs.
There's no security or privacy issues here because the user has consented to run your program. It would be wrong to allow you to read the clipboard of another logged in user, but you can't do that.
You've updated the question and now are asking something a little more specific. So I copied some widgets to the clipboard and then used the Clipboard Viewer to see what formats were in there. The one that jumped out was CF_DESIGNERCOMPONENTS_V2
. A quick websearch for this lead me to this website:
There is some code there, apparently from Reflector, which shows how the designer handles the Copy command:
protected void OnMenuCopy(object sender, EventArgs e)
{
if (this.SelectionService != null)
{
Cursor cursor1 = Cursor.Current;
try
{
Cursor.Current = Cursors.WaitCursor;
ICollection collection1 = this.GetCopySelection();
collection1 = this.PrependComponentNames(collection1);
IDesignerSerializationService service1 = (IDesignerSerializationService) this.GetService(typeof(IDesignerSerializationService));
if (service1 != null)
{
object obj1 = service1.Serialize(collection1);
MemoryStream stream1 = new MemoryStream();
new BinaryFormatter().Serialize(stream1, obj1);
stream1.Seek((long) 0, SeekOrigin.Begin);
byte[] buffer1 = stream1.GetBuffer();
IDataObject obj2 = new DataObject("CF_DESIGNERCOMPONENTS_V2", buffer1);
Clipboard.SetDataObject(obj2);
}
this.UpdateClipboardItems(null, null);
}
finally
{
Cursor.Current = cursor1;
}
}
}
This ought to get you started!