xref: /AOO41X/main/dtrans/test/win32/dnd/atlwindow.cxx (revision 48123e16153c92857455f9e7a0d17cc19307983f)
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