Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for drag images and drop descriptions #6576

Merged
merged 103 commits into from
Jul 5, 2022
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
33827ef
Allow drop targets to display a drag image while the cursor is over t…
willibrandon Jan 29, 2022
1ce2618
Tweak the drop description icon names.
willibrandon Feb 5, 2022
2fd573a
Merged from upstream
willibrandon Feb 25, 2022
bd2ccdf
Cleanup feedback from RussKie
willibrandon Feb 25, 2022
3152d4f
Build fix
willibrandon Feb 25, 2022
7ee1ac0
Add IDragSourceHelper2 interface, SHDRAGIMAGE structure, and implemen…
willibrandon Mar 10, 2022
07721df
Merge from upstream and resolve conflict.
willibrandon Mar 10, 2022
c1a0803
Add the Control.DoDratgDrop API for specifying the drag image bitmap.
willibrandon Mar 16, 2022
18fa962
Merge branch 'main' into 5884_DragImageDropDescription
willibrandon Mar 16, 2022
ec23acf
Fix naming rule violation.
willibrandon Mar 16, 2022
a63e71b
Implement a CopyDragDropStgMedium function for copying drag-and-drop …
willibrandon Mar 17, 2022
6e7813b
Remove unused DragDropHelper methods and add comments.
willibrandon Mar 18, 2022
aa54e1e
Add CopyDragDropStgMedium format validation and comments.
willibrandon Mar 20, 2022
e64aafd
Hide the PictureBox default pointer on the test form.
willibrandon Mar 20, 2022
07a2601
Cleanup feedback from RussKie.
willibrandon Mar 20, 2022
ff8edb6
Tweak DragDropHelper return values.
willibrandon Mar 20, 2022
ff9938d
Fix the cursor from getting stuck and fix the cursor offset.
willibrandon Mar 21, 2022
2d4ddee
Fix memory leak and add additional formats.
willibrandon Mar 22, 2022
8230dc9
Allow the application to specify the drag image bitmap via Givefeedba…
willibrandon Mar 22, 2022
f79fd07
Merge from main and resolve conflict
willibrandon Mar 23, 2022
6dc33dc
Add more comments.
willibrandon Mar 23, 2022
21f3d6a
Cleanup some feedback from welkante.
willibrandon Mar 31, 2022
0610164
Reject SetData calls which have a non-NULL target device pointer.
willibrandon Mar 31, 2022
0706f13
Add an internal drag and drop format class to hold related private fo…
willibrandon Apr 1, 2022
e941b12
Handle when the caller retains ownership of the storage medium and ma…
willibrandon Apr 1, 2022
b7fbae0
Reject incompatible storage medium types in IDataObject::SetData.
willibrandon Apr 1, 2022
e9a2f9b
Debug assert null target device pointer.
willibrandon Apr 1, 2022
3e09de5
Cleanup the return and let it fall through like previously.
willibrandon Apr 1, 2022
2c4444b
Add the Control.DoDragDrop API surface.
willibrandon Apr 2, 2022
5156bcb
Add the ToolStripItem.DoDragDrop API surface.
willibrandon Apr 3, 2022
daec799
Add drag image and drop description support for RichTextBox.
willibrandon Apr 3, 2022
e55259f
Add a RichTextBox demo to load DragAccept.rtf on DragDrop.
willibrandon Apr 3, 2022
2c2eaf9
Optimize drop description changes in DragLeave and Drop.
willibrandon Apr 3, 2022
91c5b39
Add a comment regarding IDataObject::GetData and when the Windows dra…
willibrandon Apr 4, 2022
b8b98a4
Improve the RichTextBox and ToolStrip demos.
willibrandon Apr 4, 2022
ea06211
Add the InShellDragLoop format.
willibrandon Apr 4, 2022
ce98fb2
Add data object support for CF_INDRAGLOOP.
willibrandon Apr 4, 2022
9df4aff
Use Marshal.ReleaseComObject instead of Marshal.FinalReleaseComObject.
willibrandon Apr 4, 2022
275dc8e
Finish adding support CFSTR_INDRAGLOOP.
willibrandon Apr 5, 2022
e3d02f3
Add support for dynamic addition of data during the drag loop through…
willibrandon Apr 5, 2022
d0d70fd
Fix the timing of the flag.
willibrandon Apr 5, 2022
4ff6ec2
Clean up the comments and code.
willibrandon Apr 6, 2022
4d6ef75
Free the DragDropFormat storage mediums after they are no longer in use.
willibrandon Apr 7, 2022
6f80f25
Fix the timing of the drag loop flag.
willibrandon Apr 7, 2022
cab7c8b
Give the DragDropFormat appropriate method names.
willibrandon Apr 7, 2022
ed696e7
Set InDragLoop in GiveFeedback for good measure.
willibrandon Apr 7, 2022
9978ee7
Wrap the drag loop in a try finally and reset InDragLoop.
willibrandon Apr 8, 2022
d36fe75
Merge from upstream and resolve conflicts
willibrandon May 5, 2022
b29b48a
Resolve nullable and mark members as static errors.
willibrandon May 5, 2022
3e22499
Track the DropSource last target handle using IDropSourceNotify::Drag…
willibrandon May 5, 2022
c9e925e
Cleanup feedback from dotnet api review
willibrandon May 5, 2022
4e020ad
Fix typo
willibrandon May 6, 2022
f698858
Check if the drop description values specified are valid
willibrandon May 6, 2022
ac6fd7d
Review feedback
willibrandon May 7, 2022
c70d975
Review feedback
willibrandon May 7, 2022
069b505
Move CopyMedium to the DragDropFormat class and rename it to CopyData
willibrandon May 7, 2022
7557ade
Remove unnecessary return and cleanup the demo
willibrandon May 7, 2022
d1748a1
Review feedback
willibrandon May 10, 2022
9bcd671
Update DropSource CCW to include support for IDropSourceNotify
willibrandon May 10, 2022
b7dfbfb
Review feedback
willibrandon May 10, 2022
82b30f5
Fix MessageReplacementToken conditional
willibrandon May 10, 2022
5622b7d
Be explicit about the entry indexes
willibrandon May 10, 2022
badf921
Review feedback
willibrandon May 10, 2022
80e2cb7
Wrap the methods calls in a try/catch and return HResult of exception
willibrandon May 10, 2022
8caf9bf
Remove the unnecessary checks in ToolStripDropTargetManager
willibrandon May 11, 2022
a82c81d
Simplify the checks in DropTarget
willibrandon May 11, 2022
50d0f30
Simplify the checks in RichTextBox.OleCallback
willibrandon May 11, 2022
5c68627
Simplify the checks in DropSource
willibrandon May 11, 2022
2b78ced
Review feedback, first round
willibrandon May 13, 2022
5041c0a
Remove the unused using
willibrandon May 13, 2022
870c4eb
Better way of checking the incoming data object
willibrandon May 13, 2022
96ef5a4
Have the designer generate the code
willibrandon May 14, 2022
27e3ab9
Put the update drag image logic in its own method
willibrandon May 14, 2022
e51a0e3
Review feedback
willibrandon May 14, 2022
955db62
Review feedback, second round
willibrandon May 15, 2022
2c3414a
Add the <returns> tag and describe the DragDropEffects return value
willibrandon May 15, 2022
cd0fa59
Add GiveFeedbackEventArgs remarks
willibrandon May 15, 2022
82ec322
Review feedback
willibrandon May 16, 2022
1bd2a6f
Review feedback and encapsulate the event argument equality logic
willibrandon May 17, 2022
169da25
Review feedback
willibrandon May 18, 2022
e645457
Merge from upstream and resolve conflict
willibrandon Jun 2, 2022
a2bf363
Fix duplicate symbols
willibrandon Jun 2, 2022
beb2124
Review feedback
willibrandon Jun 2, 2022
9a038a9
Add DragDropFormat unit tests
willibrandon Jun 3, 2022
dcef881
Supply named arguments for boolean parameters
willibrandon Jun 3, 2022
8669315
Cleanup the data source and variable name
willibrandon Jun 3, 2022
e943108
Add DragContext test data and generalize the tests
willibrandon Jun 4, 2022
6a00a2f
Add DragDropHelper unit tests
willibrandon Jun 4, 2022
56bb0d4
Skip test DragDropHelper_SetDragImage_ReturnsExptected
willibrandon Jun 4, 2022
608f067
Add DragEventArgsTests for newly added properties
willibrandon Jun 4, 2022
f343c22
Add GiveFeedbackEventArgs unit tests
willibrandon Jun 4, 2022
4d52d30
Add unit tests that verify thrown exceptions
willibrandon Jun 5, 2022
3101a43
Add UI integration test for DragEnter
willibrandon Jun 5, 2022
cefa154
Fix the fatal error on x86
willibrandon Jun 7, 2022
a0f667b
Tune up the test
willibrandon Jun 7, 2022
83c7539
Unskip the skipped tests
willibrandon Jun 7, 2022
662c8a0
Fix the hard coded delay
willibrandon Jun 7, 2022
df9bb0f
Fix SetDragImage tests
willibrandon Jun 7, 2022
d829f95
Review feedback
willibrandon Jun 8, 2022
45d7dbd
Check for illegal cross-thread calls in DragDropHelper
willibrandon Jun 8, 2022
8cd128f
Skip the problem tests
willibrandon Jun 8, 2022
81e78d9
Drag two items in the UI test
willibrandon Jun 8, 2022
229a700
Merge branch 'main' into 5884_DragImageDropDescription
JeremyKuhne Jul 1, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ internal static class CLSID
// 00BB2763-6A77-11D0-A535-00C04FD7D062
internal static Guid AutoComplete = new Guid(0x00BB2763, 0x6A77, 0x11D0, 0xA5, 0x35, 0x00, 0xC0, 0x4F, 0xD7, 0xD0, 0x62);

// 4657278A-411B-11D2-839A-00C04FD918D0
internal static Guid DragDropHelper = new Guid(0x4657278A, 0x411B, 0x11D2, 0x83, 0x9A, 0x0, 0xC0, 0x4F, 0xD9, 0x18, 0xD0);

// C0B4E2F3-BA21-4773-8DBA-335EC946EB8B
internal static Guid FileSaveDialog = new Guid(0xC0B4E2F3, 0xBA21, 0x4773, 0x8D, 0xBA, 0x33, 0x5E, 0xC9, 0x46, 0xEB, 0x8B);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// 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.InteropServices;

internal partial class Interop
{
internal static partial class Ole32
{
[ComImport]
[Guid("0000012B-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDropSourceNotfiy
willibrandon marked this conversation as resolved.
Show resolved Hide resolved
{
[PreserveSig]
HRESULT DragEnterTarget(
IntPtr hwndTarget);

[PreserveSig]
HRESULT DragLeaveTarget();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 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.InteropServices;
using static Interop.Kernel32;

internal static partial class Interop
{
internal static partial class Ole32
{
[DllImport(Libraries.Ole32, ExactSpelling = true)]
public static extern IntPtr OleDuplicateData(IntPtr hSrc, short cfFormat, GMEM uiFlags);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// 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.InteropServices;

internal partial class Interop
{
internal static partial class Shell32
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public unsafe struct DROPDESCRIPTION
{
private DROPIMAGETYPE _type;
private fixed char _szMessage[Kernel32.MAX_PATH];
private fixed char _szInsert[Kernel32.MAX_PATH];

private Span<char> szMessage
{
get { fixed (char* c = _szMessage) { return new Span<char>(c, Kernel32.MAX_PATH); } }
}

private Span<char> szInsert
{
get { fixed (char* c = _szInsert) { return new Span<char>(c, Kernel32.MAX_PATH); } }
}

public DROPIMAGETYPE Type
RussKie marked this conversation as resolved.
Show resolved Hide resolved
{
get => _type;
set => _type = value;
}

public ReadOnlySpan<char> Message
{
get => szMessage.SliceAtFirstNull();
set => SpanHelpers.CopyAndTerminate(value, szMessage);
}

public ReadOnlySpan<char> Insert
{
get => szInsert.SliceAtFirstNull();
set => SpanHelpers.CopyAndTerminate(value, szInsert);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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.

internal partial class Interop
{
internal static partial class Shell32
{
public enum DROPIMAGETYPE
{
DROPIMAGE_INVALID = -1,
DROPIMAGE_NONE = 0,
DROPIMAGE_COPY = 1,
DROPIMAGE_MOVE = 2,
DROPIMAGE_LINK = 4,
DROPIMAGE_LABEL = 6,
DROPIMAGE_WARNING = 7,
DROPIMAGE_NOIMAGE = 8
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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.Drawing;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

internal static partial class Interop
{
internal static partial class Shell32
{
[ComImport]
[Guid("DE5BF786-477A-11D2-839D-00C04FD918D0")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDragSourceHelper2
{
HRESULT InitializeFromBitmap(
SHDRAGIMAGE pshdi,
Copy link
Contributor

@kant2002 kant2002 Jun 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will double check this after I'm off work today, but if this fixes the issue, then I owe you big time. I was scratching my head quite a bit over this yesterday.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests succeeded and you are awesome! Thank you!

Copy link
Member

@RussKie RussKie Jun 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the docs, the struct is passed by ref, i.e., SHDRAGIMAGE* pshdi

IDataObject dataObject);

HRESULT InitializeFromWindow(
IntPtr hwnd,
Point ppt,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs indicate that the 2nd and 3rd args are pointers, since IDataObject is a ref type, it's passed by ref. But shouldn't it be Point* ppt?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess in is likely achieving the same, https://devblogs.microsoft.com/premier-developer/the-in-modifier-and-the-readonly-structs-in-c/. Though we generally strive to align with the native definitions where possible.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LPDATAOBJECT in C++ is IDataObject in C# in order to add ref we need at least LPLPDATAOBJECT in C++

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use in here, because other option to use ref and because [in] Point* I belive it's better capture that [in] modifier in C# which is possible nowadays.

IDataObject dataObject);

HRESULT SetFlags(
int dwFlags);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 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.Drawing;
using System.Runtime.InteropServices;
using IComDataObject = System.Runtime.InteropServices.ComTypes.IDataObject;

internal static partial class Interop
{
internal static partial class Shell32
{
[ComImport]
[Guid("4657278B-411B-11D2-839A-00C04FD918D0")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDropTargetHelper
{
[PreserveSig]
HRESULT DragEnter(
IntPtr hwndTarget,
[MarshalAs(UnmanagedType.Interface)]
RussKie marked this conversation as resolved.
Show resolved Hide resolved
IComDataObject pDataObj,
ref Point ppt,
uint dwEffect);
RussKie marked this conversation as resolved.
Show resolved Hide resolved

[PreserveSig]
HRESULT DragLeave();

[PreserveSig]
HRESULT DragOver(
ref Point ppt,
uint dwEffect);

[PreserveSig]
HRESULT Drop(
[MarshalAs(UnmanagedType.Interface)]
IComDataObject pDataObj,
ref Point ppt,
uint dwEffect);

[PreserveSig]
HRESULT Show(
BOOL fShow);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// 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.Drawing;
using System.Runtime.InteropServices;
using static Interop.Gdi32;

internal partial class Interop
{
internal static partial class Shell32
{
[StructLayout(LayoutKind.Sequential)]
public struct SHDRAGIMAGE
{
public Size sizeDragImage;
public Point ptOffset;
public HBITMAP hbmpDragImage;
public COLORREF crColorKey;
}
}
}
25 changes: 25 additions & 0 deletions src/System.Windows.Forms/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,28 @@ System.Windows.Forms.LinkArea.Equals(System.Windows.Forms.LinkArea other) -> boo
System.Windows.Forms.TableLayoutPanelCellPosition.Equals(System.Windows.Forms.TableLayoutPanelCellPosition other) -> bool
override System.Windows.Forms.Form.OnGotFocus(System.EventArgs! e) -> void
~override System.Windows.Forms.ToolStripDropDownMenu.CreateAccessibilityInstance() -> System.Windows.Forms.AccessibleObject
System.Windows.Forms.DropImageType
System.Windows.Forms.DropImageType.Invalid = -1 -> System.Windows.Forms.DropImageType
System.Windows.Forms.DropImageType.None = 0 -> System.Windows.Forms.DropImageType
System.Windows.Forms.DropImageType.Copy = 1 -> System.Windows.Forms.DropImageType
System.Windows.Forms.DropImageType.Move = 2 -> System.Windows.Forms.DropImageType
System.Windows.Forms.DropImageType.Link = 4 -> System.Windows.Forms.DropImageType
System.Windows.Forms.DropImageType.Label = 6 -> System.Windows.Forms.DropImageType
System.Windows.Forms.DropImageType.Warning = 7 -> System.Windows.Forms.DropImageType
System.Windows.Forms.DropImageType.NoImage = 8 -> System.Windows.Forms.DropImageType
~System.Windows.Forms.Control.DoDragDrop(object data, System.Windows.Forms.DragDropEffects allowedEffects, System.Drawing.Bitmap dragImage, System.Drawing.Point cursorOffset, bool useDefaultDragImage) -> System.Windows.Forms.DragDropEffects
~System.Windows.Forms.ToolStripItem.DoDragDrop(object data, System.Windows.Forms.DragDropEffects allowedEffects, System.Drawing.Bitmap dragImage, System.Drawing.Point cursorOffset, bool useDefaultDragImage) -> System.Windows.Forms.DragDropEffects
System.Windows.Forms.DragEventArgs.DragEventArgs(System.Windows.Forms.IDataObject? data, int keyState, int x, int y, System.Windows.Forms.DragDropEffects allowedEffect, System.Windows.Forms.DragDropEffects effect, System.Windows.Forms.DropImageType dropImageType, string! message, string! messageReplacementToken) -> void
System.Windows.Forms.DragEventArgs.DropImageType.get -> System.Windows.Forms.DropImageType
System.Windows.Forms.DragEventArgs.DropImageType.set -> void
System.Windows.Forms.DragEventArgs.Message.get -> string?
System.Windows.Forms.DragEventArgs.Message.set -> void
System.Windows.Forms.DragEventArgs.MessageReplacementToken.get -> string?
System.Windows.Forms.DragEventArgs.MessageReplacementToken.set -> void
System.Windows.Forms.GiveFeedbackEventArgs.GiveFeedbackEventArgs(System.Windows.Forms.DragDropEffects effect, bool useDefaultCursors, System.Drawing.Bitmap! dragImage, System.Drawing.Point cursorOffset, bool useDefaultDragImage) -> void
System.Windows.Forms.GiveFeedbackEventArgs.CursorOffset.get -> System.Drawing.Point
System.Windows.Forms.GiveFeedbackEventArgs.CursorOffset.set -> void
System.Windows.Forms.GiveFeedbackEventArgs.DragImage.get -> System.Drawing.Bitmap!
System.Windows.Forms.GiveFeedbackEventArgs.DragImage.set -> void
System.Windows.Forms.GiveFeedbackEventArgs.UseDefaultDragImage.get -> bool
System.Windows.Forms.GiveFeedbackEventArgs.UseDefaultDragImage.set -> void
32 changes: 28 additions & 4 deletions src/System.Windows.Forms/src/System/Windows/Forms/Control.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5292,8 +5292,19 @@ internal virtual void DisposeAxControls()
/// </summary>
public DragDropEffects DoDragDrop(object data, DragDropEffects allowedEffects)
{
Ole32.IDropSource dropSource = new DropSource(this);
return DoDragDrop(data, allowedEffects, dragImage: null, cursorOffset: default, useDefaultDragImage: false);
}

/// <summary>
/// Begins a drag operation. The allowedEffects determine which
/// drag operations can occur. If the drag operation needs to interop
/// with applications in another process, data should either be
/// a base managed class (String, Bitmap, or Metafile) or some Object
/// that implements System.Runtime.Serialization.ISerializable. data can also be any Object that
/// implements System.Windows.Forms.IDataObject.
/// </summary>
willibrandon marked this conversation as resolved.
Show resolved Hide resolved
public DragDropEffects DoDragDrop(object data, DragDropEffects allowedEffects, Bitmap dragImage, Point cursorOffset, bool useDefaultDragImage)
RussKie marked this conversation as resolved.
Show resolved Hide resolved
{
IComDataObject dataObject = null;

if (data is IComDataObject)
Expand All @@ -5316,10 +5327,23 @@ public DragDropEffects DoDragDrop(object data, DragDropEffects allowedEffects)
dataObject = (IComDataObject)iwdata;
}

HRESULT hr = Ole32.DoDragDrop(dataObject, dropSource, (Ole32.DROPEFFECT)allowedEffects, out Ole32.DROPEFFECT finalEffect);
if (!hr.Succeeded())
Ole32.DROPEFFECT finalEffect;

try
{
return DragDropEffects.None;
Ole32.IDropSource dropSource = new DropSource(this, dataObject, dragImage, cursorOffset, useDefaultDragImage);
HRESULT hr = Ole32.DoDragDrop(dataObject, dropSource, (Ole32.DROPEFFECT)allowedEffects, out finalEffect);
if (!hr.Succeeded())
{
return DragDropEffects.None;
}
}
finally
{
if (DragDropHelper.GetInDragLoop(dataObject))
{
DragDropHelper.SetInDragLoop(dataObject, false);
RussKie marked this conversation as resolved.
Show resolved Hide resolved
}
}

return (DragDropEffects)finalEffect;
Expand Down
30 changes: 30 additions & 0 deletions src/System.Windows.Forms/src/System/Windows/Forms/DataObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,19 @@ void IComDataObject.GetData(ref FORMATETC formatetc, out STGMEDIUM medium)
converter.OleDataObject.GetData(ref formatetc, out medium);
return;
}
else if (_innerData is IDataObject dataObject && DragDropHelper.GetInDragLoop(dataObject))
{
medium = new STGMEDIUM();
RussKie marked this conversation as resolved.
Show resolved Hide resolved
string formatName = DataFormats.GetFormat(formatetc.cfFormat).Name;
Debug.WriteLineIf(CompModSwitches.DataObject.TraceVerbose, $" InDragLoop {formatName}");
if (dataObject.GetDataPresent(formatName) && dataObject.GetData(formatName) is DragDropFormat dragDropFormat)
{
medium = dragDropFormat.GetData();
Debug.WriteLineIf(CompModSwitches.DataObject.TraceVerbose, $" drag-and-drop private format retrieved {formatName}");
willibrandon marked this conversation as resolved.
Show resolved Hide resolved
}

return;
}

medium = new STGMEDIUM();

Expand Down Expand Up @@ -670,6 +683,23 @@ void IComDataObject.SetData(ref FORMATETC pFormatetcIn, ref STGMEDIUM pmedium, b
converter.OleDataObject.SetData(ref pFormatetcIn, ref pmedium, fRelease);
return;
}
else if (_innerData is IDataObject dataObject
&& (DragDropHelper.GetInDragLoopFormat(pFormatetcIn) || DragDropHelper.GetInDragLoop(dataObject)))
{
string formatName = DataFormats.GetFormat(pFormatetcIn.cfFormat).Name;
Debug.WriteLineIf(CompModSwitches.DataObject.TraceVerbose, $" InDragLoop {formatName}");
if (dataObject.GetDataPresent(formatName) && dataObject.GetData(formatName) is DragDropFormat dragDropFormat)
{
dragDropFormat.RefreshData(pFormatetcIn.cfFormat, pmedium, fRelease);
}
else
{
dataObject.SetData(formatName, new DragDropFormat(pFormatetcIn.cfFormat, pmedium, fRelease));
Debug.WriteLineIf(CompModSwitches.DataObject.TraceVerbose, $" drag-and-drop private format loaded {formatName}");
}

return;
}

throw new NotImplementedException();
}
Expand Down
Loading