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