1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_dtrans.hxx" 30*cdf0e10cSrcweir #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> 31*cdf0e10cSrcweir #include <com/sun/star/datatransfer/XTransferable.hpp> 32*cdf0e10cSrcweir #include <com/sun/star/awt/MouseButton.hpp> 33*cdf0e10cSrcweir #include <com/sun/star/awt/MouseEvent.hpp> 34*cdf0e10cSrcweir #include <rtl/unload.h> 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include <process.h> 37*cdf0e10cSrcweir #include <memory> 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir #include "source.hxx" 40*cdf0e10cSrcweir #include "globals.hxx" 41*cdf0e10cSrcweir #include "sourcecontext.hxx" 42*cdf0e10cSrcweir #include "../../inc/DtObjFactory.hxx" 43*cdf0e10cSrcweir #include <rtl/ustring.h> 44*cdf0e10cSrcweir #include <process.h> 45*cdf0e10cSrcweir #include <winuser.h> 46*cdf0e10cSrcweir #include <stdio.h> 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir #ifdef __MINGW32__ 49*cdf0e10cSrcweir #define __uuidof(I) IID_##I 50*cdf0e10cSrcweir #endif 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir using namespace rtl; 53*cdf0e10cSrcweir using namespace cppu; 54*cdf0e10cSrcweir using namespace osl; 55*cdf0e10cSrcweir using namespace com::sun::star::datatransfer; 56*cdf0e10cSrcweir using namespace com::sun::star::datatransfer::dnd; 57*cdf0e10cSrcweir using namespace com::sun::star::datatransfer::dnd::DNDConstants; 58*cdf0e10cSrcweir using namespace com::sun::star::uno; 59*cdf0e10cSrcweir using namespace com::sun::star::awt::MouseButton; 60*cdf0e10cSrcweir using namespace com::sun::star::awt; 61*cdf0e10cSrcweir using namespace com::sun::star::lang; 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir extern rtl_StandardModuleCount g_moduleCount; 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir //--> TRA 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir extern Reference< XTransferable > g_XTransferable; 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir //<-- TRA 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir unsigned __stdcall DndOleSTAFunc(LPVOID pParams); 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir //---------------------------------------------------- 74*cdf0e10cSrcweir /** Ctor 75*cdf0e10cSrcweir */ 76*cdf0e10cSrcweir DragSource::DragSource( const Reference<XMultiServiceFactory>& sf): 77*cdf0e10cSrcweir m_serviceFactory( sf), 78*cdf0e10cSrcweir WeakComponentImplHelper3< XDragSource, XInitialization, XServiceInfo >(m_mutex), 79*cdf0e10cSrcweir // m_pcurrentContext_impl(0), 80*cdf0e10cSrcweir m_hAppWindow(0), 81*cdf0e10cSrcweir m_MouseButton(0), 82*cdf0e10cSrcweir m_RunningDndOperationCount(0) 83*cdf0e10cSrcweir { 84*cdf0e10cSrcweir g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 85*cdf0e10cSrcweir } 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir //---------------------------------------------------- 88*cdf0e10cSrcweir /** Dtor 89*cdf0e10cSrcweir */ 90*cdf0e10cSrcweir DragSource::~DragSource() 91*cdf0e10cSrcweir { 92*cdf0e10cSrcweir g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 93*cdf0e10cSrcweir } 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir //---------------------------------------------------- 96*cdf0e10cSrcweir /** First start a new drag and drop thread if 97*cdf0e10cSrcweir the last one has finished 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir ???? 100*cdf0e10cSrcweir Do we really need a separate thread for 101*cdf0e10cSrcweir every Dnd opeartion or only if the source 102*cdf0e10cSrcweir thread is an MTA thread 103*cdf0e10cSrcweir ???? 104*cdf0e10cSrcweir */ 105*cdf0e10cSrcweir void DragSource::StartDragImpl( 106*cdf0e10cSrcweir const DragGestureEvent& trigger, 107*cdf0e10cSrcweir sal_Int8 sourceActions, 108*cdf0e10cSrcweir sal_Int32 /*cursor*/, 109*cdf0e10cSrcweir sal_Int32 /*image*/, 110*cdf0e10cSrcweir const Reference<XTransferable >& trans, 111*cdf0e10cSrcweir const Reference<XDragSourceListener >& listener ) 112*cdf0e10cSrcweir { 113*cdf0e10cSrcweir // The actions supported by the drag source 114*cdf0e10cSrcweir m_sourceActions= sourceActions; 115*cdf0e10cSrcweir // We need to know which mouse button triggered the operation. 116*cdf0e10cSrcweir // If it was the left one, then the drop occurs when that button 117*cdf0e10cSrcweir // has been released and if it was the right one then the drop 118*cdf0e10cSrcweir // occurs when the right button has been released. If the event is not 119*cdf0e10cSrcweir // set then we assume that the left button is pressed. 120*cdf0e10cSrcweir MouseEvent evtMouse; 121*cdf0e10cSrcweir trigger.Event >>= evtMouse; 122*cdf0e10cSrcweir m_MouseButton= evtMouse.Buttons; 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir // The SourceContext class administers the XDragSourceListener s and 125*cdf0e10cSrcweir // fires events to them. An instance only exists in the scope of this 126*cdf0e10cSrcweir // functions. However, the drag and drop operation causes callbacks 127*cdf0e10cSrcweir // to the IDropSource interface implemented in this class (but only 128*cdf0e10cSrcweir // while this function executes). The source context is also used 129*cdf0e10cSrcweir // in DragSource::QueryContinueDrag. 130*cdf0e10cSrcweir m_currentContext= static_cast<XDragSourceContext*>( new SourceContext( 131*cdf0e10cSrcweir static_cast<DragSource*>(this), listener ) ); 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir // Convert the XTransferable data object into an IDataObject object; 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir //--> TRA 136*cdf0e10cSrcweir g_XTransferable = trans; 137*cdf0e10cSrcweir //<-- TRA 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir m_spDataObject= m_aDataConverter.createDataObjFromTransferable( 140*cdf0e10cSrcweir m_serviceFactory, trans); 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir // Obtain the id of the thread that created the window 143*cdf0e10cSrcweir DWORD processId; 144*cdf0e10cSrcweir m_threadIdWindow= GetWindowThreadProcessId( m_hAppWindow, &processId); 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir // hold the instance for the DnD thread, it's to late 147*cdf0e10cSrcweir // to acquire at the start of the thread procedure 148*cdf0e10cSrcweir // the thread procedure is responsible for the release 149*cdf0e10cSrcweir acquire(); 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir // The thread acccesses members of this instance but does not call acquire. 152*cdf0e10cSrcweir // Hopefully this instance is not destroyed before the thread has terminated. 153*cdf0e10cSrcweir unsigned threadId; 154*cdf0e10cSrcweir HANDLE hThread= reinterpret_cast<HANDLE>(_beginthreadex( 155*cdf0e10cSrcweir 0, 0, DndOleSTAFunc, reinterpret_cast<void*>(this), 0, &threadId)); 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir // detach from thread 158*cdf0e10cSrcweir CloseHandle(hThread); 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir // XInitialization 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir //---------------------------------------------------- 164*cdf0e10cSrcweir /** aArguments contains a machine id 165*cdf0e10cSrcweir */ 166*cdf0e10cSrcweir void SAL_CALL DragSource::initialize( const Sequence< Any >& aArguments ) 167*cdf0e10cSrcweir throw(Exception, RuntimeException) 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir if( aArguments.getLength() >=2) 170*cdf0e10cSrcweir m_hAppWindow= *(HWND*)aArguments[1].getValue(); 171*cdf0e10cSrcweir OSL_ASSERT( IsWindow( m_hAppWindow) ); 172*cdf0e10cSrcweir } 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir //---------------------------------------------------- 175*cdf0e10cSrcweir /** XDragSource 176*cdf0e10cSrcweir */ 177*cdf0e10cSrcweir sal_Bool SAL_CALL DragSource::isDragImageSupported( ) 178*cdf0e10cSrcweir throw(RuntimeException) 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir return 0; 181*cdf0e10cSrcweir } 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir //---------------------------------------------------- 184*cdf0e10cSrcweir /** 185*cdf0e10cSrcweir */ 186*cdf0e10cSrcweir sal_Int32 SAL_CALL DragSource::getDefaultCursor( sal_Int8 /*dragAction*/ ) 187*cdf0e10cSrcweir throw( IllegalArgumentException, RuntimeException) 188*cdf0e10cSrcweir { 189*cdf0e10cSrcweir return 0; 190*cdf0e10cSrcweir } 191*cdf0e10cSrcweir 192*cdf0e10cSrcweir //---------------------------------------------------- 193*cdf0e10cSrcweir /** Notifies the XDragSourceListener by 194*cdf0e10cSrcweir calling dragDropEnd 195*cdf0e10cSrcweir */ 196*cdf0e10cSrcweir void SAL_CALL DragSource::startDrag( 197*cdf0e10cSrcweir const DragGestureEvent& trigger, 198*cdf0e10cSrcweir sal_Int8 sourceActions, 199*cdf0e10cSrcweir sal_Int32 cursor, 200*cdf0e10cSrcweir sal_Int32 image, 201*cdf0e10cSrcweir const Reference<XTransferable >& trans, 202*cdf0e10cSrcweir const Reference<XDragSourceListener >& listener ) throw( RuntimeException) 203*cdf0e10cSrcweir { 204*cdf0e10cSrcweir // Allow only one running dnd operation at a time, 205*cdf0e10cSrcweir // see XDragSource documentation 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir long cnt = InterlockedIncrement(&m_RunningDndOperationCount); 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir if (1 == cnt) 210*cdf0e10cSrcweir { 211*cdf0e10cSrcweir StartDragImpl(trigger, sourceActions, cursor, image, trans, listener); 212*cdf0e10cSrcweir } 213*cdf0e10cSrcweir else 214*cdf0e10cSrcweir { 215*cdf0e10cSrcweir //OSL_ENSURE(false, "Overlapping Drag&Drop operation rejected!"); 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir cnt = InterlockedDecrement(&m_RunningDndOperationCount); 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir DragSourceDropEvent dsde; 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir dsde.DropAction = ACTION_NONE; 222*cdf0e10cSrcweir dsde.DropSuccess = false; 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir try 225*cdf0e10cSrcweir { 226*cdf0e10cSrcweir listener->dragDropEnd(dsde); 227*cdf0e10cSrcweir } 228*cdf0e10cSrcweir catch(RuntimeException&) 229*cdf0e10cSrcweir { 230*cdf0e10cSrcweir OSL_ENSURE(false, "Runtime exception during event dispatching"); 231*cdf0e10cSrcweir } 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir //---------------------------------------------------- 236*cdf0e10cSrcweir /**IDropTarget 237*cdf0e10cSrcweir */ 238*cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE DragSource::QueryInterface( REFIID riid, void **ppvObject) 239*cdf0e10cSrcweir { 240*cdf0e10cSrcweir if( !ppvObject) 241*cdf0e10cSrcweir return E_POINTER; 242*cdf0e10cSrcweir *ppvObject= NULL; 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir if( riid == __uuidof( IUnknown) ) 245*cdf0e10cSrcweir *ppvObject= static_cast<IUnknown*>( this); 246*cdf0e10cSrcweir else if ( riid == __uuidof( IDropSource) ) 247*cdf0e10cSrcweir *ppvObject= static_cast<IDropSource*>( this); 248*cdf0e10cSrcweir 249*cdf0e10cSrcweir if(*ppvObject) 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir AddRef(); 252*cdf0e10cSrcweir return S_OK; 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir else 255*cdf0e10cSrcweir return E_NOINTERFACE; 256*cdf0e10cSrcweir 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir //---------------------------------------------------- 260*cdf0e10cSrcweir /** 261*cdf0e10cSrcweir */ 262*cdf0e10cSrcweir ULONG STDMETHODCALLTYPE DragSource::AddRef( void) 263*cdf0e10cSrcweir { 264*cdf0e10cSrcweir acquire(); 265*cdf0e10cSrcweir return (ULONG) m_refCount; 266*cdf0e10cSrcweir } 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir //---------------------------------------------------- 269*cdf0e10cSrcweir /** 270*cdf0e10cSrcweir */ 271*cdf0e10cSrcweir ULONG STDMETHODCALLTYPE DragSource::Release( void) 272*cdf0e10cSrcweir { 273*cdf0e10cSrcweir ULONG ref= m_refCount; 274*cdf0e10cSrcweir release(); 275*cdf0e10cSrcweir return --ref; 276*cdf0e10cSrcweir } 277*cdf0e10cSrcweir 278*cdf0e10cSrcweir //---------------------------------------------------- 279*cdf0e10cSrcweir /** IDropSource 280*cdf0e10cSrcweir */ 281*cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE DragSource::QueryContinueDrag( 282*cdf0e10cSrcweir /* [in] */ BOOL fEscapePressed, 283*cdf0e10cSrcweir /* [in] */ DWORD grfKeyState) 284*cdf0e10cSrcweir { 285*cdf0e10cSrcweir #if defined DBG_CONSOLE_OUT 286*cdf0e10cSrcweir printf("\nDragSource::QueryContinueDrag"); 287*cdf0e10cSrcweir #endif 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir HRESULT retVal= S_OK; // default continue DnD 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir if (fEscapePressed) 292*cdf0e10cSrcweir { 293*cdf0e10cSrcweir retVal= DRAGDROP_S_CANCEL; 294*cdf0e10cSrcweir } 295*cdf0e10cSrcweir else 296*cdf0e10cSrcweir { 297*cdf0e10cSrcweir if( ( m_MouseButton == MouseButton::RIGHT && !(grfKeyState & MK_RBUTTON) ) || 298*cdf0e10cSrcweir ( m_MouseButton == MouseButton::MIDDLE && !(grfKeyState & MK_MBUTTON) ) || 299*cdf0e10cSrcweir ( m_MouseButton == MouseButton::LEFT && !(grfKeyState & MK_LBUTTON) ) || 300*cdf0e10cSrcweir ( m_MouseButton == 0 && !(grfKeyState & MK_LBUTTON) ) ) 301*cdf0e10cSrcweir { 302*cdf0e10cSrcweir retVal= DRAGDROP_S_DROP; 303*cdf0e10cSrcweir } 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir 306*cdf0e10cSrcweir // fire dropActionChanged event. 307*cdf0e10cSrcweir // this is actually done by the context, which also detects whether the action 308*cdf0e10cSrcweir // changed at all 309*cdf0e10cSrcweir sal_Int8 dropAction= fEscapePressed ? ACTION_NONE : 310*cdf0e10cSrcweir dndOleKeysToAction( grfKeyState, m_sourceActions); 311*cdf0e10cSrcweir 312*cdf0e10cSrcweir sal_Int8 userAction= fEscapePressed ? ACTION_NONE : 313*cdf0e10cSrcweir dndOleKeysToAction( grfKeyState, -1 ); 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir static_cast<SourceContext*>(m_currentContext.get())->fire_dropActionChanged( 316*cdf0e10cSrcweir dropAction, userAction); 317*cdf0e10cSrcweir 318*cdf0e10cSrcweir return retVal; 319*cdf0e10cSrcweir } 320*cdf0e10cSrcweir 321*cdf0e10cSrcweir //---------------------------------------------------- 322*cdf0e10cSrcweir /** 323*cdf0e10cSrcweir */ 324*cdf0e10cSrcweir HRESULT STDMETHODCALLTYPE DragSource::GiveFeedback( 325*cdf0e10cSrcweir /* [in] */ DWORD 326*cdf0e10cSrcweir #if defined DBG_CONSOLE_OUT 327*cdf0e10cSrcweir dwEffect 328*cdf0e10cSrcweir #endif 329*cdf0e10cSrcweir ) 330*cdf0e10cSrcweir { 331*cdf0e10cSrcweir #if defined DBG_CONSOLE_OUT 332*cdf0e10cSrcweir printf("\nDragSource::GiveFeedback %d", dwEffect); 333*cdf0e10cSrcweir #endif 334*cdf0e10cSrcweir 335*cdf0e10cSrcweir return DRAGDROP_S_USEDEFAULTCURSORS; 336*cdf0e10cSrcweir } 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir // XServiceInfo 339*cdf0e10cSrcweir OUString SAL_CALL DragSource::getImplementationName( ) throw (RuntimeException) 340*cdf0e10cSrcweir { 341*cdf0e10cSrcweir return OUString(RTL_CONSTASCII_USTRINGPARAM(DNDSOURCE_IMPL_NAME));; 342*cdf0e10cSrcweir } 343*cdf0e10cSrcweir // XServiceInfo 344*cdf0e10cSrcweir sal_Bool SAL_CALL DragSource::supportsService( const OUString& ServiceName ) throw (RuntimeException) 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir if( ServiceName.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(DNDSOURCE_SERVICE_NAME )))) 347*cdf0e10cSrcweir return sal_True; 348*cdf0e10cSrcweir return sal_False; 349*cdf0e10cSrcweir } 350*cdf0e10cSrcweir 351*cdf0e10cSrcweir Sequence< OUString > SAL_CALL DragSource::getSupportedServiceNames( ) throw (RuntimeException) 352*cdf0e10cSrcweir { 353*cdf0e10cSrcweir OUString names[1]= {OUString(RTL_CONSTASCII_USTRINGPARAM(DNDSOURCE_SERVICE_NAME))}; 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir return Sequence<OUString>(names, 1); 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir //---------------------------------------------------- 359*cdf0e10cSrcweir /**This function is called as extra thread from 360*cdf0e10cSrcweir DragSource::executeDrag. The function 361*cdf0e10cSrcweir carries out a drag and drop operation by calling 362*cdf0e10cSrcweir DoDragDrop. The thread also notifies all 363*cdf0e10cSrcweir XSourceListener. 364*cdf0e10cSrcweir */ 365*cdf0e10cSrcweir unsigned __stdcall DndOleSTAFunc(LPVOID pParams) 366*cdf0e10cSrcweir { 367*cdf0e10cSrcweir // The structure contains all arguments for DoDragDrop and other 368*cdf0e10cSrcweir DragSource *pSource= (DragSource*)pParams; 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir // Drag and drop only works in a thread in which OleInitialize is called. 371*cdf0e10cSrcweir HRESULT hr= OleInitialize( NULL); 372*cdf0e10cSrcweir 373*cdf0e10cSrcweir if(SUCCEEDED(hr)) 374*cdf0e10cSrcweir { 375*cdf0e10cSrcweir // We force the creation of a thread message queue. This is necessary 376*cdf0e10cSrcweir // for a later call to AttachThreadInput 377*cdf0e10cSrcweir MSG msgtemp; 378*cdf0e10cSrcweir PeekMessage( &msgtemp, NULL, WM_USER, WM_USER, PM_NOREMOVE); 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir DWORD threadId= GetCurrentThreadId(); 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir // This thread is attached to the thread that created the window. Hence 383*cdf0e10cSrcweir // this thread also receives all mouse and keyboard messages which are 384*cdf0e10cSrcweir // needed by DoDragDrop 385*cdf0e10cSrcweir AttachThreadInput( threadId , pSource->m_threadIdWindow, TRUE ); 386*cdf0e10cSrcweir 387*cdf0e10cSrcweir DWORD dwEffect= 0; 388*cdf0e10cSrcweir hr= DoDragDrop( 389*cdf0e10cSrcweir pSource->m_spDataObject.get(), 390*cdf0e10cSrcweir static_cast<IDropSource*>(pSource), 391*cdf0e10cSrcweir dndActionsToDropEffects( pSource->m_sourceActions), 392*cdf0e10cSrcweir &dwEffect); 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir // #105428 detach my message queue from the other threads 395*cdf0e10cSrcweir // message queue before calling fire_dragDropEnd else 396*cdf0e10cSrcweir // the office may appear to hang sometimes 397*cdf0e10cSrcweir AttachThreadInput( threadId, pSource->m_threadIdWindow, FALSE); 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir //--> TRA 400*cdf0e10cSrcweir // clear the global transferable again 401*cdf0e10cSrcweir g_XTransferable = Reference< XTransferable >( ); 402*cdf0e10cSrcweir //<-- TRA 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir OSL_ENSURE( hr != E_INVALIDARG, "IDataObject impl does not contain valid data"); 405*cdf0e10cSrcweir 406*cdf0e10cSrcweir //Fire event 407*cdf0e10cSrcweir sal_Int8 action= hr == DRAGDROP_S_DROP ? dndOleDropEffectsToActions( dwEffect) : ACTION_NONE; 408*cdf0e10cSrcweir 409*cdf0e10cSrcweir static_cast<SourceContext*>(pSource->m_currentContext.get())->fire_dragDropEnd( 410*cdf0e10cSrcweir hr == DRAGDROP_S_DROP ? sal_True : sal_False, action); 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir // Destroy SourceContextslkfgj 413*cdf0e10cSrcweir pSource->m_currentContext= 0; 414*cdf0e10cSrcweir // Destroy the XTransferable wrapper 415*cdf0e10cSrcweir pSource->m_spDataObject=0; 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir OleUninitialize(); 418*cdf0e10cSrcweir } 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir InterlockedDecrement(&pSource->m_RunningDndOperationCount); 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir // the DragSource was manually acquired by 423*cdf0e10cSrcweir // thread starting method DelayedStartDrag 424*cdf0e10cSrcweir pSource->release(); 425*cdf0e10cSrcweir 426*cdf0e10cSrcweir return 0; 427*cdf0e10cSrcweir } 428*cdf0e10cSrcweir 429*cdf0e10cSrcweir 430*cdf0e10cSrcweir 431*cdf0e10cSrcweir 432