VirtualBox

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

Last change on this file since 74473 was 74473, checked in by vboxsync, 6 years ago

DnD/VBoxTray: Made the proxy window's reset() function public and use that one instead of hide() from other places.

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