1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/uno/Reference.h>
21 #include <com/sun/star/lang/XComponent.hpp>
22 #include <com/sun/star/lang/XInitialization.hpp>
23 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
24 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
26 #include <cppuhelper/servicefactory.hxx>
27 #include <rtl/string.h>
29 #include "atlwindow.hxx"
30 #include "targetlistener.hxx"
31 #include "sourcelistener.hxx"
35 using namespace com::sun::star::lang
;
36 using namespace com::sun::star::datatransfer::dnd
;
37 using namespace com::sun::star::datatransfer::dnd::DNDConstants
;
41 LRESULT APIENTRY
EditSubclassProc( HWND hwnd
, UINT uMsg
,WPARAM wParam
, LPARAM lParam
) ;
43 extern Reference
< XMultiServiceFactory
> MultiServiceFactory
;
44 DWORD WINAPI
MTAFunc(LPVOID pParams
);
46 char* szSTAWin
= "XDragSource::executeDrag is called from the same "
47 "OLE STA thread that created the window.";
48 char* szMTAWin
= "XDragSource::executeDrag is called from an MTA thread "
49 "that did not create the window.";
51 WNDPROC wpOrigEditProc
;
53 map
<HWND
, HWND
> mapEditToMainWnd
;
55 LRESULT
AWindow::OnClose(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
57 Reference
<XComponent
> xcompSource( m_xDragSource
, UNO_QUERY
);
64 // Remove the subclass from the edit control.
65 ::SetWindowLong(m_hwndEdit
, GWL_WNDPROC
,
66 (LONG
) wpOrigEditProc
);
71 LRESULT
AWindow::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
73 // Prepare the EDIT control
74 m_hwndEdit
= CreateWindowA(
75 "EDIT", // predefined class
76 NULL
, // no window title
77 WS_CHILD
| WS_VISIBLE
| WS_VSCROLL
|
78 ES_LEFT
| ES_MULTILINE
| ES_AUTOVSCROLL
,
79 0, 0, 0, 0, // set size in WM_SIZE message
80 m_hWnd
, // parent window
81 (HMENU
) NULL
, // edit control ID
82 (HINSTANCE
) GetWindowLong( GWL_HINSTANCE
),
85 // the map is used in the window procedure for the edit window to associate the
86 // it to the right main window ( AWindow)
87 mapEditToMainWnd
[m_hwndEdit
]= m_hWnd
;
88 // Superclass the edit window, because we want to process mouse messages
89 wpOrigEditProc
= (WNDPROC
) ::SetWindowLongA(m_hwndEdit
,
90 GWL_WNDPROC
, (LONG
) EditSubclassProc
);
92 // Add text to the window.
94 ::SendMessageA(m_hwndEdit
, WM_SETTEXT
, 0, (LPARAM
) szMTAWin
);
96 ::SendMessageA(m_hwndEdit
, WM_SETTEXT
, 0, (LPARAM
) szSTAWin
);
98 // create the DragSource
99 Reference
< XInterface
> xint
= MultiServiceFactory
->createInstance("com.sun.star.datatransfer.dnd.OleDragSource");
100 m_xDragSource
.set( xint
, UNO_QUERY
);
101 Reference
<XInitialization
> xInit( xint
, UNO_QUERY
);
104 ar
[1]<<= (sal_uInt32
)m_hWnd
;
105 xInit
->initialize( Sequence
<Any
>( ar
, 2) );
107 //create the DropTarget
108 Reference
< XInterface
> xintTarget
= MultiServiceFactory
->createInstance("com.sun.star.datatransfer.dnd.OleDropTarget");
109 m_xDropTarget
.set( xintTarget
, UNO_QUERY
);
110 Reference
<XInitialization
> xInitTarget( xintTarget
, UNO_QUERY
);
113 any
<<= (sal_uInt32
)m_hWnd
;
114 xInitTarget
->initialize( Sequence
<Any
>( &any
, 1) );
116 m_xDropTarget
->addDropTargetListener( static_cast<XDropTargetListener
*>
117 ( new DropTargetListener( m_hwndEdit
)) );
118 // // make this window a drop target
119 m_xDropTarget
->setActive(sal_True
);
124 // When the mouse is dragged for a second than a drag is initiated
125 LRESULT
AWindow::OnMouseAction(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
127 if( uMsg
== WM_LBUTTONDOWN
)
132 else if( uMsg
== WM_LBUTTONUP
)
140 LRESULT
AWindow::OnTimer(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
144 if(m_xDragSource
.is())
147 //Get the Text out of the Edit window
148 int length
= (int)::SendMessageA( m_hwndEdit
, WM_GETTEXTLENGTH
, 0, 0);
149 char * pBuffer
= new char[length
+ 1];
150 ZeroMemory( pBuffer
, length
+ 1);
151 ::SendMessageA( m_hwndEdit
, WM_GETTEXT
, length
, (LPARAM
) pBuffer
);
153 IDataObject
* pData
= NULL
;
154 HRESULT hr
= CreateDataCache( NULL
, CLSID_NULL
, __uuidof(IDataObject
),(void**) &pData
);
157 FORMATETC format
={ CF_TEXT
, NULL
, DVASPECT_CONTENT
, -1, };
159 HGLOBAL mem
= GlobalAlloc(GHND
, length
+ 1 );
160 void* pMem
= GlobalLock( mem
);
161 memcpy( pMem
, pBuffer
, length
+1);
165 medium
.tymed
= TYMED_HGLOBAL
;
167 medium
.pUnkForRelease
= NULL
;
169 pData
->SetData( &format
, &medium
, TRUE
); // releases HGLOBAL eventually
171 Reference
<XTransferable
> xTrans
= CDOTransferable::create(
172 MultiServiceFactory
, pData
);
174 // call XDragSource::executeDrag from an MTA
179 data
.source
= m_xDragSource
;
180 data
.transferable
= xTrans
;
182 data
.evtThreadReady
= CreateEvent( NULL
, FALSE
, FALSE
, NULL
);
184 CloseHandle(CreateThread(NULL
, 0, MTAFunc
, &data
, 0, &mtaThreadId
));
185 // We must wait until the thread copied the ThreadData structure
186 WaitForSingleObject( data
.evtThreadReady
, INFINITE
);
187 CloseHandle( data
.evtThreadReady
);
192 m_xDragSource
->startDrag( DragGestureEvent(),
193 ACTION_LINK
|ACTION_MOVE
|ACTION_COPY
,
197 Reference
<XDragSourceListener
>( static_cast<XDragSourceListener
*>(new DragSourceListener() ) ) );
207 LRESULT
AWindow::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
209 // Make the edit control the size of the window's
211 ::MoveWindow(m_hwndEdit
,
212 0, 0, // starting x- and y-coordinates
213 LOWORD(lParam
), // width of client area
214 HIWORD(lParam
), // height of client area
215 TRUE
); // repaint window
219 LRESULT
AWindow::OnFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
221 ::SetFocus(m_hwndEdit
);
225 // Subclass procedure for EDIT window
226 LRESULT APIENTRY
EditSubclassProc( HWND hwnd
, UINT uMsg
,WPARAM wParam
, LPARAM lParam
)
229 if( uMsg
>= WM_MOUSEFIRST
&& uMsg
<= WM_MOUSELAST
)
231 HWND hAWindow
= mapEditToMainWnd
[hwnd
];
232 ::SendMessage( hAWindow
, uMsg
, wParam
, lParam
);
235 return CallWindowProc( wpOrigEditProc
, hwnd
, uMsg
,
239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */