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