VirtualBox

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

Last change on this file since 96686 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

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