Added ability to pick character set in IDataObject.GetData<T> method

pull/363/head
David Hall 2022-12-20 15:05:01 -07:00
parent ff5d0acb2a
commit 64cab4e063
1 changed files with 27 additions and 58 deletions

View File

@ -204,62 +204,26 @@ namespace Vanara.PInvoke
lindex = index, lindex = index,
tymed = tymed tymed = tymed
}; };
STGMEDIUM medium = new() { tymed = attr?.Medium ?? TYMED.TYMED_HGLOBAL }; //STGMEDIUM medium = new() { tymed = attr?.Medium ?? TYMED.TYMED_HGLOBAL };
dataObj.GetData(ref formatetc, out medium); dataObj.GetData(ref formatetc, out var medium);
// Handle TYMED values // Handle TYMED values, passing through HGLOBAL
bool userFree = medium.pUnkForRelease is null; bool userFree = medium.pUnkForRelease is null;
switch (medium.tymed) if (medium.tymed != TYMED.TYMED_HGLOBAL)
{ return medium.tymed switch
case TYMED.TYMED_HGLOBAL: {
// Pass this one through TYMED.TYMED_FILE => new SafeMoveableHGlobalHandle(medium.unionmember, userFree).ToString(-1, CharSet.Ansi),
break; TYMED.TYMED_ISTREAM => Marshal.GetObjectForIUnknown(medium.unionmember) as IStream,
TYMED.TYMED_ISTORAGE => Marshal.GetObjectForIUnknown(medium.unionmember) as IStorage,
case TYMED.TYMED_FILE: TYMED.TYMED_GDI when userFree => new SafeHBITMAP(medium.unionmember),
return new SafeMoveableHGlobalHandle(medium.unionmember, userFree).ToString(-1, CharSet.Ansi); TYMED.TYMED_GDI when !userFree => (HBITMAP)medium.unionmember,
TYMED.TYMED_MFPICT when userFree => new SafeHMETAFILE(medium.unionmember),
case TYMED.TYMED_ISTREAM: TYMED.TYMED_MFPICT when !userFree => (HMETAFILE)medium.unionmember,
return Marshal.GetObjectForIUnknown(medium.unionmember) as IStream; TYMED.TYMED_ENHMF when userFree => new SafeHENHMETAFILE(medium.unionmember),
TYMED.TYMED_ENHMF when !userFree => (HENHMETAFILE)medium.unionmember,
case TYMED.TYMED_ISTORAGE: TYMED.TYMED_NULL => null,
return Marshal.GetObjectForIUnknown(medium.unionmember) as IStorage; _ => throw new InvalidOperationException(),
};
case TYMED.TYMED_GDI:
if (userFree)
{
return new SafeHBITMAP(medium.unionmember);
}
else
{
return (HBITMAP)medium.unionmember;
}
case TYMED.TYMED_MFPICT:
if (userFree)
{
return new SafeHMETAFILE(medium.unionmember);
}
else
{
return (HMETAFILE)medium.unionmember;
}
case TYMED.TYMED_ENHMF:
if (userFree)
{
return new SafeHENHMETAFILE(medium.unionmember);
}
else
{
return (HENHMETAFILE)medium.unionmember;
}
case TYMED.TYMED_NULL:
return null;
default:
throw new InvalidOperationException();
}
using SafeMoveableHGlobalHandle hmem = new(medium.unionmember, userFree); using SafeMoveableHGlobalHandle hmem = new(medium.unionmember, userFree);
try try
@ -320,8 +284,10 @@ namespace Vanara.PInvoke
/// Part of the aspect when the data must be split across page boundaries. The most common value is -1, which identifies all of the /// Part of the aspect when the data must be split across page boundaries. The most common value is -1, which identifies all of the
/// data. For the aspects DVASPECT_THUMBNAIL and DVASPECT_ICON, lindex is ignored. /// data. For the aspects DVASPECT_THUMBNAIL and DVASPECT_ICON, lindex is ignored.
/// </param> /// </param>
/// <param name="charSet">The character set to use for string types.</param>
/// <returns>The object associated with the request. If no object can be determined, <c>default(T)</c> is returned.</returns> /// <returns>The object associated with the request. If no object can be determined, <c>default(T)</c> is returned.</returns>
public static T GetData<T>(this IDataObject dataObj, uint formatId, int index = -1) /// <exception cref="System.ArgumentException">This format does not support direct type access. - formatId</exception>
public static T GetData<T>(this IDataObject dataObj, uint formatId, int index = -1, CharSet charSet = CharSet.Auto)
{ {
FORMATETC formatetc = new() FORMATETC formatetc = new()
{ {
@ -330,8 +296,8 @@ namespace Vanara.PInvoke
lindex = index, lindex = index,
tymed = TYMED.TYMED_HGLOBAL tymed = TYMED.TYMED_HGLOBAL
}; };
STGMEDIUM medium = new() { tymed = TYMED.TYMED_HGLOBAL }; //STGMEDIUM medium = new() { tymed = TYMED.TYMED_HGLOBAL };
dataObj.GetData(ref formatetc, out medium); dataObj.GetData(ref formatetc, out var medium);
if (medium.tymed != TYMED.TYMED_HGLOBAL) if (medium.tymed != TYMED.TYMED_HGLOBAL)
throw new ArgumentException("This format does not support direct type access.", nameof(formatId)); throw new ArgumentException("This format does not support direct type access.", nameof(formatId));
if (medium.unionmember == default) if (medium.unionmember == default)
@ -340,7 +306,7 @@ namespace Vanara.PInvoke
try try
{ {
hmem.Lock(); hmem.Lock();
return hmem.ToType<T>(); return hmem.ToType<T>(charSet == CharSet.Auto ? (StringHelper.GetCharSize(charSet) == 1 ? CharSet.Ansi : CharSet.Unicode) : charSet);
} }
finally finally
{ {
@ -861,7 +827,9 @@ namespace Vanara.PInvoke
public string cFileName; public string cFileName;
/// <summary>The file size, in bytes.</summary> /// <summary>The file size, in bytes.</summary>
#pragma warning disable IDE1006 // Naming Styles
public ulong nFileSize public ulong nFileSize
#pragma warning restore IDE1006 // Naming Styles
{ {
get => Macros.MAKELONG64(nFileSizeLow, nFileSizeHigh); get => Macros.MAKELONG64(nFileSizeLow, nFileSizeHigh);
set set
@ -1562,6 +1530,7 @@ namespace Vanara.PInvoke
public override IntPtr Write(object value) => base.Write(FormatHtmlForClipboard((string)value)); public override IntPtr Write(object value) => base.Write(FormatHtmlForClipboard((string)value));
} }
internal class ClipboardSerializedFormatter : IClipboardFormatter internal class ClipboardSerializedFormatter : IClipboardFormatter
{ {
private static readonly byte[] guid = new Guid("FD9EA796-3B13-4370-A679-56106BB288FB").ToByteArray(); private static readonly byte[] guid = new Guid("FD9EA796-3B13-4370-A679-56106BB288FB").ToByteArray();