VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.5 KB
RevLine 
[49947]1/* $Id: VBoxDnD.h 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBoxDnD.h - Windows-specific bits of the drag'n drop service.
4 */
5
6/*
[98103]7 * Copyright (C) 2013-2023 Oracle and/or its affiliates.
[49947]8 *
[96407]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
[49947]26 */
27
[76563]28#ifndef GA_INCLUDED_SRC_WINNT_VBoxTray_VBoxDnD_h
29#define GA_INCLUDED_SRC_WINNT_VBoxTray_VBoxDnD_h
[76540]30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
[49947]33
[50101]34#include <iprt/critsect.h>
35
[49947]36#include <iprt/cpp/mtlist.h>
37#include <iprt/cpp/ministring.h>
38
39class VBoxDnDWnd;
40
[85681]41/**
42 * Class for implementing IDataObject for VBoxTray's DnD support.
43 */
[49947]44class VBoxDnDDataObject : public IDataObject
45{
46public:
47
48 enum Status
49 {
[85694]50 Status_Uninitialized = 0,
51 Status_Initialized,
52 Status_Dropping,
53 Status_Dropped,
54 Status_Aborted,
55 Status_32Bit_Hack = 0x7fffffff
[49947]56 };
57
58public:
59
[56661]60 VBoxDnDDataObject(LPFORMATETC pFormatEtc = NULL, LPSTGMEDIUM pStgMed = NULL, ULONG cFormats = 0);
[49947]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
[56661]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);
[49947]76 STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc);
[56661]77 STDMETHOD(DAdvise)(LPFORMATETC pFormatEtc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
[49947]78 STDMETHOD(DUnadvise)(DWORD dwConnection);
79 STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppEnumAdvise);
80
81public:
82
83 static const char* ClipboardFormatToString(CLIPFORMAT fmt);
84
[95837]85 int Init(LPFORMATETC pFormatEtc, LPSTGMEDIUM pStgMed, ULONG cFormats);
86 int Destroy(void);
[49947]87 int Abort(void);
88 void SetStatus(Status status);
[85371]89 int Signal(const RTCString &strFormat, const void *pvData, size_t cbData);
[49947]90
91protected:
92
[56661]93 bool LookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex);
94 void RegisterFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, TYMED tyMed = TYMED_HGLOBAL,
[49947]95 LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL);
96
[85681]97 /** Current drag and drop status. */
[85694]98 Status m_enmStatus;
[85681]99 /** Internal reference count of this object. */
[85694]100 LONG m_cRefs;
[85681]101 /** Number of native formats registered. This can be a different number than supplied with m_lstFormats. */
[85694]102 ULONG m_cFormats;
[85681]103 /** Array of registered FORMATETC structs. Matches m_cFormats. */
[85694]104 LPFORMATETC m_paFormatEtc;
[85681]105 /** Array of registered STGMEDIUM structs. Matches m_cFormats. */
[85694]106 LPSTGMEDIUM m_paStgMedium;
[85681]107 /** Event semaphore used for waiting on status changes. */
[85694]108 RTSEMEVENT m_EvtDropped;
[85681]109 /** Format of currently retrieved data. */
[85694]110 RTCString m_strFormat;
[85681]111 /** The retrieved data as a raw buffer. */
[85694]112 void *m_pvData;
[85681]113 /** Raw buffer size (in bytes). */
[85694]114 size_t m_cbData;
[49947]115};
116
[85681]117/**
118 * Class for implementing IDropSource for VBoxTray's DnD support.
119 */
[49947]120class VBoxDnDDropSource : public IDropSource
121{
122public:
123
124 VBoxDnDDropSource(VBoxDnDWnd *pThis);
125 virtual ~VBoxDnDDropSource(void);
126
127public:
128
[85694]129 VBOXDNDACTION GetCurrentAction(void) { return m_enmActionCurrent; }
[49947]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
[59840]144 /** Reference count of this object. */
[85694]145 LONG m_cRefs;
[59840]146 /** Pointer to parent proxy window. */
[85694]147 VBoxDnDWnd *m_pWndParent;
[59840]148 /** Current drag effect. */
[85694]149 DWORD m_dwCurEffect;
[59840]150 /** Current action to perform on the host. */
[85694]151 VBOXDNDACTION m_enmActionCurrent;
[49947]152};
153
[85681]154/**
155 * Class for implementing IDropTarget for VBoxTray's DnD support.
156 */
[50101]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
[50102]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);
[50101]176
177protected:
178
[59840]179 static void DumpFormats(IDataObject *pDataObject);
[50101]180 static DWORD GetDropEffect(DWORD grfKeyState, DWORD dwAllowedEffects);
[50265]181 void reset(void);
[50101]182
[50177]183public:
184
[85681]185 /** Returns the data as mutable raw. Use with caution! */
[85694]186 void *DataMutableRaw(void) const { return m_pvData; }
[85681]187
188 /** Returns the data size (in bytes). */
[85694]189 size_t DataSize(void) const { return m_cbData; }
[85681]190
[59840]191 RTCString Formats(void) const;
[50265]192 int WaitForDrop(RTMSINTERVAL msTimeout);
[50177]193
[50101]194protected:
195
[59840]196 /** Reference count of this object. */
[85694]197 LONG m_cRefs;
[59840]198 /** Pointer to parent proxy window. */
[85694]199 VBoxDnDWnd *m_pWndParent;
[59840]200 /** Current drop effect. */
[85694]201 DWORD m_dwCurEffect;
[59840]202 /** Copy of the data object's current FORMATETC struct.
[55422]203 * Note: We don't keep the pointer of the DVTARGETDEVICE here! */
[85694]204 FORMATETC m_FormatEtc;
205 /** Stringified data object's format currently in use. */
206 RTCString m_strFormat;
[59840]207 /** Pointer to actual format data. */
[85694]208 void *m_pvData;
[59840]209 /** Size (in bytes) of format data. */
[85694]210 size_t m_cbData;
[59840]211 /** Event for waiting on the "drop" event. */
[85694]212 RTSEMEVENT m_EvtDrop;
[59840]213 /** Result of the drop event. */
[85694]214 int m_rcDropped;
[50101]215};
216
[85681]217/**
218 * Class for implementing IEnumFORMATETC for VBoxTray's DnD support.
219 */
[49947]220class VBoxDnDEnumFormatEtc : public IEnumFORMATETC
221{
222public:
223
[95837]224 VBoxDnDEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG uIdx, ULONG cToCopy, ULONG cTotal);
[50102]225 virtual ~VBoxDnDEnumFormatEtc(void);
[49947]226
227public:
228
[50102]229 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
230 STDMETHOD_(ULONG, AddRef)(void);
231 STDMETHOD_(ULONG, Release)(void);
[49947]232
[56661]233 STDMETHOD(Next)(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched);
[50102]234 STDMETHOD(Skip)(ULONG cFormats);
235 STDMETHOD(Reset)(void);
[56661]236 STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc);
[49947]237
238public:
239
[95837]240 int Init(LPFORMATETC pFormatEtc, ULONG uIdx, ULONG cToCopy, ULONG cTotal);
241
242public:
243
244 static int CopyFormat(LPFORMATETC pFormatDest, LPFORMATETC pFormatSource);
[56661]245 static HRESULT CreateEnumFormatEtc(UINT cFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc);
[49947]246
247private:
248
[85681]249 /** Reference count of this object. */
[85694]250 LONG m_cRefs;
[85681]251 /** Current index for format iteration. */
[85694]252 ULONG m_uIdxCur;
[85681]253 /** Number of format this object contains. */
[85694]254 ULONG m_cFormats;
255 /** Array of FORMATETC formats this object contains. Matches m_cFormats. */
256 LPFORMATETC m_paFormatEtc;
[49947]257};
[50101]258
259struct VBOXDNDCONTEXT;
260class VBoxDnDWnd;
261
[85681]262/**
[50101]263 * A drag'n drop event from the host.
264 */
265typedef struct VBOXDNDEVENT
266{
[74380]267 /** The actual DnD HGCM event data. */
268 PVBGLR3DNDEVENT pVbglR3Event;
[50101]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;
[73947]279 /** Started indicator. */
280 bool fStarted;
[50101]281 /** Shutdown indicator. */
282 bool fShutdown;
[57741]283 /** The registered window class. */
284 ATOM wndClass;
[50101]285 /** The DnD main event queue. */
286 RTCMTList<VBOXDNDEVENT> lstEvtQueue;
287 /** Semaphore for waiting on main event queue
288 * events. */
289 RTSEMEVENT hEvtQueueSem;
[51675]290 /** List of drag'n drop proxy windows.
291 * Note: At the moment only one window is supported. */
[50101]292 RTCMTList<VBoxDnDWnd*> lstWnd;
[57741]293 /** The DnD command context. */
294 VBGLR3GUESTDNDCMDCTX cmdCtx;
[50101]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
[83833]355 int Initialize(PVBOXDNDCONTEXT a_pCtx);
[51675]356 void Destroy(void);
[50101]357
358public:
359
[85121]360 /** The window's thread for the native message pump and OLE context. */
[85695]361 static DECLCALLBACK(int) Thread(RTTHREAD hThread, void *pvUser);
[50101]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
[76105]381 int Abort(void);
382
[74473]383 /* Host -> Guest */
[85694]384 int OnHgEnter(const RTCList<RTCString> &formats, VBOXDNDACTIONLIST m_lstActionsAllowed);
[74442]385 int OnHgMove(uint32_t u32xPos, uint32_t u32yPos, VBOXDNDACTION dndAction);
[50101]386 int OnHgDrop(void);
387 int OnHgLeave(void);
[74380]388 int OnHgDataReceive(PVBGLR3GUESTDNDMETADATA pMeta);
[50101]389 int OnHgCancel(void);
390
391#ifdef VBOX_WITH_DRAG_AND_DROP_GH
[74473]392 /* Guest -> Host */
[74380]393 int OnGhIsDnDPending(void);
[74442]394 int OnGhDrop(const RTCString &strFormat, VBOXDNDACTION dndActionDefault);
[50101]395#endif
396
[57741]397 void PostMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
[50101]398 int ProcessEvent(PVBOXDNDEVENT pEvent);
399
[74478]400 int Hide(void);
[74473]401 void Reset(void);
[50101]402
403protected:
404
[74476]405 int checkForSessionChange(void);
[50101]406 int makeFullscreen(void);
[50399]407 int mouseMove(int x, int y, DWORD dwMouseInputFlags);
408 int mouseRelease(void);
[50561]409 int setMode(Mode enmMode);
[50101]410
411public: /** @todo Make protected! */
412
413 /** Pointer to DnD context. */
[85694]414 PVBOXDNDCONTEXT m_pCtx;
[51675]415 /** The proxy window's main thread for processing
416 * window messages. */
[85694]417 RTTHREAD m_hThread;
[85681]418 /** Critical section to serialize access. */
[85694]419 RTCRITSECT m_CritSect;
[85681]420 /** Event semaphore to wait for new DnD events. */
[85694]421 RTSEMEVENT m_EvtSem;
[50101]422#ifdef RT_OS_WINDOWS
423 /** The window's handle. */
[85694]424 HWND m_hWnd;
[50101]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. */
[85694]429 RTCList<RTCString> m_lstFmtSup;
[50101]430 /** List of formats for the current
431 * drag'n drop operation. */
[85694]432 RTCList<RTCString> m_lstFmtActive;
[74439]433 /** List of all current drag'n drop actions allowed. */
[85694]434 VBOXDNDACTIONLIST m_lstActionsAllowed;
[50101]435 /** The startup information required
436 * for the actual DoDragDrop() call. */
[85694]437 VBOXDNDSTARTUPINFO m_startupInfo;
[50101]438 /** Is the left mouse button being pressed
439 * currently while being in this window? */
[85694]440 bool m_fMouseButtonDown;
[50101]441# ifdef VBOX_WITH_DRAG_AND_DROP_GH
[85681]442 /** Pointer to IDropTarget implementation for
443 * guest -> host support. */
[85694]444 VBoxDnDDropTarget *m_pDropTarget;
[50101]445# endif /* VBOX_WITH_DRAG_AND_DROP_GH */
[62194]446#else /* !RT_OS_WINDOWS */
[50101]447 /** @todo Implement me. */
[62194]448#endif /* !RT_OS_WINDOWS */
[50101]449
[55422]450 /** The window's own DnD context. */
[85694]451 VBGLR3GUESTDNDCMDCTX m_cmdCtx;
[50101]452 /** The current operation mode. */
[85694]453 Mode m_enmMode;
[50101]454 /** The current state. */
[85694]455 State m_enmState;
[51675]456 /** Format being requested. */
[85694]457 RTCString m_strFmtReq;
[50101]458};
[49947]459
[76563]460#endif /* !GA_INCLUDED_SRC_WINNT_VBoxTray_VBoxDnD_h */
[62194]461
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use