VirtualBox

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

Last change on this file since 56661 was 56661, checked in by vboxsync, 9 years ago

DnD/VBoxTray: Also support retrieving plain text, added better (release) diagnostics, some renaming.

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