VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h@ 85681

Last change on this file since 85681 was 85681, checked in by vboxsync, 4 years ago

DnD: Lots of documentation.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.0 KB
Line 
1/* $Id: VBoxDnD.h 85681 2020-08-11 09:36:37Z vboxsync $ */
2/** @file
3 * VBoxDnD.h - Windows-specific bits of the drag'n drop service.
4 */
5
6/*
7 * Copyright (C) 2013-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef GA_INCLUDED_SRC_WINNT_VBoxTray_VBoxDnD_h
19#define GA_INCLUDED_SRC_WINNT_VBoxTray_VBoxDnD_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <iprt/critsect.h>
25
26#include <iprt/cpp/mtlist.h>
27#include <iprt/cpp/ministring.h>
28
29class VBoxDnDWnd;
30
31/**
32 * Class for implementing IDataObject for VBoxTray's DnD support.
33 */
34class VBoxDnDDataObject : public IDataObject
35{
36public:
37
38 enum Status
39 {
40 Uninitialized = 0,
41 Initialized,
42 Dropping,
43 Dropped,
44 Aborted
45 };
46
47public:
48
49 VBoxDnDDataObject(LPFORMATETC pFormatEtc = NULL, LPSTGMEDIUM pStgMed = NULL, ULONG cFormats = 0);
50 virtual ~VBoxDnDDataObject(void);
51
52public: /* IUnknown methods. */
53
54 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
55 STDMETHOD_(ULONG, AddRef)(void);
56 STDMETHOD_(ULONG, Release)(void);
57
58public: /* IDataObject methods. */
59
60 STDMETHOD(GetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
61 STDMETHOD(GetDataHere)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
62 STDMETHOD(QueryGetData)(LPFORMATETC pFormatEtc);
63 STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pFormatEct, LPFORMATETC pFormatEtcOut);
64 STDMETHOD(SetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium, BOOL fRelease);
65 STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc);
66 STDMETHOD(DAdvise)(LPFORMATETC pFormatEtc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
67 STDMETHOD(DUnadvise)(DWORD dwConnection);
68 STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppEnumAdvise);
69
70public:
71
72 static const char* ClipboardFormatToString(CLIPFORMAT fmt);
73
74 int Abort(void);
75 void SetStatus(Status status);
76 int Signal(const RTCString &strFormat, const void *pvData, size_t cbData);
77
78protected:
79
80 bool LookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex);
81 static HGLOBAL MemDup(HGLOBAL hMemSource);
82 void RegisterFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, TYMED tyMed = TYMED_HGLOBAL,
83 LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL);
84
85 /** Current drag and drop status. */
86 Status mStatus;
87 /** Internal reference count of this object. */
88 LONG mRefCount;
89 /** Number of native formats registered. This can be a different number than supplied with m_lstFormats. */
90 ULONG mcFormats;
91 /** Array of registered FORMATETC structs. Matches m_cFormats. */
92 LPFORMATETC mpFormatEtc;
93 /** Array of registered STGMEDIUM structs. Matches m_cFormats. */
94 LPSTGMEDIUM mpStgMedium;
95 /** Event semaphore used for waiting on status changes. */
96 RTSEMEVENT mEventDropped;
97 /** Format of currently retrieved data. */
98 RTCString mstrFormat;
99 /** The retrieved data as a raw buffer. */
100 void *mpvData;
101 /** Raw buffer size (in bytes). */
102 size_t mcbData;
103};
104
105/**
106 * Class for implementing IDropSource for VBoxTray's DnD support.
107 */
108class VBoxDnDDropSource : public IDropSource
109{
110public:
111
112 VBoxDnDDropSource(VBoxDnDWnd *pThis);
113 virtual ~VBoxDnDDropSource(void);
114
115public:
116
117 VBOXDNDACTION GetCurrentAction(void) { return mDnDActionCurrent; }
118
119public: /* IUnknown methods. */
120
121 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
122 STDMETHOD_(ULONG, AddRef)(void);
123 STDMETHOD_(ULONG, Release)(void);
124
125public: /* IDropSource methods. */
126
127 STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD dwKeyState);
128 STDMETHOD(GiveFeedback)(DWORD dwEffect);
129
130protected:
131
132 /** Reference count of this object. */
133 LONG mRefCount;
134 /** Pointer to parent proxy window. */
135 VBoxDnDWnd *mpWndParent;
136 /** Current drag effect. */
137 DWORD mdwCurEffect;
138 /** Current action to perform on the host. */
139 VBOXDNDACTION mDnDActionCurrent;
140};
141
142/**
143 * Class for implementing IDropTarget for VBoxTray's DnD support.
144 */
145class VBoxDnDDropTarget : public IDropTarget
146{
147public:
148
149 VBoxDnDDropTarget(VBoxDnDWnd *pThis);
150 virtual ~VBoxDnDDropTarget(void);
151
152public: /* IUnknown methods. */
153
154 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
155 STDMETHOD_(ULONG, AddRef)(void);
156 STDMETHOD_(ULONG, Release)(void);
157
158public: /* IDropTarget methods. */
159
160 STDMETHOD(DragEnter)(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
161 STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
162 STDMETHOD(DragLeave)(void);
163 STDMETHOD(Drop)(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
164
165protected:
166
167 static void DumpFormats(IDataObject *pDataObject);
168 static DWORD GetDropEffect(DWORD grfKeyState, DWORD dwAllowedEffects);
169 void reset(void);
170
171public:
172
173 /** Returns the data as mutable raw. Use with caution! */
174 void *DataMutableRaw(void) const { return mpvData; }
175
176 /** Returns the data size (in bytes). */
177 size_t DataSize(void) const { return mcbData; }
178
179 RTCString Formats(void) const;
180 int WaitForDrop(RTMSINTERVAL msTimeout);
181
182protected:
183
184 /** Reference count of this object. */
185 LONG mRefCount;
186 /** Pointer to parent proxy window. */
187 VBoxDnDWnd *mpWndParent;
188 /** Current drop effect. */
189 DWORD mdwCurEffect;
190 /** Copy of the data object's current FORMATETC struct.
191 * Note: We don't keep the pointer of the DVTARGETDEVICE here! */
192 FORMATETC mFormatEtc;
193 /** Stringified data object's formats string. */
194 RTCString mstrFormats;
195 /** Pointer to actual format data. */
196 void *mpvData;
197 /** Size (in bytes) of format data. */
198 size_t mcbData;
199 /** Event for waiting on the "drop" event. */
200 RTSEMEVENT hEventDrop;
201 /** Result of the drop event. */
202 int mDroppedRc;
203};
204
205/**
206 * Class for implementing IEnumFORMATETC for VBoxTray's DnD support.
207 */
208class VBoxDnDEnumFormatEtc : public IEnumFORMATETC
209{
210public:
211
212 VBoxDnDEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG cFormats);
213 virtual ~VBoxDnDEnumFormatEtc(void);
214
215public:
216
217 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
218 STDMETHOD_(ULONG, AddRef)(void);
219 STDMETHOD_(ULONG, Release)(void);
220
221 STDMETHOD(Next)(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched);
222 STDMETHOD(Skip)(ULONG cFormats);
223 STDMETHOD(Reset)(void);
224 STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc);
225
226public:
227
228 static void CopyFormat(LPFORMATETC pFormatDest, LPFORMATETC pFormatSource);
229 static HRESULT CreateEnumFormatEtc(UINT cFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc);
230
231private:
232
233 /** Reference count of this object. */
234 LONG m_lRefCount;
235 /** Current index for format iteration. */
236 ULONG m_nIndex;
237 /** Number of format this object contains. */
238 ULONG m_nNumFormats;
239 /** Array of FORMATETC formats this object contains. Matches m_nNumFormats. */
240 LPFORMATETC m_pFormatEtc;
241};
242
243struct VBOXDNDCONTEXT;
244class VBoxDnDWnd;
245
246/**
247 * A drag'n drop event from the host.
248 */
249typedef struct VBOXDNDEVENT
250{
251 /** The actual DnD HGCM event data. */
252 PVBGLR3DNDEVENT pVbglR3Event;
253
254} VBOXDNDEVENT, *PVBOXDNDEVENT;
255
256/**
257 * DnD context data.
258 */
259typedef struct VBOXDNDCONTEXT
260{
261 /** Pointer to the service environment. */
262 const VBOXSERVICEENV *pEnv;
263 /** Started indicator. */
264 bool fStarted;
265 /** Shutdown indicator. */
266 bool fShutdown;
267 /** The registered window class. */
268 ATOM wndClass;
269 /** The DnD main event queue. */
270 RTCMTList<VBOXDNDEVENT> lstEvtQueue;
271 /** Semaphore for waiting on main event queue
272 * events. */
273 RTSEMEVENT hEvtQueueSem;
274 /** List of drag'n drop proxy windows.
275 * Note: At the moment only one window is supported. */
276 RTCMTList<VBoxDnDWnd*> lstWnd;
277 /** The DnD command context. */
278 VBGLR3GUESTDNDCMDCTX cmdCtx;
279
280} VBOXDNDCONTEXT, *PVBOXDNDCONTEXT;
281
282/**
283 * Everything which is required to successfully start
284 * a drag'n drop operation via DoDragDrop().
285 */
286typedef struct VBOXDNDSTARTUPINFO
287{
288 /** Our DnD data object, holding
289 * the raw DnD data. */
290 VBoxDnDDataObject *pDataObject;
291 /** The drop source for sending the
292 * DnD request to a IDropTarget. */
293 VBoxDnDDropSource *pDropSource;
294 /** The DnD effects which are wanted / allowed. */
295 DWORD dwOKEffects;
296
297} VBOXDNDSTARTUPINFO, *PVBOXDNDSTARTUPINFO;
298
299/**
300 * Class for handling a DnD proxy window.
301 ** @todo Unify this and VBoxClient's DragInstance!
302 */
303class VBoxDnDWnd
304{
305 /**
306 * Current state of a DnD proxy
307 * window.
308 */
309 enum State
310 {
311 Uninitialized = 0,
312 Initialized,
313 Dragging,
314 Dropped,
315 Canceled
316 };
317
318 /**
319 * Current operation mode of
320 * a DnD proxy window.
321 */
322 enum Mode
323 {
324 /** Unknown mode. */
325 Unknown = 0,
326 /** Host to guest. */
327 HG,
328 /** Guest to host. */
329 GH
330 };
331
332public:
333
334 VBoxDnDWnd(void);
335 virtual ~VBoxDnDWnd(void);
336
337public:
338
339 int Initialize(PVBOXDNDCONTEXT a_pCtx);
340 void Destroy(void);
341
342public:
343
344 /** The window's thread for the native message pump and OLE context. */
345 static DECLCALLBACK(int) Thread(RTTHREAD hThread, void *pvUser);
346
347public:
348
349 static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM lParam);
350 /** The per-instance wndproc routine. */
351 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
352
353public:
354
355#ifdef VBOX_WITH_DRAG_AND_DROP_GH
356 int RegisterAsDropTarget(void);
357 int UnregisterAsDropTarget(void);
358#endif
359
360public:
361
362 int OnCreate(void);
363 void OnDestroy(void);
364
365 int Abort(void);
366
367 /* Host -> Guest */
368 int OnHgEnter(const RTCList<RTCString> &formats, VBOXDNDACTIONLIST dndLstActionsAllowed);
369 int OnHgMove(uint32_t u32xPos, uint32_t u32yPos, VBOXDNDACTION dndAction);
370 int OnHgDrop(void);
371 int OnHgLeave(void);
372 int OnHgDataReceive(PVBGLR3GUESTDNDMETADATA pMeta);
373 int OnHgCancel(void);
374
375#ifdef VBOX_WITH_DRAG_AND_DROP_GH
376 /* Guest -> Host */
377 int OnGhIsDnDPending(void);
378 int OnGhDrop(const RTCString &strFormat, VBOXDNDACTION dndActionDefault);
379#endif
380
381 void PostMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
382 int ProcessEvent(PVBOXDNDEVENT pEvent);
383
384 int Hide(void);
385 void Reset(void);
386
387protected:
388
389 int checkForSessionChange(void);
390 int makeFullscreen(void);
391 int mouseMove(int x, int y, DWORD dwMouseInputFlags);
392 int mouseRelease(void);
393 int setMode(Mode enmMode);
394
395public: /** @todo Make protected! */
396
397 /** Pointer to DnD context. */
398 PVBOXDNDCONTEXT pCtx;
399 /** The proxy window's main thread for processing
400 * window messages. */
401 RTTHREAD hThread;
402 /** Critical section to serialize access. */
403 RTCRITSECT mCritSect;
404 /** Event semaphore to wait for new DnD events. */
405 RTSEMEVENT mEventSem;
406#ifdef RT_OS_WINDOWS
407 /** The window's handle. */
408 HWND hWnd;
409 /** List of allowed MIME types this
410 * client can handle. Make this a per-instance
411 * property so that we can selectively allow/forbid
412 * certain types later on runtime. */
413 RTCList<RTCString> lstFmtSup;
414 /** List of formats for the current
415 * drag'n drop operation. */
416 RTCList<RTCString> lstFmtActive;
417 /** List of all current drag'n drop actions allowed. */
418 VBOXDNDACTIONLIST dndLstActionsAllowed;
419 /** The startup information required
420 * for the actual DoDragDrop() call. */
421 VBOXDNDSTARTUPINFO startupInfo;
422 /** Is the left mouse button being pressed
423 * currently while being in this window? */
424 bool mfMouseButtonDown;
425# ifdef VBOX_WITH_DRAG_AND_DROP_GH
426 /** Pointer to IDropTarget implementation for
427 * guest -> host support. */
428 VBoxDnDDropTarget *pDropTarget;
429# endif /* VBOX_WITH_DRAG_AND_DROP_GH */
430#else /* !RT_OS_WINDOWS */
431 /** @todo Implement me. */
432#endif /* !RT_OS_WINDOWS */
433
434 /** The window's own DnD context. */
435 VBGLR3GUESTDNDCMDCTX mDnDCtx;
436 /** The current operation mode. */
437 Mode mMode;
438 /** The current state. */
439 State mState;
440 /** Format being requested. */
441 RTCString mFormatRequested;
442};
443
444#endif /* !GA_INCLUDED_SRC_WINNT_VBoxTray_VBoxDnD_h */
445
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette