VirtualBox

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

Last change on this file since 51556 was 50561, checked in by vboxsync, 11 years ago

DnD: Update, bugfixes.

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