VirtualBox

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

Last change on this file since 69360 was 62194, checked in by vboxsync, 8 years ago

sigh, please get those #endif/#else marker right or just forward them to /dev/null. They're useless when wrong.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1/* $Id: VBoxDnD.h 62194 2016-07-12 13:03:21Z vboxsync $ */
2/** @file
3 * VBoxDnD.h - Windows-specific bits of the drag'n drop service.
4 */
5
6/*
7 * Copyright (C) 2013-2016 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 mSemEvent;
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 uint32_t GetCurrentAction(void) { return muCurAction; }
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 uint32_t muCurAction;
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 event data. */
220 VBGLR3DNDHGCMEVENT Event;
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 /** Shutdown indicator. */
232 bool fShutdown;
233 /** The registered window class. */
234 ATOM wndClass;
235 /** The DnD main event queue. */
236 RTCMTList<VBOXDNDEVENT> lstEvtQueue;
237 /** Semaphore for waiting on main event queue
238 * events. */
239 RTSEMEVENT hEvtQueueSem;
240 /** List of drag'n drop proxy windows.
241 * Note: At the moment only one window is supported. */
242 RTCMTList<VBoxDnDWnd*> lstWnd;
243 /** The DnD command context. */
244 VBGLR3GUESTDNDCMDCTX cmdCtx;
245
246} VBOXDNDCONTEXT, *PVBOXDNDCONTEXT;
247
248/**
249 * Everything which is required to successfully start
250 * a drag'n drop operation via DoDragDrop().
251 */
252typedef struct VBOXDNDSTARTUPINFO
253{
254 /** Our DnD data object, holding
255 * the raw DnD data. */
256 VBoxDnDDataObject *pDataObject;
257 /** The drop source for sending the
258 * DnD request to a IDropTarget. */
259 VBoxDnDDropSource *pDropSource;
260 /** The DnD effects which are wanted / allowed. */
261 DWORD dwOKEffects;
262
263} VBOXDNDSTARTUPINFO, *PVBOXDNDSTARTUPINFO;
264
265/**
266 * Class for handling a DnD proxy window.
267 ** @todo Unify this and VBoxClient's DragInstance!
268 */
269class VBoxDnDWnd
270{
271 /**
272 * Current state of a DnD proxy
273 * window.
274 */
275 enum State
276 {
277 Uninitialized = 0,
278 Initialized,
279 Dragging,
280 Dropped,
281 Canceled
282 };
283
284 /**
285 * Current operation mode of
286 * a DnD proxy window.
287 */
288 enum Mode
289 {
290 /** Unknown mode. */
291 Unknown = 0,
292 /** Host to guest. */
293 HG,
294 /** Guest to host. */
295 GH
296 };
297
298public:
299
300 VBoxDnDWnd(void);
301 virtual ~VBoxDnDWnd(void);
302
303public:
304
305 int Initialize(PVBOXDNDCONTEXT pContext);
306 void Destroy(void);
307
308public:
309
310 /** The window's thread for the native message pump and
311 * OLE context. */
312 static int Thread(RTTHREAD hThread, void *pvUser);
313
314public:
315
316 static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM lParam);
317 /** The per-instance wndproc routine. */
318 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
319
320public:
321
322#ifdef VBOX_WITH_DRAG_AND_DROP_GH
323 int RegisterAsDropTarget(void);
324 int UnregisterAsDropTarget(void);
325#endif
326
327public:
328
329 int OnCreate(void);
330 void OnDestroy(void);
331
332 /* H->G */
333 int OnHgEnter(const RTCList<RTCString> &formats, uint32_t uAllActions);
334 int OnHgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAllActions);
335 int OnHgDrop(void);
336 int OnHgLeave(void);
337 int OnHgDataReceived(const void *pvData, uint32_t cData);
338 int OnHgCancel(void);
339
340#ifdef VBOX_WITH_DRAG_AND_DROP_GH
341 /* G->H */
342 int OnGhIsDnDPending(uint32_t uScreenID);
343 int OnGhDropped(const char *pszFormat, uint32_t cbFormats, uint32_t uDefAction);
344#endif
345
346 void PostMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
347 int ProcessEvent(PVBOXDNDEVENT pEvent);
348
349public:
350
351 int hide(void);
352
353protected:
354
355 int makeFullscreen(void);
356 int mouseMove(int x, int y, DWORD dwMouseInputFlags);
357 int mouseRelease(void);
358 void reset(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 /** Flags of all current drag'n drop
382 * actions allowed. */
383 uint32_t uAllActions;
384 /** The startup information required
385 * for the actual DoDragDrop() call. */
386 VBOXDNDSTARTUPINFO startupInfo;
387 /** Is the left mouse button being pressed
388 * currently while being in this window? */
389 bool mfMouseButtonDown;
390# ifdef VBOX_WITH_DRAG_AND_DROP_GH
391 /** IDropTarget implementation for guest -> host
392 * support. */
393 VBoxDnDDropTarget *pDropTarget;
394# endif /* VBOX_WITH_DRAG_AND_DROP_GH */
395#else /* !RT_OS_WINDOWS */
396 /** @todo Implement me. */
397#endif /* !RT_OS_WINDOWS */
398
399 /** The window's own DnD context. */
400 VBGLR3GUESTDNDCMDCTX mDnDCtx;
401 /** The current operation mode. */
402 Mode mMode;
403 /** The current state. */
404 State mState;
405 /** Format being requested. */
406 RTCString mFormatRequested;
407};
408
409#endif /* !__VBOXTRAYDND__H */
410
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