Skip to content

Commit

Permalink
Create CCW for IDropSource
Browse files Browse the repository at this point in the history
Progress towards dotnet#5163 and dotnet#4649
  • Loading branch information
kant2002 committed Feb 23, 2022
1 parent 2646981 commit 196b93b
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ internal static class IID
// EAC04BC0-3791-11D2-BB95-0060977B464C
public static Guid IAutoComplete2 { get; } = new(0xEAC04BC0, 0x3791, 0x11D2, 0xBB, 0x95, 0x00, 0x60, 0x97, 0x7B, 0x46, 0x4C);

// 00000121-0000-0000-C000-000000000046
public static Guid IDropSource { get; } = new(0x00000121, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);

// 00000101-0000-0000-C000-000000000046
public static Guid IEnumString { get; } = new(0x00000101, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,18 @@ internal static partial class Ole32
[DllImport(Libraries.Ole32, ExactSpelling = true)]
public static extern HRESULT DoDragDrop(
IDataObject pDataObj,
IDropSource pDropSource,
IntPtr pDropSource,
DROPEFFECT dwOKEffects,
out DROPEFFECT pdwEffect);

public static HRESULT DoDragDrop(
IDataObject pDataObj,
IDropSource pDropSource,
DROPEFFECT dwOKEffects,
out DROPEFFECT pdwEffect)
{
var dropSourcePtr = WinFormsComWrappers.Instance.GetOrCreateComInterfaceForObject(pDropSource, CreateComInterfaceFlags.None);
return DoDragDrop(pDataObj, dropSourcePtr, dwOKEffects, out pdwEffect);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal unsafe partial class WinFormsComWrappers
{
internal static class IDropSourceVtbl
{
public static IntPtr Create(IntPtr fpQueryInterface, IntPtr fpAddRef, IntPtr fpRelease)
{
IntPtr* vtblRaw = (IntPtr*)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(IDropSourceVtbl), IntPtr.Size * 5);
vtblRaw[0] = fpQueryInterface;
vtblRaw[1] = fpAddRef;
vtblRaw[2] = fpRelease;
vtblRaw[3] = (IntPtr)(delegate* unmanaged<IntPtr, BOOL, User32.MK, HRESULT>)&QueryContinueDrag;
vtblRaw[4] = (IntPtr)(delegate* unmanaged<IntPtr, Ole32.DROPEFFECT, HRESULT>)&GiveFeedback;

return (IntPtr)vtblRaw;
}

[UnmanagedCallersOnly]
private static HRESULT QueryContinueDrag(IntPtr thisPtr, BOOL fEscapePressed, User32.MK grfKeyState)
{
var inst = ComInterfaceDispatch.GetInstance<Ole32.IDropSource>((ComInterfaceDispatch*)thisPtr);
return inst.QueryContinueDrag(fEscapePressed, grfKeyState);
}

[UnmanagedCallersOnly]
private static HRESULT GiveFeedback(IntPtr thisPtr, Ole32.DROPEFFECT dwEffect)
{
var inst = ComInterfaceDispatch.GetInstance<Ole32.IDropSource>((ComInterfaceDispatch*)thisPtr);
return inst.GiveFeedback(dwEffect);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ internal unsafe partial class WinFormsComWrappers : ComWrappers
private static readonly ComInterfaceEntry* s_streamEntry = InitializeIStreamEntry();
private static readonly ComInterfaceEntry* s_fileDialogEventsEntry = InitializeIFileDialogEventsEntry();
private static readonly ComInterfaceEntry* s_enumStringEntry = InitializeIEnumStringEntry();
private static readonly ComInterfaceEntry* s_dropSourceEntry = InitializeIDropSourceEntry();

internal static WinFormsComWrappers Instance { get; } = new WinFormsComWrappers();

Expand Down Expand Up @@ -62,6 +63,18 @@ private WinFormsComWrappers() { }
return wrapperEntry;
}

private static ComInterfaceEntry* InitializeIDropSourceEntry()
{
GetIUnknownImpl(out IntPtr fpQueryInterface, out IntPtr fpAddRef, out IntPtr fpRelease);

IntPtr iDropSourceVtbl = IDropSourceVtbl.Create(fpQueryInterface, fpAddRef, fpRelease);

ComInterfaceEntry* wrapperEntry = (ComInterfaceEntry*)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(WinFormsComWrappers), sizeof(ComInterfaceEntry));
wrapperEntry->IID = IID.IDropSource;
wrapperEntry->Vtable = iDropSourceVtbl;
return wrapperEntry;
}

protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
{
if (obj is Interop.Ole32.IStream)
Expand All @@ -76,6 +89,12 @@ private WinFormsComWrappers() { }
return s_fileDialogEventsEntry;
}

if (obj is Ole32.IDropSource)
{
count = 1;
return s_dropSourceEntry;
}

if (obj is IEnumString)
{
count = 1;
Expand Down

0 comments on commit 196b93b

Please # to comment.