xref: /aoo41x/main/dtrans/test/win32/dnd/atlwindow.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dtrans.hxx"
30 
31 #include <com/sun/star/uno/Reference.h>
32 #include <com/sun/star/lang/XComponent.hpp>
33 #include <com/sun/star/lang/XInitialization.hpp>
34 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
35 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
36 
37 #include <cppuhelper/servicefactory.hxx>
38 #include <rtl/string.h>
39 
40 #include "atlwindow.hxx"
41 #include "targetlistener.hxx"
42 #include "sourcelistener.hxx"
43 //#include "transferable.hxx"
44 #include <map>
45 
46 #include <winbase.h>
47 using namespace com::sun::star::lang;
48 using namespace com::sun::star::datatransfer::dnd;
49 using namespace com::sun::star::datatransfer::dnd::DNDConstants;
50 using namespace cppu;
51 using namespace rtl;
52 using namespace std;
53 
54 LRESULT APIENTRY EditSubclassProc( HWND hwnd, UINT uMsg,WPARAM wParam, LPARAM lParam) ;
55 
56 
57 extern Reference< XMultiServiceFactory > MultiServiceFactory;
58 DWORD WINAPI MTAFunc(LPVOID pParams);
59 
60 char* szSTAWin= "XDragSource::executeDrag is called from the same "
61 				"OLE STA thread that created the window.";
62 char* szMTAWin= "XDragSource::executeDrag is called from a MTA thread "
63 				"that did not create the window.";
64 
65 WNDPROC wpOrigEditProc;
66 
67 map<HWND, HWND> mapEditToMainWnd;
68 
69 LRESULT AWindow::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
70 {
71 	Reference<XComponent> xcompSource( m_xDragSource, UNO_QUERY);
72 
73 	PostQuitMessage(0);
74 
75 
76 	m_xDropTarget=0;
77 	m_xDragSource=0;
78 
79 
80      // Remove the subclass from the edit control.
81     ::SetWindowLong(m_hwndEdit, GWL_WNDPROC,
82                 (LONG) wpOrigEditProc);
83 
84 	return 0;
85 }
86 
87 
88 LRESULT AWindow::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
89 {
90 	// Prepare the EDIT control
91     m_hwndEdit = CreateWindowA(
92         "EDIT",     // predefined class
93         NULL,       // no window title
94         WS_CHILD | WS_VISIBLE | WS_VSCROLL |
95             ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
96         0, 0, 0, 0, // set size in WM_SIZE message
97         m_hWnd,       // parent window
98         (HMENU) NULL, // edit control ID
99         (HINSTANCE) GetWindowLong( GWL_HINSTANCE),
100         NULL);
101 
102 	// the map is used in the window procedure for the edit window to associate the
103 	// it to the right main window ( AWindow)
104 	mapEditToMainWnd[m_hwndEdit]= m_hWnd;
105 	// Superclass the edit window, because we want to process mouse messages
106 	wpOrigEditProc = (WNDPROC) ::SetWindowLongA(m_hwndEdit,
107                 GWL_WNDPROC, (LONG) EditSubclassProc);
108 
109 
110 	// Add text to the window.
111 	if( m_isMTA)
112 		::SendMessageA(m_hwndEdit, WM_SETTEXT, 0, (LPARAM) szMTAWin);
113 	else
114 		::SendMessageA(m_hwndEdit, WM_SETTEXT, 0, (LPARAM) szSTAWin);
115 
116 
117 	// create the DragSource
118 	Reference< XInterface> xint= MultiServiceFactory->createInstance(OUString(L"com.sun.star.datatransfer.dnd.OleDragSource"));
119 	m_xDragSource= Reference<XDragSource>( xint, UNO_QUERY);
120 	Reference<XInitialization> xInit( xint, UNO_QUERY);
121 
122 	Any ar[2];
123 	ar[1]<<= (sal_uInt32)m_hWnd;
124 	xInit->initialize( Sequence<Any>( ar, 2) );
125 
126 	//create the DropTarget
127 	Reference< XInterface> xintTarget= MultiServiceFactory->createInstance(OUString(L"com.sun.star.datatransfer.dnd.OleDropTarget"));
128 	m_xDropTarget= Reference<XDropTarget>( xintTarget, UNO_QUERY);
129 	Reference<XInitialization> xInitTarget( xintTarget, UNO_QUERY);
130 
131 	Any any;
132 	any <<= (sal_uInt32)m_hWnd;
133 	xInitTarget->initialize( Sequence<Any>( &any, 1) );
134 
135 
136 	m_xDropTarget->addDropTargetListener( static_cast<XDropTargetListener*>
137 		( new DropTargetListener( m_hwndEdit)) );
138 //	// make this window tho a drop target
139 	m_xDropTarget->setActive(sal_True);
140 
141 	return 0;
142 }
143 
144 // When the mouse is dragged for a second than a drag is initiated
145 LRESULT AWindow::OnMouseAction(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
146 {
147 	if( uMsg== WM_LBUTTONDOWN)
148 	{
149 		SetTimer( 1, 1000);
150 	}
151 
152 	else if( uMsg == WM_LBUTTONUP)
153 	{
154 		KillTimer(  1);
155 	}
156 
157 	return 0;
158 }
159 
160 LRESULT AWindow::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
161 {
162 	HRESULT hr;
163 	USES_CONVERSION;
164 	KillTimer( 1);
165 	if(m_xDragSource.is())
166 	{
167 
168 		//Get the Text out of the Edit window
169 		int length= (int)::SendMessageA( m_hwndEdit, WM_GETTEXTLENGTH, 0, 0);
170 		char * pBuffer= new char[length + 1];
171 		ZeroMemory( pBuffer, length + 1);
172 		::SendMessageA( m_hwndEdit, WM_GETTEXT, length, (LPARAM) pBuffer);
173 
174 		IDataObject* pData= NULL;
175 		HRESULT hr= CreateDataCache( NULL, CLSID_NULL, __uuidof(IDataObject),(void**) &pData);
176 		if( pData)
177 		{
178 			FORMATETC format={ CF_TEXT, NULL, DVASPECT_CONTENT, -1, };
179 
180 			HGLOBAL mem= GlobalAlloc(GHND, length + 1 );
181 			void* pMem= GlobalLock( mem);
182 			memcpy( pMem, pBuffer, length+1);
183 			GlobalUnlock( mem);
184 
185 			STGMEDIUM medium;
186 			medium.tymed= TYMED_HGLOBAL;
187 			medium.hGlobal= mem;
188 			medium.pUnkForRelease= NULL;
189 
190 			pData->SetData( &format,  &medium, TRUE); // releases HGLOBAL eventually
191 
192 			Reference<XTransferable> xTrans= m_aDataConverter.createTransferableFromDataObj(
193 												MultiServiceFactory, pData);
194 
195 			// call XDragSource::executeDrag from an MTA
196 			if( m_isMTA )
197 			{
198 				DWORD mtaThreadId;
199 				ThreadData data;
200 				data.source= m_xDragSource;
201 				data.transferable= xTrans;
202 
203 				data.evtThreadReady= CreateEvent( NULL, FALSE, FALSE, NULL);
204 
205 				HANDLE hThread= CreateThread( NULL, 0, MTAFunc, &data, 0, &mtaThreadId);
206 				// We must wait until the thread copied the ThreadData structure
207 				WaitForSingleObject( data.evtThreadReady, INFINITE);
208 				CloseHandle( data.evtThreadReady);
209 
210 
211 			}
212 			else
213 			{
214 				m_xDragSource->startDrag( DragGestureEvent(),
215 					ACTION_LINK|ACTION_MOVE|ACTION_COPY,
216 					0,
217 					0,
218 					xTrans,
219 					Reference<XDragSourceListener>( static_cast<XDragSourceListener*>(new DragSourceListener() ) ) );
220 			}
221 		}
222 
223 		delete[] pBuffer;
224 	}
225 
226 	return 0;
227 }
228 
229 LRESULT AWindow::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
230 {
231     // Make the edit control the size of the window's
232     // client area.
233     ::MoveWindow(m_hwndEdit,
234         0, 0,           // starting x- and y-coordinates
235         LOWORD(lParam), // width of client area
236         HIWORD(lParam), // height of client area
237         TRUE);          // repaint window
238 
239 	return 0;
240 }
241 LRESULT AWindow::OnFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
242 {
243     ::SetFocus(m_hwndEdit);
244     return 0;
245 }
246 
247 
248 
249 // Subclass procedure for EDIT window
250 LRESULT APIENTRY EditSubclassProc( HWND hwnd, UINT uMsg,WPARAM wParam, LPARAM lParam)
251 {
252 
253 	if( uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)
254 	{
255 		HWND hAWindow= mapEditToMainWnd[hwnd];
256 		::SendMessage( hAWindow, uMsg, wParam, lParam);
257 
258 	}
259     return CallWindowProc( wpOrigEditProc, hwnd, uMsg,
260         wParam, lParam);
261 }
262 
263