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 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 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 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 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 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 } 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 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