VirtualBox

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

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

DnD/VBoxTray: Update; implemented own drop target for guest->host support (work in progress).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.5 KB
Line 
1/* $Id: VBoxDnD.h 50101 2014-01-17 23:33:40Z 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 static int CreateDropSource(VBoxDnDWnd *pParent, IDropSource **ppDropSource);
109
110public:
111
112 uint32_t GetCurrentAction(void) { return muCurAction; }
113
114public: /* IUnknown methods. */
115
116 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
117 STDMETHOD_(ULONG, AddRef)(void);
118 STDMETHOD_(ULONG, Release)(void);
119
120public: /* IDropSource methods. */
121
122 STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD dwKeyState);
123 STDMETHOD(GiveFeedback)(DWORD dwEffect);
124
125protected:
126
127 LONG mRefCount;
128 VBoxDnDWnd *mpWndParent;
129 uint32_t mClientID;
130 DWORD mdwCurEffect;
131 uint32_t muCurAction;
132};
133
134class VBoxDnDDropTarget : public IDropTarget
135{
136public:
137
138 VBoxDnDDropTarget(VBoxDnDWnd *pThis);
139 virtual ~VBoxDnDDropTarget(void);
140
141public:
142
143 static int CreateDropTarget(VBoxDnDWnd *pParent, IDropTarget **ppDropTarget);
144
145public: /* IUnknown methods. */
146
147 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
148 STDMETHOD_(ULONG, AddRef)(void);
149 STDMETHOD_(ULONG, Release)(void);
150
151public: /* IDropTarget methods. */
152
153 STDMETHOD(DragEnter)(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
154 STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
155 STDMETHOD(DragLeave)(void);
156 STDMETHOD(Drop)(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
157
158protected:
159
160 static DWORD GetDropEffect(DWORD grfKeyState, DWORD dwAllowedEffects);
161
162protected:
163
164 LONG mRefCount;
165 VBoxDnDWnd *mpWndParent;
166 uint32_t mClientID;
167 DWORD mdwCurEffect;
168 IDataObject *mpDataObject;
169 bool mfHasDropData;
170};
171
172class VBoxDnDEnumFormatEtc : public IEnumFORMATETC
173{
174public:
175
176 VBoxDnDEnumFormatEtc(FORMATETC *pFormatEtc, ULONG cFormats);
177 virtual ~VBoxDnDEnumFormatEtc(void);
178
179public:
180
181 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
182 STDMETHOD_(ULONG, AddRef)(void);
183 STDMETHOD_(ULONG, Release)(void);
184
185 STDMETHOD(Next)(ULONG cFormats, FORMATETC *pFormatEtc, ULONG *pcFetched);
186 STDMETHOD(Skip)(ULONG cFormats);
187 STDMETHOD(Reset)(void);
188 STDMETHOD(Clone)(IEnumFORMATETC ** ppEnumFormatEtc);
189
190public:
191
192 static void CopyFormat(FORMATETC *pFormatDest, FORMATETC *pFormatSource);
193 static HRESULT CreateEnumFormatEtc(UINT cFormats, FORMATETC *pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc);
194
195private:
196
197 LONG m_lRefCount;
198 ULONG m_nIndex;
199 ULONG m_nNumFormats;
200 FORMATETC * m_pFormatEtc;
201};
202
203struct VBOXDNDCONTEXT;
204class VBoxDnDWnd;
205
206/*
207 * A drag'n drop event from the host.
208 */
209typedef struct VBOXDNDEVENT
210{
211 /** The actual event data. */
212 VBGLR3DNDHGCMEVENT Event;
213
214} VBOXDNDEVENT, *PVBOXDNDEVENT;
215
216/**
217 * DnD context data.
218 */
219typedef struct VBOXDNDCONTEXT
220{
221 /** Pointer to the service environment. */
222 const VBOXSERVICEENV *pEnv;
223 /** Shutdown indicator. */
224 bool fShutdown;
225 /** Thread handle for main event queue
226 * processing. */
227 RTTHREAD hEvtQueue;
228 /** The DnD main event queue. */
229 RTCMTList<VBOXDNDEVENT> lstEvtQueue;
230 /** Semaphore for waiting on main event queue
231 * events. */
232 RTSEMEVENT hEvtQueueSem;
233 /** List of drag'n drop windows. At
234 * the moment only one source is supported. */
235 RTCMTList<VBoxDnDWnd*> lstWnd;
236
237} VBOXDNDCONTEXT, *PVBOXDNDCONTEXT;
238static VBOXDNDCONTEXT gCtx = {0};
239
240/**
241 * Everything which is required to successfully start
242 * a drag'n drop operation via DoDragDrop().
243 */
244typedef struct VBOXDNDSTARTUPINFO
245{
246 /** Our DnD data object, holding
247 * the raw DnD data. */
248 VBoxDnDDataObject *pDataObject;
249 /** The drop source for sending the
250 * DnD request to a IDropTarget. */
251 VBoxDnDDropSource *pDropSource;
252 /** The DnD effects which are wanted / allowed. */
253 DWORD dwOKEffects;
254
255} VBOXDNDSTARTUPINFO, *PVBOXDNDSTARTUPINFO;
256
257/**
258 * Class for handling a DnD proxy window.
259 ** @todo Unify this and VBoxClient's DragInstance!
260 */
261class VBoxDnDWnd
262{
263 /**
264 * Current state of a DnD proxy
265 * window.
266 */
267 enum State
268 {
269 Uninitialized = 0,
270 Initialized,
271 Dragging,
272 Dropped,
273 Canceled
274 };
275
276 /**
277 * Current operation mode of
278 * a DnD proxy window.
279 */
280 enum Mode
281 {
282 /** Unknown mode. */
283 Unknown = 0,
284 /** Host to guest. */
285 HG,
286 /** Guest to host. */
287 GH
288 };
289
290public:
291
292 VBoxDnDWnd(void);
293 virtual ~VBoxDnDWnd(void);
294
295public:
296
297 int Initialize(PVBOXDNDCONTEXT pContext);
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 *pszFormats, 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 dragRelease(void);
346 int makeFullscreen(void);
347 void reset(void);
348
349public: /** @todo Make protected! */
350
351 /** Pointer to DnD context. */
352 PVBOXDNDCONTEXT pContext;
353 RTCRITSECT mCritSect;
354 RTSEMEVENT mEventSem;
355#ifdef RT_OS_WINDOWS
356 /** The window's handle. */
357 HWND hWnd;
358 /** List of allowed MIME types this
359 * client can handle. Make this a per-instance
360 * property so that we can selectively allow/forbid
361 * certain types later on runtime. */
362 RTCList<RTCString> lstAllowedFormats;
363 /** List of formats for the current
364 * drag'n drop operation. */
365 RTCList<RTCString> lstFormats;
366 /** Flags of all current drag'n drop
367 * actions allowed. */
368 uint32_t uAllActions;
369 /** The startup information required
370 * for the actual DoDragDrop() call. */
371 VBOXDNDSTARTUPINFO startupInfo;
372 /** Is the left mouse button being pressed
373 * currently while being in this window? */
374 bool mfMouseButtonDown;
375# ifdef VBOX_WITH_DRAG_AND_DROP_GH
376 IDropTarget *pDropTarget;
377# endif /* VBOX_WITH_DRAG_AND_DROP_GH */
378#else
379 /** @todo Implement me. */
380#endif
381
382 /** The window's own HGCM client ID. */
383 uint32_t mClientID;
384 /** The current operation mode. */
385 Mode mMode;
386 /** The current state. */
387 State mState;
388 RTCString mFormatRequested;
389 RTCList<RTCString> mLstFormats;
390 RTCList<RTCString> mLstActions;
391};
392#endif /* __VBOXTRAYDND__H */
393
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