Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ public virtual StringCollection GetFileDropList()
return dropList;
}

public virtual Image? GetImage() => GetData(DataFormats.Bitmap, autoConvert: true) as Image;
public virtual Image? GetImage() =>
TryGetData<Image>(DataFormats.Bitmap, autoConvert: true, out Image? image) ? image : null;

public virtual string GetText(TextDataFormat format)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,11 +378,29 @@ internal class DataObjectOverridesTryGetDataCore : DataObject
// true is the default value for general purpose APIs (GetData).
private readonly bool _autoConvert;

public DataObjectOverridesTryGetDataCore(string format, Func<TypeName, Type>? resolver, bool autoConvert) : base()
private readonly Type _expectedType;
private readonly bool _resultToReturn;
private readonly object? _dataToReturn;

public DataObjectOverridesTryGetDataCore(string format, Func<TypeName, Type>? resolver, bool autoConvert)
: this(format, resolver, autoConvert, typeof(string), resultToReturn: false, dataToReturn: null)
{
}

public DataObjectOverridesTryGetDataCore(
string format,
Func<TypeName, Type>? resolver,
bool autoConvert,
Type expectedType,
bool resultToReturn,
object? dataToReturn) : base()
{
_format = format;
_resolver = resolver;
_autoConvert = autoConvert;
_expectedType = expectedType;
_resultToReturn = resultToReturn;
_dataToReturn = dataToReturn;
}

public int Count { get; private set; }
Expand All @@ -397,9 +415,16 @@ protected override bool TryGetDataCore<T>(
format.Should().Be(_format);
resolver.Should().BeEquivalentTo(_resolver);
autoConvert.Should().Be(_autoConvert);
typeof(T).Should().Be<string>();
typeof(T).Should().Be(_expectedType);

Count++;

if (typeof(T) == _expectedType && _dataToReturn is not null)
{
data = (T)_dataToReturn;
return _resultToReturn;
}

// This is a mock implementation that never returns anything.
data = default;
return false;
Expand Down Expand Up @@ -909,18 +934,46 @@ public void GetImage_InvokeWithData_ReturnsExpected(object result, Image expecte

[Theory]
[MemberData(nameof(GetImage_TheoryData))]
public void GetImage_InvokeMocked_ReturnsExpected(object result, Image expected)
public void GetImage_Invoke_CallsTryGetData(object result, Image expected)
{
bool autoConvert = true;
bool resultToReturn = result is Image;
Image dataToReturn = result as Image;
DataObjectOverridesTryGetDataCore dataObject = new(
DataFormats.Bitmap,
resolver: null,
autoConvert,
expectedType: typeof(Image),
resultToReturn,
dataToReturn);
dataObject.Count.Should().Be(0);

Image image = dataObject.GetImage();

image.Should().BeSameAs(expected);
dataObject.Count.Should().Be(1);
}

[WinFormsFact]
public void GetDataObject_GetImage_RoundTripsBitmap()
{
Mock<DataObject> mockDataObject = new(MockBehavior.Strict);
mockDataObject
.Setup(o => o.GetImage())
.CallBase();
mockDataObject
.Setup(o => o.GetData(DataFormats.Bitmap, true))
.Returns(result)
.Verifiable();
mockDataObject.Object.GetImage().Should().BeSameAs(expected);
mockDataObject.Verify(o => o.GetData(DataFormats.Bitmap, true), Times.Once());
try
{
using Bitmap bitmap = new(10, 10);
bitmap.SetPixel(1, 2, Color.FromArgb(0x01, 0x02, 0x03, 0x04));
Clipboard.SetImage(bitmap);

DataObject dataObject = Clipboard.GetDataObject().Should().BeOfType<DataObject>().Subject;

var result = dataObject.GetImage().Should().BeOfType<Bitmap>().Subject;
result.Size.Should().Be(bitmap.Size);
result.GetPixel(1, 2).Should().Be(Color.FromArgb(0xFF, 0xD2, 0xD2, 0xD2));
Clipboard.ContainsImage().Should().BeTrue();
}
finally
{
Clipboard.Clear();
}
}

[Fact]
Expand Down