File: System\Windows\Forms\DataObjectComTests.cs
Web Access
Project: src\src\System.Windows.Forms\tests\UnitTests\System.Windows.Forms.Tests.csproj (System.Windows.Forms.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Runtime.InteropServices.ComTypes;
using Com = Windows.Win32.System.Com;
using IComDataObject = System.Runtime.InteropServices.ComTypes.IDataObject;
 
namespace System.Windows.Forms.Tests;
 
public unsafe partial class DataObjectTests
{
    private delegate IDataObject CreateWinFormsDataObjectForOutgoingDropData(Com.IDataObject* dataObject);
 
    [WinFormsFact]
    public void DataObject_CustomIDataObject_MockRoundTrip()
    {
        CustomIDataObject data = new();
        dynamic accessor = typeof(Control).TestAccessor().Dynamic;
        var dropTargetAccessor = typeof(DropTarget).TestAccessor();
 
        IComDataObject inData = accessor.CreateRuntimeDataObjectForDrag(data);
        inData.Should().BeAssignableTo<DataObject>();
        inData.Should().NotBeSameAs(data);
 
        // Simulate COM call. The COM call will eventually hit CreateWinFormsDataObjectForOutgoingDropData.
        // Note that this will be a ComWrappers created object since data has been wrapped in our DataObject.
        var inDataPtr = ComHelpers.GetComScope<Com.IDataObject>(inData);
        IDataObject outData = dropTargetAccessor.CreateDelegate<CreateWinFormsDataObjectForOutgoingDropData>()(inDataPtr);
 
        outData.Should().BeSameAs(data);
    }
 
    [WinFormsFact]
    public void DataObject_ComTypesIDataObject_MockRoundTrip()
    {
        CustomComTypesDataObject data = new();
        dynamic accessor = typeof(Control).TestAccessor().Dynamic;
        var dropTargetAccessor = typeof(DropTarget).TestAccessor();
 
        DataObject inData = accessor.CreateRuntimeDataObjectForDrag(data);
        inData.Should().NotBeSameAs(data);
 
        // Simulate COM call. The COM call will eventually hit CreateWinFormsDataObjectForOutgoingDropData.
        // Note that this will not be a ComWrappers created object since IComDataObject does not get wrapped in our DataObject.
        var inDataPtr = ComHelpers.GetComScope<Com.IDataObject>(inData);
        IDataObject outData = dropTargetAccessor.CreateDelegate<CreateWinFormsDataObjectForOutgoingDropData>()(inDataPtr);
 
        outData.Should().BeSameAs(inData);
    }
 
    private class CustomIDataObject : IDataObject
    {
        public object GetData(string format, bool autoConvert) => throw new NotImplementedException();
        public object GetData(string format) => throw new NotImplementedException();
        public object GetData(Type format) => throw new NotImplementedException();
        public bool GetDataPresent(string format, bool autoConvert) => throw new NotImplementedException();
        public bool GetDataPresent(string format) => throw new NotImplementedException();
        public bool GetDataPresent(Type format) => throw new NotImplementedException();
        public string[] GetFormats(bool autoConvert) => throw new NotImplementedException();
        public string[] GetFormats() => throw new NotImplementedException();
        public void SetData(string format, bool autoConvert, object data) => throw new NotImplementedException();
        public void SetData(string format, object data) => throw new NotImplementedException();
        public void SetData(Type format, object data) => throw new NotImplementedException();
        public void SetData(object data) => throw new NotImplementedException();
    }
 
    private class CustomComTypesDataObject : IComDataObject
    {
        public int DAdvise(ref FORMATETC pFormatetc, ADVF advf, IAdviseSink adviseSink, out int connection) => throw new NotImplementedException();
        public void DUnadvise(int connection) => throw new NotImplementedException();
        public int EnumDAdvise(out IEnumSTATDATA enumAdvise) => throw new NotImplementedException();
        public IEnumFORMATETC EnumFormatEtc(DATADIR direction) => throw new NotImplementedException();
        public int GetCanonicalFormatEtc(ref FORMATETC formatIn, out FORMATETC formatOut) => throw new NotImplementedException();
        public void GetData(ref FORMATETC format, out STGMEDIUM medium) => throw new NotImplementedException();
        public void GetDataHere(ref FORMATETC format, ref STGMEDIUM medium) => throw new NotImplementedException();
        public int QueryGetData(ref FORMATETC format) => throw new NotImplementedException();
        public void SetData(ref FORMATETC formatIn, ref STGMEDIUM medium, bool release) => throw new NotImplementedException();
    }
}