Skip to content

Commit ec7b350

Browse files
authored
Update NotifyDropTargetAction.md
1 parent c3fe5df commit ec7b350

File tree

1 file changed

+29
-106
lines changed

1 file changed

+29
-106
lines changed

specs/NotifyDropTargetAction.md

Lines changed: 29 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ The hosting app needs to call RegisterDragDrop on the HWND that contains the Web
1919
calls (IDropTarget::DragEnter, DragMove, DragLeave, and Drop) to the WebView. Other UI frameworks have their own ways to register.
2020
For example, Xaml require setting event handler for DragEnter, DragOver, DragLeave, and Drop on the corresponding UIElement.
2121

22-
Additionally, for win32, the hosting app also needs to call into IDropTargetHelper before forwarding those calls to us as documented here:
23-
https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-idroptargethelper
24-
2522
For API reviewers, We want a unified API surface between COM and WinRT that works in both UWP and Win32.
2623

2724
We could:
@@ -34,17 +31,20 @@ Because the conversion is simple and we have a large Win32 user base we chose (1
3431

3532
# Description
3633
DragEnter, DragOver, DragLeave, and Drop are functions meant to provide a way for composition hosted WebViews to receive drop events as part of a drag/drop operation.
37-
It is the hosting application's responsibility to call RegisterDragDrop (https://docs.microsoft.com/en-us/windows/win32/api/ole2/nf-ole2-registerdragdrop)
38-
on the HWND that contains any composition hosted WebViews and to implement IDropTarget(https://docs.microsoft.com/en-us/windows/win32/api/oleidl/nn-oleidl-idroptarget)
34+
For win32, it is the hosting application's responsibility to call [RegisterDragDrop](https://docs.microsoft.com/en-us/windows/win32/api/ole2/nf-ole2-registerdragdrop)
35+
on the HWND that contains any composition hosted WebViews and to implement [IDropTarget](https://docs.microsoft.com/en-us/windows/win32/api/oleidl/nn-oleidl-idroptarget)
3936
to receive the corresponding drop events from Ole32:
4037

4138
- IDropTarget::DragEnter
4239
- IDropTarget::DragMove
4340
- IDropTarget::DragLeave
4441
- IDropTarget::Drop
4542

46-
For other UI frameworks such as Xaml, the hosting application would set event handlers for DragEnter, DragOver, DragLeave, and Drop
47-
on the UIElement that contains the WebView2 element.
43+
The HWND doesn't have to be the immediate parent of the WebView2 but it does have to convert the POINTL argument in the above functions from screen coordinates to client coordinates of the WebView2.
44+
45+
For WinRT, it is the hosting applications responsibility to register as a drop target via [CoreDragDropManager](https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.datatransfer.dragdrop.core.coredragdropmanager)
46+
on CoreDragDropManager.TargetRequested and to call [CoreDropOperationTargetRequestedEventArgs.SetTarget(ICoreDropOperationTarget)](https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.datatransfer.dragdrop.core.coredropoperationtargetrequestedeventargs)
47+
on an implementation of [ICoreDropOperationTarget](https://docs.microsoft.com/en-us/uwp/api/Windows.ApplicationModel.DataTransfer.DragDrop.Core.ICoreDropOperationTarget).
4848

4949
# Examples
5050
## Win32
@@ -54,17 +54,10 @@ on the UIElement that contains the WebView2 element.
5454
// Implementation for IDropTarget
5555
HRESULT DropTarget::DragEnter(IDataObject* dataObject,
5656
DWORD keyState,
57-
POINTL point,
57+
POINTL cursorPosition,
5858
DWORD* effect)
5959
{
6060
POINT point = { cursorPosition.x, cursorPosition.y };
61-
// Tell the helper that we entered so it can update the drag image and get
62-
// the correct effect.
63-
wil::com_ptr<IDropTargetHelper> dropHelper = DropHelper();
64-
if (dropHelper)
65-
{
66-
dropHelper->DragEnter(GetHWND(), dataObject, &point, *effect);
67-
}
6861

6962
// Convert the screen point to client coordinates add the WebView's offset.
7063
m_viewComponent->OffsetPointToWebView(&point);
@@ -73,17 +66,10 @@ HRESULT DropTarget::DragEnter(IDataObject* dataObject,
7366
}
7467

7568
HRESULT DropTarget::DragOver(DWORD keyState,
76-
POINTL point,
69+
POINTL cursorPosition,
7770
DWORD* effect)
7871
{
7972
POINT point = { cursorPosition.x, cursorPosition.y };
80-
// Tell the helper that we moved over it so it can update the drag image
81-
// and get the correct effect.
82-
wil::com_ptr<IDropTargetHelper> dropHelper = DropHelper();
83-
if (dropHelper)
84-
{
85-
dropHelper->DragOver(&point, *effect);
86-
}
8773

8874
// Convert the screen point to client coordinates add the WebView's offset.
8975
// This returns whether the resultant point is over the WebView visual.
@@ -94,29 +80,15 @@ HRESULT DropTarget::DragOver(DWORD keyState,
9480

9581
HRESULT DropTarget::DragLeave()
9682
{
97-
// Tell the helper that we moved out of it so it can update the drag image.
98-
wil::com_ptr<IDropTargetHelper> dropHelper = DropHelper();
99-
if (dropHelper)
100-
{
101-
dropHelper->DragLeave();
102-
}
103-
10483
return m_webViewCompositionController2->DragLeave();
10584
}
10685

10786
HRESULT DropTarget::Drop(IDataObject* dataObject,
10887
DWORD keyState,
109-
POINTL point,
88+
POINTL cursorPosition,
11089
DWORD* effect)
11190
{
11291
POINT point = { cursorPosition.x, cursorPosition.y };
113-
// Tell the helper that we dropped onto it so it can update the drag image
114-
// and get the correct effect.
115-
wil::com_ptr<IDropTargetHelper> dropHelper = DropHelper();
116-
if (dropHelper)
117-
{
118-
dropHelper->Drop(dataObject, &point, *effect);
119-
}
12092

12193
// Convert the screen point to client coordinates add the WebView's offset.
12294
// This returns whether the resultant point is over the WebView visual.
@@ -129,71 +101,24 @@ HRESULT DropTarget::Drop(IDataObject* dataObject,
129101
## WinRT
130102
```c#
131103
// WinRT Sample
132-
private void WebView_DragEnter(object sender, DragEventArgs e)
133-
{
134-
uint keyboardState =
135-
ConvertDragDropModifiersToWin32KeyboardState(e.Modifiers);
136-
Point pointerPosition = CoreWindow.GetForCurrentThread().PointerPosition;
137-
DataPackageOperation operation =
138-
(DataPackageOperation)webView2CompositionController.DragEnter(
139-
e.Data, keyboardState, pointerPosition);
140-
e.AcceptedOperation = operation;
141-
}
142-
143-
private void WebView_DragOver(object sender, DragEventArgs e)
104+
IAsyncOperation<DataPackageOperation> ICoreDropOperationTarget.EnterAsync(CoreDragInfo dragInfo, CoreDragUIOverride dragUIOverride)
144105
{
145-
uint keyboardState =
146-
ConvertDragDropModifiersToWin32KeyboardState(e.Modifiers);
147-
Point pointerPosition = CoreWindow.GetForCurrentThread().PointerPosition;
148-
DataPackageOperation operation =
149-
(DataPackageOperation)webView2CompositionController.DragOver(
150-
keyboardState, pointerPosition);
151-
e.AcceptedOperation = operation;
106+
return compositionController.DragEnter(dragInfo, dragUIOverride);
152107
}
153108
154-
private void WebView_DragLeave(object sender, DragEventArgs e)
109+
IAsyncOperation<DataPackageOperation> ICoreDropOperationTarget.OverAsync(CoreDragInfo dragInfo, CoreDragUIOverride dragUIOverride)
155110
{
156-
webView2CompositionController.DragLeave();
111+
return compositionController.DragOver(dragInfo, dragUIOverride);
157112
}
158113
159-
private void WebView_Drop(object sender, DragEventArgs e)
114+
IAsyncAction ICoreDropOperationTarget.LeaveAsync(CoreDragInfo dragInfo)
160115
{
161-
uint keyboardState =
162-
ConvertDragDropModifiersToWin32KeyboardState(e.Modifiers);
163-
Point pointerPosition = CoreWindow.GetForCurrentThread().PointerPosition;
164-
DataPackageOperation operation =
165-
(DataPackageOperation)webView2CompositionController.Drop(
166-
e.Data, keyboardState, pointerPosition);
167-
e.AcceptedOperation = operation;
116+
return compositionController.DragLeave(dragInfo);
168117
}
169118
170-
// Win32 keyboard state modifiers that are relevant during drag and drop.
171-
public const uint MK_LBUTTON = 1;
172-
public const uint MK_RBUTTON = 2;
173-
public const uint MK_SHIFT = 4;
174-
public const uint MK_CONTROL = 8;
175-
public const uint MK_MBUTTON = 16;
176-
public const uint MK_ALT = 32;
177-
178-
// Helper function to convert DragDropModifiers to win32 keyboard state
179-
// modifiers that WebView2 uses during drag and drop operation.
180-
private uint ConvertDragDropModifiersToWin32KeyboardState(
181-
Windows.ApplicationModel.DataTransfer.DragDrop.DragDropModifiers modifiers)
119+
IAsyncOperation<DataPackageOperation> ICoreDropOperationTarget.DropAsync(CoreDragInfo dragInfo)
182120
{
183-
uint win32DragDropModifiers = 0;
184-
if ((modifiers & DragDropModifiers.Shift) == DragDropModifiers.Shift)
185-
win32DragDropModifiers |= MK_SHIFT;
186-
if ((modifiers & DragDropModifiers.Control) == DragDropModifiers.Control)
187-
win32DragDropModifiers |= MK_CONTROL;
188-
if ((modifiers & DragDropModifiers.Alt) == DragDropModifiers.Alt)
189-
win32DragDropModifiers |= MK_ALT;
190-
if ((modifiers & DragDropModifiers.LeftButton) == DragDropModifiers.LeftButton)
191-
win32DragDropModifiers |= MK_LBUTTON;
192-
if ((modifiers & DragDropModifiers.MiddleButton) == DragDropModifiers.MiddleButton)
193-
win32DragDropModifiers |= MK_MBUTTON;
194-
if ((modifiers & DragDropModifiers.RightButton) == DragDropModifiers.RightButton)
195-
win32DragDropModifiers |= MK_RBUTTON;
196-
return win32DragDropModifiers;
121+
return compositionController.Drop(dragInfo);
197122
}
198123
```
199124

@@ -289,25 +214,23 @@ namespace Microsoft.Web.WebView2.Core
289214
public sealed class CoreWebView2CompositionController : CoreWebView2Controller, ICoreWebView2CompositionController2
290215
{
291216
// New APIs
292-
uint DragEnter(
293-
Windows.ApplicationModel.DataTransfer.DataPackage dataObject,
294-
uint keyState,
295-
Point point);
217+
Windows.ApplicationModel.DataTransfer.DataPackageOperation DragEnter(
218+
Windows.ApplicationModel.DataTransfer.DragDrop.Core.CoreDragInfo dragInfo,
219+
Windows.ApplicationModel.DataTransfer.DragDrop.Core.CoreDragUIOverride dragUIOverride);
296220

297-
void DragLeave();
221+
Windows.ApplicationModel.DataTransfer.DataPackageOperation DragLeave(
222+
Windows.ApplicationModel.DataTransfer.DragDrop.Core.CoreDragInfo dragInfo);
298223

299-
uint DragOver(
300-
uint keyState,
301-
Windows.Foundation.Point point);
224+
Windows.ApplicationModel.DataTransfer.DataPackageOperation DragOver(
225+
Windows.ApplicationModel.DataTransfer.DragDrop.Core.CoreDragInfo dragInfo,
226+
Windows.ApplicationModel.DataTransfer.DragDrop.Core.CoreDragUIOverride dragUIOverride);
302227

303-
uint Drop(
304-
Windows.ApplicationModel.DataTransfer.DataPackage dataObject,
305-
uint keyState,
306-
Windows.Foundation.Point point);
228+
Windows.ApplicationModel.DataTransfer.DataPackageOperation Drop(
229+
Windows.ApplicationModel.DataTransfer.DragDrop.Core.CoreDragInfo dragInfo);
307230
}
308231
}
309232
```
310233

311234
# Appendix
312235
A good resource to read about the whole Ole drag/drop is located here:
313-
https://docs.microsoft.com/en-us/cpp/mfc/drag-and-drop-ole?view=msvc-160#:~:text=You%20select%20the%20data%20from,than%20the%20copy%2Fpaste%20sequence.
236+
[OLE Drag and Drop](https://docs.microsoft.com/en-us/cpp/mfc/drag-and-drop-ole?view=msvc-160)

0 commit comments

Comments
 (0)