简体   繁体   中英

Why can't I drag a Point between two instances of a program?

I have a DoDragDrop where I set the data to a Point .when I drag within one instance – everything's OK. But when I drag between two instances of the program Visual Studio gives me this error:

The specified record cannot be mapped to a managed value class.

Why?

EDIT: here's the code:

DataObject d = new DataObject();
d.SetData("ThePoint", MyPoint);
DragDropEffects e = DoDragDrop(d, DragDropEffects.Move);

And:

Point e2 = (Point)e.Data.GetData("ThePoint");

The specified record cannot be mapped

Note the oddity of the word "record". It is a COM-centric word for "struct". What you are trying to do almost works, but not quite. The DoDragDrop() method properly marshals the Point structure to a COM object, possible because Point has the [ComVisible(true)] attribute. The missing ingredient is the info required by IRecordInfo, a COM interface that describes the layout of the structure. Required because structures have a very compiler dependent layout.

This interface is normally implemented by reading the structure definition from a type library. Which is in fact available, the Point struct is described in c:\\windows\\microsoft.net\\framework\\v2.0.50727\\system.drawing.tlb. You can look at it with the OleView.exe tool, File + View Typelib.

Everything good, except for the part where the receiver of the COM object has to translate it back to a managed object, a Point. That requires finding out what type library contains the object definition so IRecordInfo can do its job. Which is recorded in the registry, HKCR\\Record key. Which does not contain an entry for Point. Kaboom.

Create your own class (not struct) to store the data, give it the [Serializable] attribute so it can trivially be marshaled.

This is gonna look like a hack but you can do this, I tested it it works. Edit Guess it doesn't answer the WHY? question.

private void panel1_MouseDown(object sender, MouseEventArgs e)
    {
        Point MyPoint = new Point(100, 200);
        DoDragDrop(new string[] { MyPoint.X.ToString(), MyPoint.Y.ToString() }, DragDropEffects.Copy);
    }

    private void Form1_DragEnter(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Copy;
    }

    private void Form1_DragDrop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(typeof(string[])))
        {
            string[] item = (string[])e.Data.GetData(typeof(string[]));
            Point e2 = new Point(Int32.Parse(item[0]), Int32.Parse(item[1]));

            MessageBox.Show(e2.X+":"+e2.Y);
        }

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM