|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable enable
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using Windows.Win32.System.Ole;
using Com = Windows.Win32.System.Com;
using ComTypes = System.Runtime.InteropServices.ComTypes;
namespace System.Windows.Forms.Tests;
// Note: each registered Clipboard format is an OS singleton
// and we should not run this test at the same time as other tests using the same format.
[Collection("Sequential")]
[UISettings(MaxAttempts = 3)] // Try up to 3 times before failing.
public class ClipboardTests
{
[WinFormsFact]
public void Clipboard_SetText_InvokeString_GetReturnsExpected()
{
Clipboard.SetText("text");
Clipboard.GetText().Should().Be("text");
Clipboard.ContainsText().Should().BeTrue();
}
[WinFormsFact]
public void Clipboard_Clear_InvokeMultipleTimes_Success()
{
Clipboard.Clear();
Clipboard.ContainsAudio().Should().BeFalse();
Clipboard.ContainsData("format").Should().BeFalse();
Clipboard.ContainsFileDropList().Should().BeFalse();
Clipboard.ContainsImage().Should().BeFalse();
Clipboard.ContainsText().Should().BeFalse();
Clipboard.Clear();
Clipboard.ContainsAudio().Should().BeFalse();
Clipboard.ContainsData("format").Should().BeFalse();
Clipboard.ContainsFileDropList().Should().BeFalse();
Clipboard.ContainsImage().Should().BeFalse();
Clipboard.ContainsText().Should().BeFalse();
}
public static TheoryData<Func<bool>> ContainsMethodsTheoryData =>
[
Clipboard.ContainsAudio,
Clipboard.ContainsFileDropList,
Clipboard.ContainsImage,
Clipboard.ContainsText
];
[WinFormsTheory]
[MemberData(nameof(ContainsMethodsTheoryData))]
public void Clipboard_Contains_InvokeMultipleTimes_Success(Func<bool> contains)
{
Clipboard.Clear();
bool result = contains.Invoke();
contains.Invoke().Should().Be(result);
result.Should().BeFalse();
}
[WinFormsTheory]
[StringWithNullData]
public void Clipboard_ContainsData_InvokeMultipleTimes_Success(string format)
{
bool result = Clipboard.ContainsData(format);
Clipboard.ContainsData(format).Should().Be(result);
result.Should().BeFalse();
}
[WinFormsTheory]
[EnumData<TextDataFormat>]
public void Clipboard_ContainsText_TextDataFormat_InvokeMultipleTimes_Success(TextDataFormat format)
{
bool result = Clipboard.ContainsText(format);
Clipboard.ContainsText(format).Should().Be(result);
}
[WinFormsTheory]
[InvalidEnumData<TextDataFormat>]
public void Clipboard_ContainsText_InvalidFormat_ThrowsInvalidEnumArgumentException(TextDataFormat format)
{
Action action = () => Clipboard.ContainsText(format);
action.Should().Throw<InvalidEnumArgumentException>().WithParameterName("format");
}
[WinFormsFact]
public void Clipboard_GetAudioStream_InvokeMultipleTimes_Success()
{
Stream? result = Clipboard.GetAudioStream();
(Clipboard.GetAudioStream() == result).Should().BeTrue();
}
[WinFormsTheory]
[InlineData(null)]
[InlineData("")]
[InlineData("\t")]
public void Clipboard_GetData_NullOrEmptyFormat_Returns_Null(string? format)
{
object? result = Clipboard.GetData(format!);
result.Should().BeNull();
result = Clipboard.GetData(format!);
result.Should().BeNull();
}
[WinFormsFact]
public void Clipboard_GetDataObject_InvokeMultipleTimes_Success()
{
IDataObject? result = Clipboard.GetDataObject();
(result == Clipboard.GetDataObject()).Should().BeFalse();
}
[WinFormsFact]
public void Clipboard_GetFileDropList_InvokeMultipleTimes_Success()
{
StringCollection result = Clipboard.GetFileDropList();
Clipboard.GetFileDropList().Should().BeEquivalentTo(result);
}
[WinFormsFact]
public void Clipboard_GetImage_InvokeMultipleTimes_Success()
{
Image? result = Clipboard.GetImage();
Clipboard.GetImage().Should().BeEquivalentTo(result);
}
[WinFormsFact]
public void Clipboard_GetText_InvokeMultipleTimes_Success()
{
string result = Clipboard.GetText();
Clipboard.GetText().Should().Be(result);
}
[WinFormsTheory]
[EnumData<TextDataFormat>]
public void Clipboard_GetText_TextDataFormat_InvokeMultipleTimes_Success(TextDataFormat format)
{
string result = Clipboard.GetText(format);
Clipboard.GetText(format).Should().Be(result);
}
[WinFormsTheory]
[InvalidEnumData<TextDataFormat>]
public void Clipboard_GetText_InvalidFormat_ThrowsInvalidEnumArgumentException(TextDataFormat format)
{
Action action = () => Clipboard.GetText(format);
action.Should().Throw<InvalidEnumArgumentException>().WithParameterName("format");
}
[WinFormsFact]
public void Clipboard_SetAudio_InvokeByteArray_GetReturnsExpected()
{
byte[] audioBytes = [1, 2, 3];
Clipboard.SetAudio(audioBytes);
Clipboard.GetAudioStream().Should().BeOfType<MemoryStream>().Which.ToArray().Should().Equal(audioBytes);
Clipboard.GetData(DataFormats.WaveAudio).Should().BeOfType<MemoryStream>().Which.ToArray().Should().Equal(audioBytes);
Clipboard.ContainsAudio().Should().BeTrue();
Clipboard.ContainsData(DataFormats.WaveAudio).Should().BeTrue();
}
[WinFormsFact]
public void Clipboard_SetAudio_InvokeEmptyByteArray_GetReturnsExpected()
{
byte[] audioBytes = Array.Empty<byte>();
Clipboard.SetAudio(audioBytes);
Clipboard.GetAudioStream().Should().BeNull();
Clipboard.GetData(DataFormats.WaveAudio).Should().BeNull();
Clipboard.ContainsAudio().Should().BeTrue();
Clipboard.ContainsData(DataFormats.WaveAudio).Should().BeTrue();
}
[WinFormsFact]
public void Clipboard_SetAudio_NullAudioBytes_ThrowsArgumentNullException()
{
Action action = () => Clipboard.SetAudio((byte[])null!);
action.Should().Throw<ArgumentNullException>().WithParameterName("audioBytes");
}
[WinFormsFact]
public void Clipboard_SetAudio_InvokeStream_GetReturnsExpected()
{
byte[] audioBytes = [1, 2, 3];
using MemoryStream audioStream = new(audioBytes);
Clipboard.SetAudio(audioStream);
Clipboard.GetAudioStream().Should().BeOfType<MemoryStream>().Which.ToArray().Should().Equal(audioBytes);
Clipboard.GetData(DataFormats.WaveAudio).Should().BeOfType<MemoryStream>().Which.ToArray().Should().Equal(audioBytes);
Clipboard.ContainsAudio().Should().BeTrue();
Clipboard.ContainsData(DataFormats.WaveAudio).Should().BeTrue();
}
[WinFormsFact]
public void Clipboard_SetAudio_InvokeEmptyStream_GetReturnsExpected()
{
using MemoryStream audioStream = new();
Clipboard.SetAudio(audioStream);
Clipboard.GetAudioStream().Should().BeNull();
Clipboard.GetData(DataFormats.WaveAudio).Should().BeNull();
Clipboard.ContainsAudio().Should().BeTrue();
Clipboard.ContainsData(DataFormats.WaveAudio).Should().BeTrue();
}
[WinFormsFact]
public void Clipboard_SetAudio_NullAudioStream_ThrowsArgumentNullException()
{
Action action = () => Clipboard.SetAudio((Stream)null!);
action.Should().Throw<ArgumentNullException>().WithParameterName("audioStream");
}
[WinFormsTheory]
[InlineData("format", null)]
[InlineData("format", 1)]
public void Clipboard_SetData_Invoke_GetReturnsExpected(string format, object? data)
{
Clipboard.SetData(format, data!);
Clipboard.GetData(format).Should().Be(data);
Clipboard.ContainsData(format).Should().BeTrue();
}
[WinFormsTheory]
[InlineData("")]
[InlineData(" ")]
[InlineData("\t")]
[InlineData(null)]
public void Clipboard_SetData_EmptyOrWhitespaceFormat_ThrowsArgumentException(string? format)
{
Action action = () => Clipboard.SetData(format!, "data");
action.Should().Throw<ArgumentException>().WithParameterName("format");
}
[WinFormsFact]
public void Clipboard_SetData_null_NotThrow()
{
try
{
Action action = () => Clipboard.SetData("MyData", data: null!);
action.Should().NotThrow();
// Clipboard flushes format only, content is not stored.
// GetData will hit "Data on clipboard is invalid (0x800401D3 (CLIPBRD_E_BAD_DATA))"
Clipboard.ContainsData("MyData").Should().BeTrue();
Clipboard.GetData("MyData").Should().BeNull();
}
finally
{
Clipboard.Clear();
}
}
[WinFormsTheory]
[InlineData(1)]
[InlineData("data")]
public void Clipboard_SetDataObject_InvokeObjectNotIComDataObject_GetReturnsExpected(object data)
{
Clipboard.SetDataObject(data);
var dataObject = Clipboard.GetDataObject();
Assert.NotNull(dataObject);
dataObject.GetData(data.GetType()).Should().Be(data);
Clipboard.ContainsData(data.GetType().FullName).Should().BeTrue();
}
[WinFormsTheory]
[InlineData(1)]
[InlineData("data")]
public void Clipboard_SetDataObject_InvokeObjectIComDataObject_GetReturnsExpected(object data)
{
DataObject dataObject = new(data);
Clipboard.SetDataObject(dataObject);
DataObject actual = Clipboard.GetDataObject().Should().BeOfType<DataObject>().Subject;
actual.GetData(data.GetType()).Should().Be(data);
Clipboard.ContainsData(data.GetType().FullName).Should().BeTrue();
}
[WinFormsTheory]
[InlineData(1, true)]
[InlineData(1, false)]
[InlineData("data", true)]
[InlineData("data", false)]
public void Clipboard_SetDataObject_InvokeObjectBoolNotIComDataObject_GetReturnsExpected(object data, bool copy)
{
Clipboard.SetDataObject(data, copy);
DataObject dataObject = Clipboard.GetDataObject().Should().BeOfType<DataObject>().Subject;
dataObject.GetData(data.GetType()).Should().Be(data);
Clipboard.ContainsData(data.GetType().FullName).Should().BeTrue();
}
[WinFormsTheory]
[InlineData(1, true, 0, 0)]
[InlineData(1, false, 1, 2)]
[InlineData("data", true, 0, 0)]
[InlineData("data", false, 1, 2)]
public void Clipboard_SetDataObject_InvokeObjectBoolIComDataObject_GetReturnsExpected(object data, bool copy, int retryTimes, int retryDelay)
{
DataObject dataObject = new(data);
Clipboard.SetDataObject(dataObject, copy, retryTimes, retryDelay);
DataObject actual = Clipboard.GetDataObject().Should().BeOfType<DataObject>().Which;
actual.GetData(data.GetType()).Should().Be(data);
Clipboard.ContainsData(data.GetType().FullName).Should().BeTrue();
}
[WinFormsTheory]
[InlineData(1, true, 0, 0)]
[InlineData(1, false, 1, 2)]
[InlineData("data", true, 0, 0)]
[InlineData("data", false, 1, 2)]
public void Clipboard_SetDataObject_InvokeObjectBoolIntIntNotIComDataObject_GetReturnsExpected(object data, bool copy, int retryTimes, int retryDelay)
{
Clipboard.SetDataObject(data, copy, retryTimes, retryDelay);
DataObject dataObject = Clipboard.GetDataObject().Should().BeOfType<DataObject>().Which;
dataObject.GetData(data.GetType()).Should().Be(data);
Clipboard.ContainsData(data.GetType().FullName).Should().BeTrue();
}
public static TheoryData<Action> Clipboard_SetDataObject_Null_TheoryData =>
[
() => Clipboard.SetDataObject(null!),
() => Clipboard.SetDataObject(null!, copy: true),
() => Clipboard.SetDataObject(null!, copy: true, retryTimes: 10, retryDelay: 0)
];
[WinFormsTheory]
[MemberData(nameof(Clipboard_SetDataObject_Null_TheoryData))]
public void Clipboard_SetDataObject_NullData_ThrowsArgumentNullException(Action action)
{
action.Should().Throw<ArgumentNullException>().WithParameterName("data");
}
[WinFormsFact]
public void Clipboard_SetDataObject_NegativeRetryTimes_ThrowsArgumentOutOfRangeException()
{
Action action = () => Clipboard.SetDataObject(new object(), copy: true, retryTimes: -1, retryDelay: 0);
action.Should().Throw<ArgumentOutOfRangeException>().WithParameterName("retryTimes");
}
[WinFormsFact]
public void Clipboard_SetDataObject_NegativeRetryDelay_ThrowsArgumentOutOfRangeException()
{
Action action = () => Clipboard.SetDataObject(new object(), copy: true, retryTimes: 10, retryDelay: -1);
action.Should().Throw<ArgumentOutOfRangeException>().WithParameterName("retryDelay");
}
public static TheoryData<Action> NotAnStaTheoryData =>
[
Clipboard.Clear,
() => Clipboard.SetAudio(Array.Empty<byte>()),
() => Clipboard.SetAudio(new MemoryStream()),
() => Clipboard.SetData("format", data: null!),
() => Clipboard.SetDataObject(null!),
() => Clipboard.SetDataObject(null!, copy: true),
() => Clipboard.SetDataObject(null!, copy: true, retryTimes: 10, retryDelay: 0),
() => Clipboard.SetFileDropList(["filePath"]),
() => Clipboard.SetText("text"),
() => Clipboard.SetText("text", TextDataFormat.Text)
];
[Theory] // x-thread
[MemberData(nameof(NotAnStaTheoryData))]
public void Clipboard_NotSta_ThrowsThreadStateException(Action action)
{
action.Should().Throw<ThreadStateException>();
}
[Fact] // x-thread
public void Clipboard_SetImage_NotSta_ThrowsThreadStateException()
{
using Bitmap bitmap = new(10, 10);
using Metafile metafile = new("bitmaps/telescope_01.wmf");
using Metafile enhancedMetafile = new("bitmaps/milkmateya01.emf");
Action action = () => Clipboard.SetImage(bitmap);
action.Should().Throw<ThreadStateException>();
action = () => Clipboard.SetImage(metafile);
action.Should().Throw<ThreadStateException>();
action = () => Clipboard.SetImage(enhancedMetafile);
action.Should().Throw<ThreadStateException>();
}
[WinFormsFact]
public void Clipboard_SetFileDropList_Invoke_GetReturnsExpected()
{
StringCollection filePaths =
[
"filePath",
"filePath2"
];
Clipboard.SetFileDropList(filePaths);
Clipboard.GetFileDropList().Should().BeEquivalentTo(filePaths);
Clipboard.ContainsFileDropList().Should().BeTrue();
}
[WinFormsFact]
public void Clipboard_SetFileDropList_NullFilePaths_ThrowsArgumentNullException()
{
Action action = () => Clipboard.SetFileDropList(null!);
action.Should().Throw<ArgumentNullException>().WithParameterName("filePaths");
}
[WinFormsFact]
public void Clipboard_SetFileDropList_EmptyFilePaths_ThrowsArgumentException()
{
Action action = static () => Clipboard.SetFileDropList([]);
action.Should().Throw<ArgumentException>();
}
[WinFormsTheory]
[InlineData("")]
[InlineData("\0")]
public void Clipboard_SetFileDropList_InvalidFileInPaths_ThrowsArgumentException(string filePath)
{
StringCollection filePaths =
[
filePath
];
Action action = () => Clipboard.SetFileDropList(filePaths);
action.Should().Throw<ArgumentException>();
}
[WinFormsFact]
public void Clipboard_SetImage_InvokeBitmap_GetReturnsExpected()
{
using Bitmap bitmap = new(10, 10);
bitmap.SetPixel(1, 2, Color.FromArgb(0x01, 0x02, 0x03, 0x04));
Clipboard.SetImage(bitmap);
Bitmap result = Assert.IsType<Bitmap>(Clipboard.GetImage());
result.Size.Should().Be(bitmap.Size);
result.GetPixel(1, 2).Should().Be(Color.FromArgb(0xFF, 0xD2, 0xD2, 0xD2));
Clipboard.ContainsImage().Should().BeTrue();
}
[WinFormsFact]
public void Clipboard_SetImage_InvokeMetafile_GetReturnsExpected()
{
try
{
using Metafile metafile = new("bitmaps/telescope_01.wmf");
Clipboard.SetImage(metafile);
Clipboard.GetImage().Should().BeNull();
Clipboard.ContainsImage().Should().BeTrue();
}
finally
{
Clipboard.Clear();
}
}
[WinFormsFact]
public void Clipboard_SetImage_InvokeEnhancedMetafile_GetReturnsExpected()
{
try
{
using Metafile metafile = new("bitmaps/milkmateya01.emf");
Clipboard.SetImage(metafile);
Clipboard.GetImage().Should().BeNull();
Clipboard.ContainsImage().Should().BeTrue();
}
finally
{
Clipboard.Clear();
}
}
[WinFormsFact]
public void Clipboard_SetImage_NullImage_ThrowsArgumentNullException()
{
Action action = () => Clipboard.SetImage(null!);
action.Should().Throw<ArgumentNullException>().WithParameterName("image");
}
[WinFormsTheory]
[EnumData<TextDataFormat>]
public void Clipboard_SetText_InvokeStringTextDataFormat_GetReturnsExpected(TextDataFormat format)
{
Clipboard.SetText("text", format);
Clipboard.GetText(format).Should().Be("text");
Clipboard.ContainsText(format).Should().BeTrue();
}
[WinFormsTheory]
[NullAndEmptyStringData]
public void Clipboard_SetText_NullOrEmptyText_ThrowsArgumentNullException(string text)
{
Action action = () => Clipboard.SetText(text);
action.Should().Throw<ArgumentNullException>().WithParameterName("text");
action = () => Clipboard.SetText(text, TextDataFormat.Text);
action.Should().Throw<ArgumentNullException>().WithParameterName("text");
}
[WinFormsTheory]
[InvalidEnumData<TextDataFormat>]
public void Clipboard_SetText_InvalidFormat_ThrowsInvalidEnumArgumentException(TextDataFormat format)
{
Action action = () => Clipboard.SetText("text", format);
action.Should().Throw<InvalidEnumArgumentException>().WithParameterName("format");
}
[WinFormsFact]
public void Clipboard_SetData_CustomFormat_Color()
{
string format = nameof(Clipboard_SetData_CustomFormat_Color);
Clipboard.SetData(format, Color.Black);
Clipboard.ContainsData(format).Should().BeTrue();
Clipboard.GetData(format).Should().Be(Color.Black);
}
[WinFormsFact]
public void Clipboard_SetData_CustomFormat_Exception_BinaryFormatterDisabled_SerializesException()
{
using BinaryFormatterScope scope = new(enable: false);
string format = nameof(Clipboard_SetData_CustomFormat_Exception_BinaryFormatterDisabled_SerializesException);
// This will fail and NotSupportedException will be put on the Clipboard instead.
Clipboard.SetData(format, new FileNotFoundException());
Clipboard.ContainsData(format).Should().BeTrue();
Clipboard.GetData(format).Should().BeOfType<NotSupportedException>();
}
[WinFormsFact]
public unsafe void Clipboard_GetClipboard_ReturnsProxy()
{
DataObject data = new();
using var dataScope = ComHelpers.GetComScope<Com.IDataObject>(data);
PInvoke.OleSetClipboard(dataScope).Succeeded.Should().BeTrue();
using ComScope<Com.IDataObject> proxy = new(null);
PInvoke.OleGetClipboard(proxy).Succeeded.Should().BeTrue();
((nint)proxy.Value).Should().NotBe((nint)dataScope.Value);
using var dataUnknown = dataScope.Query<Com.IUnknown>();
using var proxyUnknown = proxy.Query<Com.IUnknown>();
((nint)proxyUnknown.Value).Should().NotBe((nint)dataUnknown.Value);
// The proxy does not know about this interface, it should give back the real pointer.
using var realDataPointer = proxy.Query<Com.IComCallableWrapper>();
using var realDataPointerUnknown = realDataPointer.Query<Com.IUnknown>();
((nint)proxyUnknown.Value).Should().NotBe((nint)realDataPointerUnknown.Value);
((nint)dataUnknown.Value).Should().Be((nint)realDataPointerUnknown.Value);
}
[WinFormsFact]
public void Clipboard_Set_DoesNotWrapTwice()
{
string realDataObject = string.Empty;
Clipboard.SetDataObject(realDataObject);
IDataObject? clipboardDataObject = Clipboard.GetDataObject();
var dataObject = clipboardDataObject.Should().BeOfType<DataObject>().Which;
dataObject.IsWrappedForClipboard.Should().BeTrue();
Clipboard.SetDataObject(clipboardDataObject!);
IDataObject? clipboardDataObject2 = Clipboard.GetDataObject();
clipboardDataObject2.Should().NotBeNull();
clipboardDataObject2.Should().BeSameAs(clipboardDataObject);
}
[WinFormsFact]
public void Clipboard_GetSet_RoundTrip_ReturnsExpected()
{
CustomDataObject realDataObject = new();
Clipboard.SetDataObject(realDataObject);
IDataObject? clipboardDataObject = Clipboard.GetDataObject();
clipboardDataObject.Should().BeSameAs(realDataObject);
clipboardDataObject!.GetDataPresent("Foo").Should().BeTrue();
clipboardDataObject.GetData("Foo").Should().Be("Bar");
}
private class CustomDataObject : IDataObject, ComTypes.IDataObject
{
[DllImport("shell32.dll")]
public static extern int SHCreateStdEnumFmtEtc(uint cfmt, ComTypes.FORMATETC[] afmt, out ComTypes.IEnumFORMATETC ppenumFormatEtc);
int ComTypes.IDataObject.DAdvise(ref ComTypes.FORMATETC pFormatetc, ComTypes.ADVF advf, ComTypes.IAdviseSink adviseSink, out int connection) => throw new NotImplementedException();
void ComTypes.IDataObject.DUnadvise(int connection) => throw new NotImplementedException();
int ComTypes.IDataObject.EnumDAdvise(out ComTypes.IEnumSTATDATA enumAdvise) => throw new NotImplementedException();
ComTypes.IEnumFORMATETC ComTypes.IDataObject.EnumFormatEtc(ComTypes.DATADIR direction)
{
if (direction == ComTypes.DATADIR.DATADIR_GET)
{
// Create enumerator and return it
ComTypes.IEnumFORMATETC enumerator;
if (SHCreateStdEnumFmtEtc(0, [], out enumerator) == 0)
{
return enumerator;
}
}
throw new NotImplementedException();
}
int ComTypes.IDataObject.GetCanonicalFormatEtc(ref ComTypes.FORMATETC formatIn, out ComTypes.FORMATETC formatOut) => throw new NotImplementedException();
object IDataObject.GetData(string format, bool autoConvert) => format == "Foo" ? "Bar" : null!;
object IDataObject.GetData(string format) => format == "Foo" ? "Bar" : null!;
object IDataObject.GetData(Type format) => null!;
void ComTypes.IDataObject.GetData(ref ComTypes.FORMATETC format, out ComTypes.STGMEDIUM medium) => throw new NotImplementedException();
void ComTypes.IDataObject.GetDataHere(ref ComTypes.FORMATETC format, ref ComTypes.STGMEDIUM medium) => throw new NotImplementedException();
bool IDataObject.GetDataPresent(string format, bool autoConvert) => format == "Foo";
bool IDataObject.GetDataPresent(string format) => format == "Foo";
bool IDataObject.GetDataPresent(Type format) => false;
string[] IDataObject.GetFormats(bool autoConvert) => ["Foo"];
string[] IDataObject.GetFormats() => ["Foo"];
int ComTypes.IDataObject.QueryGetData(ref ComTypes.FORMATETC format) => throw new NotImplementedException();
void IDataObject.SetData(string format, bool autoConvert, object? data) => throw new NotImplementedException();
void IDataObject.SetData(string format, object? data) => throw new NotImplementedException();
void IDataObject.SetData(Type format, object? data) => throw new NotImplementedException();
void IDataObject.SetData(object? data) => throw new NotImplementedException();
void ComTypes.IDataObject.SetData(ref ComTypes.FORMATETC formatIn, ref ComTypes.STGMEDIUM medium, bool release) => throw new NotImplementedException();
}
[DllImport("user32.dll")]
private static extern bool CloseClipboard();
[DllImport("user32.dll")]
private static extern bool OpenClipboard(HWND hWndNewOwner);
[DllImport("user32.dll")]
private static extern bool SetClipboardData(uint uFormat, HANDLE data);
[WinFormsFact]
public unsafe void Clipboard_RawClipboard_SetClipboardData_ReturnsExpected()
{
Clipboard.Clear();
OpenClipboard(HWND.Null).Should().BeTrue();
string testString = "test";
SetClipboardData((uint)CLIPBOARD_FORMAT.CF_UNICODETEXT, (HANDLE)Marshal.StringToHGlobalUni(testString));
CloseClipboard().Should().BeTrue();
DataObject dataObject = Clipboard.GetDataObject().Should().BeOfType<DataObject>().Which;
dataObject.GetData(DataFormats.Text).Should().Be(testString);
}
}
|