VirtualBox

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

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

Additions/VBoxTray:

  • Refactored internal services to use the RTThread API.
  • First take on cleaning up VBoxTray, separating the services more and more. See @todos.
  • Updated some code areas where deprecated APIs were used.
  • A lot of log formatting fixes and renaming.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 KB
Line 
1/* $Id: VBoxDnD.h 57741 2015-09-14 15:24:42Z 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
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 LONG mRefCount;
115 VBoxDnDWnd *mpWndParent;
116 VBGLR3GUESTDNDCMDCTX mDnDCtx;
117 DWORD mdwCurEffect;
118 uint32_t muCurAction;
119};
120
121class VBoxDnDDropTarget : public IDropTarget
122{
123public:
124
125 VBoxDnDDropTarget(VBoxDnDWnd *pThis);
126 virtual ~VBoxDnDDropTarget(void);
127
128public: /* IUnknown methods. */
129
130 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
131 STDMETHOD_(ULONG, AddRef)(void);
132 STDMETHOD_(ULONG, Release)(void);
133
134public: /* IDropTarget methods. */
135
136 STDMETHOD(DragEnter)(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
137 STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
138 STDMETHOD(DragLeave)(void);
139 STDMETHOD(Drop)(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
140
141protected:
142
143 static DWORD GetDropEffect(DWORD grfKeyState, DWORD dwAllowedEffects);
144 void reset(void);
145
146public:
147
148 void *DataMutableRaw(void) { return mpvData; }
149 uint32_t DataSize(void) { return mcbData; }
150 RTCString Formats(void);
151 int WaitForDrop(RTMSINTERVAL msTimeout);
152
153protected:
154
155 LONG mRefCount;
156 VBoxDnDWnd *mpWndParent;
157 VBGLR3GUESTDNDCMDCTX mDnDCtx;
158 DWORD mdwCurEffect;
159 /** Copy of the data object's FORMATETC struct.
160 * Note: We don't keep the pointer of the DVTARGETDEVICE here! */
161 FORMATETC mFormatEtc;
162 RTCString mFormats;
163 void *mpvData;
164 uint32_t mcbData;
165 RTSEMEVENT hEventDrop;
166 int mDroppedRc;
167};
168
169class VBoxDnDEnumFormatEtc : public IEnumFORMATETC
170{
171public:
172
173 VBoxDnDEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG cFormats);
174 virtual ~VBoxDnDEnumFormatEtc(void);
175
176public:
177
178 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
179 STDMETHOD_(ULONG, AddRef)(void);
180 STDMETHOD_(ULONG, Release)(void);
181
182 STDMETHOD(Next)(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched);
183 STDMETHOD(Skip)(ULONG cFormats);
184 STDMETHOD(Reset)(void);
185 STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc);
186
187public:
188
189 static void CopyFormat(LPFORMATETC pFormatDest, LPFORMATETC pFormatSource);
190 static HRESULT CreateEnumFormatEtc(UINT cFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc);
191
192private:
193
194 LONG m_lRefCount;
195 ULONG m_nIndex;
196 ULONG m_nNumFormats;
197 LPFORMATETC m_pFormatEtc;
198};
199
200struct VBOXDNDCONTEXT;
201class VBoxDnDWnd;
202
203/*
204 * A drag'n drop event from the host.
205 */
206typedef struct VBOXDNDEVENT
207{
208 /** The actual event data. */
209 VBGLR3DNDHGCMEVENT Event;
210
211} VBOXDNDEVENT, *PVBOXDNDEVENT;
212
213/**
214 * DnD context data.
215 */
216typedef struct VBOXDNDCONTEXT
217{
218 /** Pointer to the service environment. */
219 const VBOXSERVICEENV *pEnv;
220 /** Shutdown indicator. */
221 bool fShutdown;
222 /** The registered window class. */
223 ATOM wndClass;
224 /** The DnD main event queue. */
225 RTCMTList<VBOXDNDEVENT> lstEvtQueue;
226 /** Semaphore for waiting on main event queue
227 * events. */
228 RTSEMEVENT hEvtQueueSem;
229 /** List of drag'n drop proxy windows.
230 * Note: At the moment only one window is supported. */
231 RTCMTList<VBoxDnDWnd*> lstWnd;
232 /** The DnD command context. */
233 VBGLR3GUESTDNDCMDCTX cmdCtx;
234
235} VBOXDNDCONTEXT, *PVBOXDNDCONTEXT;
236
237/**
238 * Everything which is required to successfully start
239 * a drag'n drop operation via DoDragDrop().
240 */
241typedef struct VBOXDNDSTARTUPINFO
242{
243 /** Our DnD data object, holding
244 * the raw DnD data. */
245 VBoxDnDDataObject *pDataObject;
246 /** The drop source for sending the
247 * DnD request to a IDropTarget. */
248 VBoxDnDDropSource *pDropSource;
249 /** The DnD effects which are wanted / allowed. */
250 DWORD dwOKEffects;
251
252} VBOXDNDSTARTUPINFO, *PVBOXDNDSTARTUPINFO;
253
254/**
255 * Class for handling a DnD proxy window.
256 ** @todo Unify this and VBoxClient's DragInstance!
257 */
258class VBoxDnDWnd
259{
260 /**
261 * Current state of a DnD proxy
262 * window.
263 */
264 enum State
265 {
266 Uninitialized = 0,
267 Initialized,
268 Dragging,
269 Dropped,
270 Canceled
271 };
272
273 /**
274 * Current operation mode of
275 * a DnD proxy window.
276 */
277 enum Mode
278 {
279 /** Unknown mode. */
280 Unknown = 0,
281 /** Host to guest. */
282 HG,
283 /** Guest to host. */
284 GH
285 };
286
287public:
288
289 VBoxDnDWnd(void);
290 virtual ~VBoxDnDWnd(void);
291
292public:
293
294 int Initialize(PVBOXDNDCONTEXT pContext);
295 void Destroy(void);
296
297public:
298
299 /** The window's thread for the native message pump and
300 * OLE context. */
301 static int Thread(RTTHREAD hThread, void *pvUser);
302
303public:
304
305 static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM lParam);
306 /** The per-instance wndproc routine. */
307 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
308
309public:
310
311#ifdef VBOX_WITH_DRAG_AND_DROP_GH
312 int RegisterAsDropTarget(void);
313 int UnregisterAsDropTarget(void);
314#endif
315
316public:
317
318 int OnCreate(void);
319 void OnDestroy(void);
320
321 /* H->G */
322 int OnHgEnter(const RTCList<RTCString> &formats, uint32_t uAllActions);
323 int OnHgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAllActions);
324 int OnHgDrop(void);
325 int OnHgLeave(void);
326 int OnHgDataReceived(const void *pvData, uint32_t cData);
327 int OnHgCancel(void);
328
329#ifdef VBOX_WITH_DRAG_AND_DROP_GH
330 /* G->H */
331 int OnGhIsDnDPending(uint32_t uScreenID);
332 int OnGhDropped(const char *pszFormat, uint32_t cbFormats, uint32_t uDefAction);
333#endif
334
335 void PostMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
336 int ProcessEvent(PVBOXDNDEVENT pEvent);
337
338public:
339
340 int hide(void);
341
342protected:
343
344 int makeFullscreen(void);
345 int mouseMove(int x, int y, DWORD dwMouseInputFlags);
346 int mouseRelease(void);
347 void reset(void);
348 int setMode(Mode enmMode);
349
350public: /** @todo Make protected! */
351
352 /** Pointer to DnD context. */
353 PVBOXDNDCONTEXT pCtx;
354 /** The proxy window's main thread for processing
355 * window messages. */
356 RTTHREAD hThread;
357 RTCRITSECT mCritSect;
358 RTSEMEVENT mEventSem;
359#ifdef RT_OS_WINDOWS
360 /** The window's handle. */
361 HWND hWnd;
362 /** List of allowed MIME types this
363 * client can handle. Make this a per-instance
364 * property so that we can selectively allow/forbid
365 * certain types later on runtime. */
366 RTCList<RTCString> lstFmtSup;
367 /** List of formats for the current
368 * drag'n drop operation. */
369 RTCList<RTCString> lstFmtActive;
370 /** Flags of all current drag'n drop
371 * actions allowed. */
372 uint32_t uAllActions;
373 /** The startup information required
374 * for the actual DoDragDrop() call. */
375 VBOXDNDSTARTUPINFO startupInfo;
376 /** Is the left mouse button being pressed
377 * currently while being in this window? */
378 bool mfMouseButtonDown;
379# ifdef VBOX_WITH_DRAG_AND_DROP_GH
380 /** IDropTarget implementation for guest -> host
381 * support. */
382 VBoxDnDDropTarget *pDropTarget;
383# endif /* VBOX_WITH_DRAG_AND_DROP_GH */
384#else
385 /** @todo Implement me. */
386#endif /* RT_OS_WINDOWS */
387
388 /** The window's own DnD context. */
389 VBGLR3GUESTDNDCMDCTX mDnDCtx;
390 /** The current operation mode. */
391 Mode mMode;
392 /** The current state. */
393 State mState;
394 /** Format being requested. */
395 RTCString mFormatRequested;
396};
397#endif /* __VBOXTRAYDND__H */
398
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