Vanara/Windows.Shell/IDataObjectExtensions.cs

81 lines
2.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Windows.Forms;
using Vanara.Extensions;
using static Vanara.PInvoke.Ole32;
using static Vanara.PInvoke.Shell32;
using IComDataObject = System.Runtime.InteropServices.ComTypes.IDataObject;
namespace Vanara.Windows.Shell
{
// TODO
internal static class DataObjectExtensions
{
public static IReadOnlyList<string> GetFileNameMap(this DataObject dobj)
{
var l = new List<string>();
if (dobj.GetDataPresent(ShellDataFormat.FileNameMap.Id()))
{
if (dobj.GetData(ShellDataFormat.FileNameMap.Id(), true) is string[] data)
l.AddRange(data);
}
return (IReadOnlyList<string>)l;
}
public static DROPEFFECT GetPreferredDropEffect(this DataObject dobj)
{
dobj.GetData(typeof(uint));
var eff = DROPEFFECT.DROPEFFECT_NONE;
if (dobj is IComDataObject cdo)
{
var fc = MakeFORMATETC(ShellClipboardFormat.CFSTR_PREFERREDDROPEFFECT);
try
{
cdo.GetData(ref fc, out var medium);
if (medium.unionmember != default)
eff = (DROPEFFECT)medium.unionmember.ToStructure<uint>();
ReleaseStgMedium(medium);
}
catch { }
}
return eff;
}
public static IReadOnlyCollection<PIDL> GetShellIdList(this DataObject dobj)
{
var l = new List<PIDL>();
if (dobj is IComDataObject cdo)
{
var fc = MakeFORMATETC(ShellClipboardFormat.CFSTR_SHELLIDLIST);
try
{
cdo.GetData(ref fc, out var medium);
if (medium.unionmember != default)
{
var cnt = (int)medium.unionmember.ToStructure<uint>() + 1;
foreach (var offset in medium.unionmember.Offset(sizeof(uint)).ToArray<uint>(cnt))
l.Add(new PIDL(medium.unionmember.Offset(offset), true));
}
ReleaseStgMedium(medium);
}
catch { }
}
return (IReadOnlyList<PIDL>)l;
}
public static void SetTargetClsid(this DataObject dobj, in Guid clsid) => dobj.SetData(ShellClipboardFormat.CFSTR_TARGETCLSID, clsid);
internal static FORMATETC MakeFORMATETC(string fmt, TYMED tymed = TYMED.TYMED_HGLOBAL) => new FORMATETC
{
cfFormat = (short)GetFormat(fmt).Id,
dwAspect = DVASPECT.DVASPECT_CONTENT,
lindex = -1,
tymed = tymed
};
private static DataFormats.Format GetFormat(string format) => DataFormats.GetFormat(format);
}
}