VirtualBox

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

最後變更 在這個檔案從95890是 95837,由 vboxsync 提交於 3 年 前

DnD/VBoxTray: Resolved some @todos (use dedicated init functions) + fixed a memory leak in VBoxDnDDataObject. Added missing documentation [build fix]. bugref:10267

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 13.3 KB
 
1/* $Id: VBoxDnD.h 95837 2022-07-26 16:16:31Z vboxsync $ */
2/** @file
3 * VBoxDnD.h - Windows-specific bits of the drag'n drop service.
4 */
5
6/*
7 * Copyright (C) 2013-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.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 GA_INCLUDED_SRC_WINNT_VBoxTray_VBoxDnD_h
19#define GA_INCLUDED_SRC_WINNT_VBoxTray_VBoxDnD_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <iprt/critsect.h>
25
26#include <iprt/cpp/mtlist.h>
27#include <iprt/cpp/ministring.h>
28
29class VBoxDnDWnd;
30
31/**
32 * Class for implementing IDataObject for VBoxTray's DnD support.
33 */
34class VBoxDnDDataObject : public IDataObject
35{
36public:
37
38 enum Status
39 {
40 Status_Uninitialized = 0,
41 Status_Initialized,
42 Status_Dropping,
43 Status_Dropped,
44 Status_Aborted,
45 Status_32Bit_Hack = 0x7fffffff
46 };
47
48public:
49
50 VBoxDnDDataObject(LPFORMATETC pFormatEtc = NULL, LPSTGMEDIUM pStgMed = NULL, ULONG cFormats = 0);
51 virtual ~VBoxDnDDataObject(void);
52
53public: /* IUnknown methods. */
54
55 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
56 STDMETHOD_(ULONG, AddRef)(void);
57 STDMETHOD_(ULONG, Release)(void);
58
59public: /* IDataObject methods. */
60
61 STDMETHOD(GetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
62 STDMETHOD(GetDataHere)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
63 STDMETHOD(QueryGetData)(LPFORMATETC pFormatEtc);
64 STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pFormatEct, LPFORMATETC pFormatEtcOut);
65 STDMETHOD(SetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium, BOOL fRelease);
66 STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc);
67 STDMETHOD(DAdvise)(LPFORMATETC pFormatEtc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
68 STDMETHOD(DUnadvise)(DWORD dwConnection);
69 STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppEnumAdvise);
70
71public:
72
73 static const char* ClipboardFormatToString(CLIPFORMAT fmt);
74
75 int Init(LPFORMATETC pFormatEtc, LPSTGMEDIUM pStgMed, ULONG cFormats);
76 int Destroy(void);
77 int Abort(void);
78 void SetStatus(Status status);
79 int Signal(const RTCString &strFormat, const void *pvData, size_t cbData);
80
81protected:
82
83 bool LookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex);
84 void RegisterFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, TYMED tyMed = TYMED_HGLOBAL,
85 LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL);
86
87 /** Current drag and drop status. */
88 Status m_enmStatus;
89 /** Internal reference count of this object. */
90 LONG m_cRefs;
91 /** Number of native formats registered. This can be a different number than supplied with m_lstFormats. */
92 ULONG m_cFormats;
93 /** Array of registered FORMATETC structs. Matches m_cFormats. */
94 LPFORMATETC m_paFormatEtc;
95 /** Array of registered STGMEDIUM structs. Matches m_cFormats. */
96 LPSTGMEDIUM m_paStgMedium;
97 /** Event semaphore used for waiting on status changes. */
98 RTSEMEVENT m_EvtDropped;
99 /** Format of currently retrieved data. */
100 RTCString m_strFormat;
101 /** The retrieved data as a raw buffer. */
102 void *m_pvData;
103 /** Raw buffer size (in bytes). */
104 size_t m_cbData;
105};
106
107/**
108 * Class for implementing IDropSource for VBoxTray's DnD support.
109 */
110class VBoxDnDDropSource : public IDropSource
111{
112public:
113
114 VBoxDnDDropSource(VBoxDnDWnd *pThis);
115 virtual ~VBoxDnDDropSource(void);
116
117public:
118
119 VBOXDNDACTION GetCurrentAction(void) { return m_enmActionCurrent; }
120
121public: /* IUnknown methods. */
122
123 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
124 STDMETHOD_(ULONG, AddRef)(void);
125 STDMETHOD_(ULONG, Release)(void);
126
127public: /* IDropSource methods. */
128
129 STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD dwKeyState);
130 STDMETHOD(GiveFeedback)(DWORD dwEffect);
131
132protected:
133
134 /** Reference count of this object. */
135 LONG m_cRefs;
136 /** Pointer to parent proxy window. */
137 VBoxDnDWnd *m_pWndParent;
138 /** Current drag effect. */
139 DWORD m_dwCurEffect;
140 /** Current action to perform on the host. */
141 VBOXDNDACTION m_enmActionCurrent;
142};
143
144/**
145 * Class for implementing IDropTarget for VBoxTray's DnD support.
146 */
147class VBoxDnDDropTarget : public IDropTarget
148{
149public:
150
151 VBoxDnDDropTarget(VBoxDnDWnd *pThis);
152 virtual ~VBoxDnDDropTarget(void);
153
154public: /* IUnknown methods. */
155
156 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
157 STDMETHOD_(ULONG, AddRef)(void);
158 STDMETHOD_(ULONG, Release)(void);
159
160public: /* IDropTarget methods. */
161
162 STDMETHOD(DragEnter)(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
163 STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
164 STDMETHOD(DragLeave)(void);
165 STDMETHOD(Drop)(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
166
167protected:
168
169 static void DumpFormats(IDataObject *pDataObject);
170 static DWORD GetDropEffect(DWORD grfKeyState, DWORD dwAllowedEffects);
171 void reset(void);
172
173public:
174
175 /** Returns the data as mutable raw. Use with caution! */
176 void *DataMutableRaw(void) const { return m_pvData; }
177
178 /** Returns the data size (in bytes). */
179 size_t DataSize(void) const { return m_cbData; }
180
181 RTCString Formats(void) const;
182 int WaitForDrop(RTMSINTERVAL msTimeout);
183
184protected:
185
186 /** Reference count of this object. */
187 LONG m_cRefs;
188 /** Pointer to parent proxy window. */
189 VBoxDnDWnd *m_pWndParent;
190 /** Current drop effect. */
191 DWORD m_dwCurEffect;
192 /** Copy of the data object's current FORMATETC struct.
193 * Note: We don't keep the pointer of the DVTARGETDEVICE here! */
194 FORMATETC m_FormatEtc;
195 /** Stringified data object's format currently in use. */
196 RTCString m_strFormat;
197 /** Pointer to actual format data. */
198 void *m_pvData;
199 /** Size (in bytes) of format data. */
200 size_t m_cbData;
201 /** Event for waiting on the "drop" event. */
202 RTSEMEVENT m_EvtDrop;
203 /** Result of the drop event. */
204 int m_rcDropped;
205};
206
207/**
208 * Class for implementing IEnumFORMATETC for VBoxTray's DnD support.
209 */
210class VBoxDnDEnumFormatEtc : public IEnumFORMATETC
211{
212public:
213
214 VBoxDnDEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG uIdx, ULONG cToCopy, ULONG cTotal);
215 virtual ~VBoxDnDEnumFormatEtc(void);
216
217public:
218
219 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
220 STDMETHOD_(ULONG, AddRef)(void);
221 STDMETHOD_(ULONG, Release)(void);
222
223 STDMETHOD(Next)(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched);
224 STDMETHOD(Skip)(ULONG cFormats);
225 STDMETHOD(Reset)(void);
226 STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc);
227
228public:
229
230 int Init(LPFORMATETC pFormatEtc, ULONG uIdx, ULONG cToCopy, ULONG cTotal);
231
232public:
233
234 static int CopyFormat(LPFORMATETC pFormatDest, LPFORMATETC pFormatSource);
235 static HRESULT CreateEnumFormatEtc(UINT cFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc);
236
237private:
238
239 /** Reference count of this object. */
240 LONG m_cRefs;
241 /** Current index for format iteration. */
242 ULONG m_uIdxCur;
243 /** Number of format this object contains. */
244 ULONG m_cFormats;
245 /** Array of FORMATETC formats this object contains. Matches m_cFormats. */
246 LPFORMATETC m_paFormatEtc;
247};
248
249struct VBOXDNDCONTEXT;
250class VBoxDnDWnd;
251
252/**
253 * A drag'n drop event from the host.
254 */
255typedef struct VBOXDNDEVENT
256{
257 /** The actual DnD HGCM event data. */
258 PVBGLR3DNDEVENT pVbglR3Event;
259
260} VBOXDNDEVENT, *PVBOXDNDEVENT;
261
262/**
263 * DnD context data.
264 */
265typedef struct VBOXDNDCONTEXT
266{
267 /** Pointer to the service environment. */
268 const VBOXSERVICEENV *pEnv;
269 /** Started indicator. */
270 bool fStarted;
271 /** Shutdown indicator. */
272 bool fShutdown;
273 /** The registered window class. */
274 ATOM wndClass;
275 /** The DnD main event queue. */
276 RTCMTList<VBOXDNDEVENT> lstEvtQueue;
277 /** Semaphore for waiting on main event queue
278 * events. */
279 RTSEMEVENT hEvtQueueSem;
280 /** List of drag'n drop proxy windows.
281 * Note: At the moment only one window is supported. */
282 RTCMTList<VBoxDnDWnd*> lstWnd;
283 /** The DnD command context. */
284 VBGLR3GUESTDNDCMDCTX cmdCtx;
285
286} VBOXDNDCONTEXT, *PVBOXDNDCONTEXT;
287
288/**
289 * Everything which is required to successfully start
290 * a drag'n drop operation via DoDragDrop().
291 */
292typedef struct VBOXDNDSTARTUPINFO
293{
294 /** Our DnD data object, holding
295 * the raw DnD data. */
296 VBoxDnDDataObject *pDataObject;
297 /** The drop source for sending the
298 * DnD request to a IDropTarget. */
299 VBoxDnDDropSource *pDropSource;
300 /** The DnD effects which are wanted / allowed. */
301 DWORD dwOKEffects;
302
303} VBOXDNDSTARTUPINFO, *PVBOXDNDSTARTUPINFO;
304
305/**
306 * Class for handling a DnD proxy window.
307 ** @todo Unify this and VBoxClient's DragInstance!
308 */
309class VBoxDnDWnd
310{
311 /**
312 * Current state of a DnD proxy
313 * window.
314 */
315 enum State
316 {
317 Uninitialized = 0,
318 Initialized,
319 Dragging,
320 Dropped,
321 Canceled
322 };
323
324 /**
325 * Current operation mode of
326 * a DnD proxy window.
327 */
328 enum Mode
329 {
330 /** Unknown mode. */
331 Unknown = 0,
332 /** Host to guest. */
333 HG,
334 /** Guest to host. */
335 GH
336 };
337
338public:
339
340 VBoxDnDWnd(void);
341 virtual ~VBoxDnDWnd(void);
342
343public:
344
345 int Initialize(PVBOXDNDCONTEXT a_pCtx);
346 void Destroy(void);
347
348public:
349
350 /** The window's thread for the native message pump and OLE context. */
351 static DECLCALLBACK(int) Thread(RTTHREAD hThread, void *pvUser);
352
353public:
354
355 static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM lParam);
356 /** The per-instance wndproc routine. */
357 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
358
359public:
360
361#ifdef VBOX_WITH_DRAG_AND_DROP_GH
362 int RegisterAsDropTarget(void);
363 int UnregisterAsDropTarget(void);
364#endif
365
366public:
367
368 int OnCreate(void);
369 void OnDestroy(void);
370
371 int Abort(void);
372
373 /* Host -> Guest */
374 int OnHgEnter(const RTCList<RTCString> &formats, VBOXDNDACTIONLIST m_lstActionsAllowed);
375 int OnHgMove(uint32_t u32xPos, uint32_t u32yPos, VBOXDNDACTION dndAction);
376 int OnHgDrop(void);
377 int OnHgLeave(void);
378 int OnHgDataReceive(PVBGLR3GUESTDNDMETADATA pMeta);
379 int OnHgCancel(void);
380
381#ifdef VBOX_WITH_DRAG_AND_DROP_GH
382 /* Guest -> Host */
383 int OnGhIsDnDPending(void);
384 int OnGhDrop(const RTCString &strFormat, VBOXDNDACTION dndActionDefault);
385#endif
386
387 void PostMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
388 int ProcessEvent(PVBOXDNDEVENT pEvent);
389
390 int Hide(void);
391 void Reset(void);
392
393protected:
394
395 int checkForSessionChange(void);
396 int makeFullscreen(void);
397 int mouseMove(int x, int y, DWORD dwMouseInputFlags);
398 int mouseRelease(void);
399 int setMode(Mode enmMode);
400
401public: /** @todo Make protected! */
402
403 /** Pointer to DnD context. */
404 PVBOXDNDCONTEXT m_pCtx;
405 /** The proxy window's main thread for processing
406 * window messages. */
407 RTTHREAD m_hThread;
408 /** Critical section to serialize access. */
409 RTCRITSECT m_CritSect;
410 /** Event semaphore to wait for new DnD events. */
411 RTSEMEVENT m_EvtSem;
412#ifdef RT_OS_WINDOWS
413 /** The window's handle. */
414 HWND m_hWnd;
415 /** List of allowed MIME types this
416 * client can handle. Make this a per-instance
417 * property so that we can selectively allow/forbid
418 * certain types later on runtime. */
419 RTCList<RTCString> m_lstFmtSup;
420 /** List of formats for the current
421 * drag'n drop operation. */
422 RTCList<RTCString> m_lstFmtActive;
423 /** List of all current drag'n drop actions allowed. */
424 VBOXDNDACTIONLIST m_lstActionsAllowed;
425 /** The startup information required
426 * for the actual DoDragDrop() call. */
427 VBOXDNDSTARTUPINFO m_startupInfo;
428 /** Is the left mouse button being pressed
429 * currently while being in this window? */
430 bool m_fMouseButtonDown;
431# ifdef VBOX_WITH_DRAG_AND_DROP_GH
432 /** Pointer to IDropTarget implementation for
433 * guest -> host support. */
434 VBoxDnDDropTarget *m_pDropTarget;
435# endif /* VBOX_WITH_DRAG_AND_DROP_GH */
436#else /* !RT_OS_WINDOWS */
437 /** @todo Implement me. */
438#endif /* !RT_OS_WINDOWS */
439
440 /** The window's own DnD context. */
441 VBGLR3GUESTDNDCMDCTX m_cmdCtx;
442 /** The current operation mode. */
443 Mode m_enmMode;
444 /** The current state. */
445 State m_enmState;
446 /** Format being requested. */
447 RTCString m_strFmtReq;
448};
449
450#endif /* !GA_INCLUDED_SRC_WINNT_VBoxTray_VBoxDnD_h */
451
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette