/* $Id: VBoxDnDDropSource.cpp 51476 2014-05-30 14:58:02Z vboxsync $ */ /** @file * VBoxDnDSource.cpp - IDropSource implementation. */ /* * Copyright (C) 2013-2014 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ #include #include /* For bad_alloc. */ #ifdef LOG_GROUP # undef LOG_GROUP #endif #define LOG_GROUP LOG_GROUP_GUEST_DND #include #include "VBoxTray.h" #include "VBoxHelpers.h" #include "VBoxDnD.h" #include "VBox/HostServices/DragAndDropSvc.h" VBoxDnDDropSource::VBoxDnDDropSource(VBoxDnDWnd *pParent) : mRefCount(1), mpWndParent(pParent), mClientID(UINT32_MAX), mdwCurEffect(0), muCurAction(DND_IGNORE_ACTION) { int rc = VbglR3DnDConnect(&mClientID); LogFlowFunc(("rc=%Rrc\n", rc)); } VBoxDnDDropSource::~VBoxDnDDropSource(void) { int rc = VbglR3DnDDisconnect(mClientID); LogFlowFunc(("rc=%Rrc, mRefCount=%RI32\n", rc, mRefCount)); } /* * IUnknown methods. */ STDMETHODIMP_(ULONG) VBoxDnDDropSource::AddRef(void) { return InterlockedIncrement(&mRefCount); } STDMETHODIMP_(ULONG) VBoxDnDDropSource::Release(void) { LONG lCount = InterlockedDecrement(&mRefCount); if (lCount == 0) { delete this; return 0; } return lCount; } STDMETHODIMP VBoxDnDDropSource::QueryInterface(REFIID iid, void **ppvObject) { AssertPtrReturn(ppvObject, E_INVALIDARG); if ( iid == IID_IDropSource || iid == IID_IUnknown) { AddRef(); *ppvObject = this; return S_OK; } *ppvObject = 0; return E_NOINTERFACE; } /* * IDropSource methods. */ /** * The system informs us about whether we should continue the drag'n drop * operation or not, depending on the sent key states. * * @return HRESULT */ STDMETHODIMP VBoxDnDDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD dwKeyState) { #if 1 LogFlowFunc(("fEscapePressed=%RTbool, dwKeyState=0x%x, mdwCurEffect=%RI32, muCurAction=%RU32\n", fEscapePressed, dwKeyState, mdwCurEffect, muCurAction)); #endif /* ESC pressed? Bail out. */ if (fEscapePressed) { mdwCurEffect = 0; muCurAction = DND_IGNORE_ACTION; LogFlowFunc(("Canceled\n")); return DRAGDROP_S_CANCEL; } /* Left mouse button released? Start "drop" action. */ if ((dwKeyState & MK_LBUTTON) == 0) { LogFlowFunc(("Dropping ...\n")); return DRAGDROP_S_DROP; } /* No change, just continue. */ return S_OK; } /** * The drop target gives our source feedback about whether * it can handle our data or not. * * @return HRESULT */ STDMETHODIMP VBoxDnDDropSource::GiveFeedback(DWORD dwEffect) { uint32_t uAction = DND_IGNORE_ACTION; #if 1 LogFlowFunc(("dwEffect=0x%x\n", dwEffect)); #endif if (dwEffect) { if (dwEffect & DROPEFFECT_COPY) uAction |= DND_COPY_ACTION; if (dwEffect & DROPEFFECT_MOVE) uAction |= DND_MOVE_ACTION; if (dwEffect & DROPEFFECT_LINK) uAction |= DND_LINK_ACTION; } mdwCurEffect = dwEffect; muCurAction = uAction; return DRAGDROP_S_USEDEFAULTCURSORS; }