VirtualBox

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

Last change on this file since 53517 was 51675, checked in by vboxsync, 11 years ago

DnD/VBoxTray: Cleanup, documentation.

  • 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 51675 2014-06-20 10:17:20Z 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 /** The DnD main event queue. */
233 RTCMTList<VBOXDNDEVENT> lstEvtQueue;
234 /** Semaphore for waiting on main event queue
235 * events. */
236 RTSEMEVENT hEvtQueueSem;
237 /** List of drag'n drop proxy windows.
238 * Note: At the moment only one window is supported. */
239 RTCMTList<VBoxDnDWnd*> lstWnd;
240
241} VBOXDNDCONTEXT, *PVBOXDNDCONTEXT;
242static VBOXDNDCONTEXT gCtx = {0};
243
244/**
245 * Everything which is required to successfully start
246 * a drag'n drop operation via DoDragDrop().
247 */
248typedef struct VBOXDNDSTARTUPINFO
249{
250 /** Our DnD data object, holding
251 * the raw DnD data. */
252 VBoxDnDDataObject *pDataObject;
253 /** The drop source for sending the
254 * DnD request to a IDropTarget. */
255 VBoxDnDDropSource *pDropSource;
256 /** The DnD effects which are wanted / allowed. */
257 DWORD dwOKEffects;
258
259} VBOXDNDSTARTUPINFO, *PVBOXDNDSTARTUPINFO;
260
261/**
262 * Class for handling a DnD proxy window.
263 ** @todo Unify this and VBoxClient's DragInstance!
264 */
265class VBoxDnDWnd
266{
267 /**
268 * Current state of a DnD proxy
269 * window.
270 */
271 enum State
272 {
273 Uninitialized = 0,
274 Initialized,
275 Dragging,
276 Dropped,
277 Canceled
278 };
279
280 /**
281 * Current operation mode of
282 * a DnD proxy window.
283 */
284 enum Mode
285 {
286 /** Unknown mode. */
287 Unknown = 0,
288 /** Host to guest. */
289 HG,
290 /** Guest to host. */
291 GH
292 };
293
294public:
295
296 VBoxDnDWnd(void);
297 virtual ~VBoxDnDWnd(void);
298
299public:
300
301 int Initialize(PVBOXDNDCONTEXT pContext);
302 void Destroy(void);
303
304public:
305
306 /** The window's thread for the native message pump and
307 * OLE context. */
308 static int Thread(RTTHREAD hThread, void *pvUser);
309
310public:
311
312 static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM lParam);
313 /** The per-instance wndproc routine. */
314 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
315
316public:
317
318#ifdef VBOX_WITH_DRAG_AND_DROP_GH
319 int RegisterAsDropTarget(void);
320 int UnregisterAsDropTarget(void);
321#endif
322
323public:
324
325 int OnCreate(void);
326 void OnDestroy(void);
327
328 /* H->G */
329 int OnHgEnter(const RTCList<RTCString> &formats, uint32_t uAllActions);
330 int OnHgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAllActions);
331 int OnHgDrop(void);
332 int OnHgLeave(void);
333 int OnHgDataReceived(const void *pvData, uint32_t cData);
334 int OnHgCancel(void);
335
336#ifdef VBOX_WITH_DRAG_AND_DROP_GH
337 /* G->H */
338 int OnGhIsDnDPending(uint32_t uScreenID);
339 int OnGhDropped(const char *pszFormat, uint32_t cbFormats, uint32_t uDefAction);
340#endif
341
342 int ProcessEvent(PVBOXDNDEVENT pEvent);
343
344public:
345
346 int hide(void);
347
348protected:
349
350 int makeFullscreen(void);
351 int mouseMove(int x, int y, DWORD dwMouseInputFlags);
352 int mouseRelease(void);
353 void reset(void);
354 int setMode(Mode enmMode);
355
356public: /** @todo Make protected! */
357
358 /** Pointer to DnD context. */
359 PVBOXDNDCONTEXT pContext;
360 /** The proxy window's main thread for processing
361 * window messages. */
362 RTTHREAD hThread;
363 RTCRITSECT mCritSect;
364 RTSEMEVENT mEventSem;
365#ifdef RT_OS_WINDOWS
366 /** The window's handle. */
367 HWND hWnd;
368 /** List of allowed MIME types this
369 * client can handle. Make this a per-instance
370 * property so that we can selectively allow/forbid
371 * certain types later on runtime. */
372 RTCList<RTCString> lstAllowedFormats;
373 /** List of formats for the current
374 * drag'n drop operation. */
375 RTCList<RTCString> lstFormats;
376 /** Flags of all current drag'n drop
377 * actions allowed. */
378 uint32_t uAllActions;
379 /** The startup information required
380 * for the actual DoDragDrop() call. */
381 VBOXDNDSTARTUPINFO startupInfo;
382 /** Is the left mouse button being pressed
383 * currently while being in this window? */
384 bool mfMouseButtonDown;
385# ifdef VBOX_WITH_DRAG_AND_DROP_GH
386 /** IDropTarget implementation for guest -> host
387 * support. */
388 VBoxDnDDropTarget *pDropTarget;
389# endif /* VBOX_WITH_DRAG_AND_DROP_GH */
390#else
391 /** @todo Implement me. */
392#endif /* RT_OS_WINDOWS */
393
394 /** The window's own HGCM client ID. */
395 uint32_t mClientID;
396 /** The current operation mode. */
397 Mode mMode;
398 /** The current state. */
399 State mState;
400 /** Format being requested. */
401 RTCString mFormatRequested;
402};
403#endif /* __VBOXTRAYDND__H */
404
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