xref: /AOO41X/main/dtrans/source/win32/dnd/source.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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