|
|
@@ -8,11 +8,16 @@ using Avalonia.Controls.DragDrop;
|
|
|
using Avalonia.Win32.Interop;
|
|
|
using IDataObject = Avalonia.Controls.DragDrop.IDataObject;
|
|
|
using IOleDataObject = System.Runtime.InteropServices.ComTypes.IDataObject;
|
|
|
+using System.IO;
|
|
|
+using System.Runtime.Serialization.Formatters.Binary;
|
|
|
|
|
|
namespace Avalonia.Win32
|
|
|
{
|
|
|
class DataObject : IDataObject, IOleDataObject
|
|
|
{
|
|
|
+ // Compatibility with WinForms + WPF...
|
|
|
+ internal static readonly byte[] SerializedObjectGUID = new Guid("FD9EA796-3B13-4370-A679-56106BB288FB").ToByteArray();
|
|
|
+
|
|
|
class FormatEnumerator : IEnumFORMATETC
|
|
|
{
|
|
|
private FORMATETC[] _formats;
|
|
|
@@ -249,7 +254,51 @@ namespace Avalonia.Win32
|
|
|
return WriteStringToHGlobal(ref hGlobal, Convert.ToString(data));
|
|
|
if (dataFormat == DataFormats.FileNames && data is IEnumerable<string> files)
|
|
|
return WriteFileListToHGlobal(ref hGlobal, files);
|
|
|
- return DV_E_TYMED;
|
|
|
+ if (data is Stream stream)
|
|
|
+ {
|
|
|
+ byte[] buffer = new byte[stream.Length - stream.Position];
|
|
|
+ stream.Read(buffer, 0, buffer.Length);
|
|
|
+ return WriteBytesToHGlobal(ref hGlobal, buffer);
|
|
|
+ }
|
|
|
+ if (data is IEnumerable<byte> bytes)
|
|
|
+ {
|
|
|
+ var byteArr = bytes is byte[] ? (byte[])bytes : bytes.ToArray();
|
|
|
+ return WriteBytesToHGlobal(ref hGlobal, byteArr);
|
|
|
+ }
|
|
|
+ return WriteBytesToHGlobal(ref hGlobal, SerializeObject(data));
|
|
|
+ }
|
|
|
+
|
|
|
+ private byte[] SerializeObject(object data)
|
|
|
+ {
|
|
|
+ using (var ms = new MemoryStream())
|
|
|
+ {
|
|
|
+ ms.Write(SerializedObjectGUID, 0, SerializedObjectGUID.Length);
|
|
|
+ BinaryFormatter binaryFormatter = new BinaryFormatter();
|
|
|
+ binaryFormatter.Serialize(ms, data);
|
|
|
+ return ms.ToArray();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private int WriteBytesToHGlobal(ref IntPtr hGlobal, byte[] data)
|
|
|
+ {
|
|
|
+ int required = data.Length;
|
|
|
+ if (hGlobal == IntPtr.Zero)
|
|
|
+ hGlobal = UnmanagedMethods.GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, required);
|
|
|
+
|
|
|
+ long available = UnmanagedMethods.GlobalSize(hGlobal).ToInt64();
|
|
|
+ if (required > available)
|
|
|
+ return STG_E_MEDIUMFULL;
|
|
|
+
|
|
|
+ IntPtr ptr = UnmanagedMethods.GlobalLock(hGlobal);
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Marshal.Copy(data, 0, ptr, data.Length);
|
|
|
+ return unchecked((int)UnmanagedMethods.HRESULT.S_OK);
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ UnmanagedMethods.GlobalUnlock(hGlobal);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private int WriteFileListToHGlobal(ref IntPtr hGlobal, IEnumerable<string> files)
|