summaryrefslogtreecommitdiffstats
path: root/vcl/workben/win
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--vcl/workben/win/dnd/atlwindow.cxx238
-rw-r--r--vcl/workben/win/dnd/atlwindow.hxx87
-rw-r--r--vcl/workben/win/dnd/dndTest.cxx177
-rw-r--r--vcl/workben/win/dnd/makefile.mk70
-rw-r--r--vcl/workben/win/dnd/sourcelistener.cxx59
-rw-r--r--vcl/workben/win/dnd/sourcelistener.hxx56
-rw-r--r--vcl/workben/win/dnd/targetlistener.cxx78
-rw-r--r--vcl/workben/win/dnd/targetlistener.hxx64
-rw-r--r--vcl/workben/win/dnd/transferable.cxx105
-rw-r--r--vcl/workben/win/dnd/transferable.hxx88
-rw-r--r--vcl/workben/win/dtrans/XTDo.cxx358
-rw-r--r--vcl/workben/win/dtrans/XTDo.hxx111
-rw-r--r--vcl/workben/win/dtrans/makefile.mk81
-rw-r--r--vcl/workben/win/dtrans/test_wincb.cxx287
-rw-r--r--vcl/workben/win/dtrans/testmarshal.cxx212
15 files changed, 2071 insertions, 0 deletions
diff --git a/vcl/workben/win/dnd/atlwindow.cxx b/vcl/workben/win/dnd/atlwindow.cxx
new file mode 100644
index 000000000..61781e18f
--- /dev/null
+++ b/vcl/workben/win/dnd/atlwindow.cxx
@@ -0,0 +1,238 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
+
+#include <cppuhelper/servicefactory.hxx>
+#include <rtl/string.h>
+
+#include "atlwindow.hxx"
+#include "targetlistener.hxx"
+#include "sourcelistener.hxx"
+#include <map>
+
+#include <winbase.h>
+using namespace com::sun::star::lang;
+using namespace com::sun::star::datatransfer::dnd;
+using namespace com::sun::star::datatransfer::dnd::DNDConstants;
+using namespace cppu;
+
+LRESULT APIENTRY EditSubclassProc( HWND hwnd, UINT uMsg,WPARAM wParam, LPARAM lParam) ;
+
+extern Reference< XMultiServiceFactory > MultiServiceFactory;
+DWORD WINAPI MTAFunc(LPVOID pParams);
+
+char* szSTAWin= "XDragSource::executeDrag is called from the same "
+ "OLE STA thread that created the window.";
+char* szMTAWin= "XDragSource::executeDrag is called from an MTA thread "
+ "that did not create the window.";
+
+WNDPROC wpOrigEditProc;
+
+map<HWND, HWND> mapEditToMainWnd;
+
+LRESULT AWindow::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ Reference<XComponent> xcompSource( m_xDragSource, UNO_QUERY);
+
+ PostQuitMessage(0);
+
+ m_xDropTarget=0;
+ m_xDragSource=0;
+
+ // Remove the subclass from the edit control.
+ ::SetWindowLong(m_hwndEdit, GWL_WNDPROC,
+ (LONG) wpOrigEditProc);
+
+ return 0;
+}
+
+LRESULT AWindow::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ // Prepare the EDIT control
+ m_hwndEdit = CreateWindowA(
+ "EDIT", // predefined class
+ NULL, // no window title
+ WS_CHILD | WS_VISIBLE | WS_VSCROLL |
+ ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
+ 0, 0, 0, 0, // set size in WM_SIZE message
+ m_hWnd, // parent window
+ (HMENU) NULL, // edit control ID
+ (HINSTANCE) GetWindowLong( GWL_HINSTANCE),
+ NULL);
+
+ // the map is used in the window procedure for the edit window to associate the
+ // it to the right main window ( AWindow)
+ mapEditToMainWnd[m_hwndEdit]= m_hWnd;
+ // Superclass the edit window, because we want to process mouse messages
+ wpOrigEditProc = (WNDPROC) ::SetWindowLongA(m_hwndEdit,
+ GWL_WNDPROC, (LONG) EditSubclassProc);
+
+ // Add text to the window.
+ if( m_isMTA)
+ ::SendMessageA(m_hwndEdit, WM_SETTEXT, 0, (LPARAM) szMTAWin);
+ else
+ ::SendMessageA(m_hwndEdit, WM_SETTEXT, 0, (LPARAM) szSTAWin);
+
+ // create the DragSource
+ Reference< XInterface> xint= MultiServiceFactory->createInstance("com.sun.star.datatransfer.dnd.OleDragSource");
+ m_xDragSource.set( xint, UNO_QUERY );
+ Reference<XInitialization> xInit( xint, UNO_QUERY);
+
+ Any ar[2];
+ ar[1]<<= (sal_uInt32)m_hWnd;
+ xInit->initialize( Sequence<Any>( ar, 2) );
+
+ //create the DropTarget
+ Reference< XInterface> xintTarget= MultiServiceFactory->createInstance("com.sun.star.datatransfer.dnd.OleDropTarget");
+ m_xDropTarget.set( xintTarget, UNO_QUERY );
+ Reference<XInitialization> xInitTarget( xintTarget, UNO_QUERY);
+
+ Any any;
+ any <<= (sal_uInt32)m_hWnd;
+ xInitTarget->initialize( Sequence<Any>( &any, 1) );
+
+ m_xDropTarget->addDropTargetListener( static_cast<XDropTargetListener*>
+ ( new DropTargetListener( m_hwndEdit)) );
+// // make this window a drop target
+ m_xDropTarget->setActive(sal_True);
+
+ return 0;
+}
+
+// When the mouse is dragged for a second than a drag is initiated
+LRESULT AWindow::OnMouseAction(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ if( uMsg== WM_LBUTTONDOWN)
+ {
+ SetTimer( 1, 1000);
+ }
+
+ else if( uMsg == WM_LBUTTONUP)
+ {
+ KillTimer( 1);
+ }
+
+ return 0;
+}
+
+LRESULT AWindow::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ USES_CONVERSION;
+ KillTimer( 1);
+ if(m_xDragSource.is())
+ {
+
+ //Get the Text out of the Edit window
+ int length= (int)::SendMessageA( m_hwndEdit, WM_GETTEXTLENGTH, 0, 0);
+ char * pBuffer= new char[length + 1];
+ ZeroMemory( pBuffer, length + 1);
+ ::SendMessageA( m_hwndEdit, WM_GETTEXT, length, (LPARAM) pBuffer);
+
+ IDataObject* pData= NULL;
+ HRESULT hr= CreateDataCache( NULL, CLSID_NULL, __uuidof(IDataObject),(void**) &pData);
+ if( pData)
+ {
+ FORMATETC format={ CF_TEXT, NULL, DVASPECT_CONTENT, -1, };
+
+ HGLOBAL mem= GlobalAlloc(GHND, length + 1 );
+ void* pMem= GlobalLock( mem);
+ memcpy( pMem, pBuffer, length+1);
+ GlobalUnlock( mem);
+
+ STGMEDIUM medium;
+ medium.tymed= TYMED_HGLOBAL;
+ medium.hGlobal= mem;
+ medium.pUnkForRelease= NULL;
+
+ pData->SetData( &format, &medium, TRUE); // releases HGLOBAL eventually
+
+ Reference<XTransferable> xTrans= CDOTransferable::create(
+ MultiServiceFactory, pData);
+
+ // call XDragSource::executeDrag from an MTA
+ if( m_isMTA )
+ {
+ DWORD mtaThreadId;
+ ThreadData data;
+ data.source= m_xDragSource;
+ data.transferable= xTrans;
+
+ data.evtThreadReady= CreateEvent( NULL, FALSE, FALSE, NULL);
+
+ CloseHandle(CreateThread(NULL, 0, MTAFunc, &data, 0, &mtaThreadId));
+ // We must wait until the thread copied the ThreadData structure
+ WaitForSingleObject( data.evtThreadReady, INFINITE);
+ CloseHandle( data.evtThreadReady);
+
+ }
+ else
+ {
+ m_xDragSource->startDrag( DragGestureEvent(),
+ ACTION_LINK|ACTION_MOVE|ACTION_COPY,
+ 0,
+ 0,
+ xTrans,
+ Reference<XDragSourceListener>( static_cast<XDragSourceListener*>(new DragSourceListener() ) ) );
+ }
+ }
+
+ delete[] pBuffer;
+ }
+
+ return 0;
+}
+
+LRESULT AWindow::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ // Make the edit control the size of the window's
+ // client area.
+ ::MoveWindow(m_hwndEdit,
+ 0, 0, // starting x- and y-coordinates
+ LOWORD(lParam), // width of client area
+ HIWORD(lParam), // height of client area
+ TRUE); // repaint window
+
+ return 0;
+}
+LRESULT AWindow::OnFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+ ::SetFocus(m_hwndEdit);
+ return 0;
+}
+
+// Subclass procedure for EDIT window
+LRESULT APIENTRY EditSubclassProc( HWND hwnd, UINT uMsg,WPARAM wParam, LPARAM lParam)
+{
+
+ if( uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)
+ {
+ HWND hAWindow= mapEditToMainWnd[hwnd];
+ ::SendMessage( hAWindow, uMsg, wParam, lParam);
+
+ }
+ return CallWindowProc( wpOrigEditProc, hwnd, uMsg,
+ wParam, lParam);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/win/dnd/atlwindow.hxx b/vcl/workben/win/dnd/atlwindow.hxx
new file mode 100644
index 000000000..047acf676
--- /dev/null
+++ b/vcl/workben/win/dnd/atlwindow.hxx
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+#include <atlbase.h>
+extern CComModule _Module;
+#include <atlcom.h>
+#include <atlctl.h>
+#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+#include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include "../../source/inc/DtObjFactory.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::datatransfer::dnd;
+using namespace com::sun::star::datatransfer;
+
+struct ThreadData
+{
+ Reference<XDragSource> source;
+ Reference<XTransferable> transferable;
+ HANDLE evtThreadReady;
+};
+
+class AWindow: public CWindowImpl<AWindow, CWindow,
+ CWinTraits<WS_CAPTION |WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0> >
+{
+ TCHAR m_strName[80];
+ Reference<XDropTarget> m_xDropTarget;
+ Reference<XDragSource> m_xDragSource;
+ BOOL m_isMTA;
+
+ HWND m_hwndEdit;
+
+public:
+ explicit AWindow(LPCTSTR strName)
+ {
+ RECT rcPos= {0,0,200,200};
+ Create(0, rcPos, strName);
+ }
+ AWindow(LPCTSTR strName, RECT pos, BOOL mta=FALSE): m_isMTA( mta)
+ {
+ Create(0, pos, strName);
+ }
+
+ ~AWindow()
+ {
+ if(m_hWnd)
+ DestroyWindow();
+ }
+
+ BEGIN_MSG_MAP(AWindow)
+ MESSAGE_HANDLER( WM_CLOSE, OnClose)
+ MESSAGE_HANDLER( WM_CREATE, OnCreate)
+ MESSAGE_RANGE_HANDLER( WM_MOUSEFIRST, WM_MOUSELAST, OnMouseAction)
+ MESSAGE_HANDLER( WM_TIMER, OnTimer)
+ MESSAGE_HANDLER( WM_SIZE, OnSize)
+ MESSAGE_HANDLER( WM_SETFOCUS, OnFocus)
+
+ END_MSG_MAP()
+
+ LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnMouseAction(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/win/dnd/dndTest.cxx b/vcl/workben/win/dnd/dndTest.cxx
new file mode 100644
index 000000000..2f2a7bccf
--- /dev/null
+++ b/vcl/workben/win/dnd/dndTest.cxx
@@ -0,0 +1,177 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#include <comdef.h>
+#include <atlbase.h>
+CComModule _Module;
+#include <atlcom.h>
+#include <atlimpl.cpp>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <rtl/process.h>
+#include <cppuhelper/servicefactory.hxx>
+#include "sourcelistener.hxx"
+
+#include "atlwindow.hxx"
+BEGIN_OBJECT_MAP(ObjectMap)
+END_OBJECT_MAP()
+
+using namespace com::sun::star::lang;
+using namespace com::sun::star::datatransfer;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::datatransfer::dnd;
+using namespace com::sun::star::datatransfer::dnd::DNDConstants;
+
+HRESULT doTest();
+DWORD WINAPI MTAFunc( void* threadData);
+
+Reference< XMultiServiceFactory > MultiServiceFactory;
+
+int main( int argc, char *argv[ ], char *envp[ ] )
+{
+ HRESULT hr;
+ if( FAILED( hr=CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
+ {
+ printf("CoInitializeEx failed \n");
+ return -1;
+ }
+
+ _Module.Init( ObjectMap, GetModuleHandleA( NULL));
+
+ if( FAILED(hr=doTest()))
+ {
+ _com_error err( hr);
+ }
+
+ _Module.Term();
+ CoUninitialize();
+ return 0;
+}
+
+HRESULT doTest()
+{
+
+ MultiServiceFactory= createRegistryServiceFactory( OUString(L"types.rdb"), OUString( L"services.rdb") , sal_True);
+
+ // create the MTA thread that is used to realize MTA calls to the services
+ // We create the thread and wait until the thread has created its message queue
+ HANDLE evt= CreateEventA(NULL, FALSE, FALSE, NULL);
+ DWORD threadIdMTA=0;
+ HANDLE hMTAThread= CreateThread( NULL, 0, MTAFunc, &evt, 0, &threadIdMTA);
+ WaitForSingleObject( evt, INFINITE);
+ CloseHandle(evt);
+
+ HRESULT hr= S_OK;
+ RECT pos1={0,0,300,200};
+ AWindow win("DnD starting in Ole STA", threadIdMTA, pos1);
+
+ RECT pos2={ 0, 205, 300, 405};
+ AWindow win2("DnD starting in MTA", threadIdMTA, pos2, true);
+
+ // win3 and win4 call initialize from an MTA but they are created in an STA
+ RECT pos3={300,0,600,200};
+ AWindow win3("DnD starting in OLE STA", threadIdMTA, pos3, false, true);
+
+ RECT pos4={ 300, 205, 600, 405};
+ AWindow win24("DnD starting in Ole MTA", threadIdMTA, pos4, true, true);
+
+ MSG msg;
+ while( GetMessageA(&msg, (HWND)NULL, 0, 0) )
+ {
+ TranslateMessage( &msg);
+ DispatchMessageA( &msg);
+ }
+
+ // Shut down the MTA thread
+ PostThreadMessageA( threadIdMTA, WM_QUIT, 0, 0);
+ WaitForSingleObject(hMTAThread, INFINITE);
+ CloseHandle(hMTAThread);
+
+ return S_OK;
+}
+
+extern Reference<XMultiServiceFactory> MultiServiceFactory;
+DWORD WINAPI MTAFunc( void* threadData)
+{
+ HRESULT hr= CoInitializeEx( NULL, COINIT_MULTITHREADED);
+ ATLASSERT( FAILED(hr) );
+ MSG msg;
+ // force the creation of a message queue
+ PeekMessageA(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
+ SetEvent( *(HANDLE*)threadData );
+
+ RECT pos={0, 406, 300, 605};
+ AWindow win("DnD, full MTA", GetCurrentThreadId(), pos, false, true);
+
+ while( GetMessageA(&msg, (HWND)NULL, 0, 0) )
+ {
+ switch( msg.message)
+ {
+ case WM_SOURCE_INIT:
+ {
+ InitializationData* pData= (InitializationData*)msg.wParam;
+ Any any;
+ any <<= (sal_uInt32) pData->hWnd;
+ pData->xInit->initialize( Sequence<Any>( &any, 1));
+
+ CoTaskMemFree( pData);
+ break;
+ }
+ case WM_SOURCE_STARTDRAG:
+ {
+ // wParam contains necessary data
+ StartDragData* pData= (StartDragData*)msg.wParam;
+ Sequence<DataFlavor> seq= pData->transferable->getTransferDataFlavors();
+ // have a look what flavours are supported
+ for( int i=0; i<seq.(); i++)
+ {
+ DataFlavor d= seq[i];
+ }
+ pData->source->startDrag( DragGestureEvent(),
+ ACTION_LINK|ACTION_MOVE|ACTION_COPY,
+ 0,
+ 0,
+ pData->transferable,
+ Reference<XDragSourceListener>( static_cast<XDragSourceListener*>
+ ( new DragSourceListener())));
+ CoTaskMemFree( pData);
+ break;
+ }
+
+ } // end switch
+
+ TranslateMessage( &msg);
+ DispatchMessageA( &msg);
+ }
+
+ CoUninitialize();
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/win/dnd/makefile.mk b/vcl/workben/win/dnd/makefile.mk
new file mode 100644
index 000000000..e0d438418
--- /dev/null
+++ b/vcl/workben/win/dnd/makefile.mk
@@ -0,0 +1,70 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+PRJ=..$/..$/..$/
+
+PRJNAME=dtrans
+TARGET=dndTest
+TARGETTYPE=CUI
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ---
+
+.INCLUDE : settings.mk
+
+# --- Files ---
+
+CFLAGS+= -D_WIN32_DCOM
+
+INCPRE+= -I$(ATL_INCLUDE)
+
+OBJFILES= $(OBJ)$/dndTest.obj \
+ $(OBJ)$/atlwindow.obj \
+ $(OBJ)$/targetlistener.obj \
+ $(OBJ)$/sourcelistener.obj \
+ $(OBJ)$/dataobject.obj
+
+APP1NOSAL=TRUE
+
+APP1TARGET= $(TARGET)
+APP1OBJS=$(OBJFILES)
+
+APP1STDLIBS= \
+ $(SALLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(UWINAPILIB) \
+ $(USER32LIB) \
+ $(OLE32LIB) \
+ comsupp.lib \
+ $(OLEAUT32LIB) \
+ $(GDI32LIB) \
+ $(UUIDLIB)
+
+APP1LIBS= \
+ $(SLB)$/dtobjfact.lib \
+ $(SLB)$/dtutils.lib
+
+APP1DEF= $(MISC)\$(APP1TARGET).def
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
diff --git a/vcl/workben/win/dnd/sourcelistener.cxx b/vcl/workben/win/dnd/sourcelistener.cxx
new file mode 100644
index 000000000..aa3366e79
--- /dev/null
+++ b/vcl/workben/win/dnd/sourcelistener.cxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "sourcelistener.hxx"
+
+DragSourceListener::DragSourceListener()
+{
+}
+DragSourceListener::~DragSourceListener()
+{
+}
+
+void SAL_CALL DragSourceListener::disposing( const EventObject& Source )
+ throw(RuntimeException)
+{
+}
+
+void SAL_CALL DragSourceListener::dragDropEnd( const DragSourceDropEvent& dsde )
+ throw(RuntimeException)
+{
+}
+
+void SAL_CALL DragSourceListener::dragEnter( const DragSourceDragEvent& dsde )
+ throw(RuntimeException)
+{
+}
+
+void SAL_CALL DragSourceListener::dragExit( const DragSourceEvent& dse )
+ throw(RuntimeException)
+{
+}
+
+void SAL_CALL DragSourceListener::dragOver( const DragSourceDragEvent& dsde )
+ throw(RuntimeException)
+{
+}
+
+void SAL_CALL DragSourceListener::dropActionChanged( const DragSourceDragEvent& dsde )
+ throw(RuntimeException)
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/win/dnd/sourcelistener.hxx b/vcl/workben/win/dnd/sourcelistener.hxx
new file mode 100644
index 000000000..0fc051399
--- /dev/null
+++ b/vcl/workben/win/dnd/sourcelistener.hxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/datatransfer/dnd/XDragSourceListener.hpp>
+#include <com/sun/star/datatransfer/dnd/DragSourceDropEvent.hpp>
+#include <com/sun/star/datatransfer/dnd/DragSourceDragEvent.hpp>
+
+using namespace ::com::sun::star::datatransfer;
+using namespace ::com::sun::star::datatransfer::dnd;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+class DragSourceListener: public WeakImplHelper<XDragSourceListener>
+{
+ // this is a window where dropped data are shown as text (only text)
+public:
+ DragSourceListener( );
+ ~DragSourceListener();
+
+ virtual void SAL_CALL disposing( const EventObject& Source )
+ throw(RuntimeException);
+
+ virtual void SAL_CALL dragDropEnd( const DragSourceDropEvent& dsde )
+ throw(RuntimeException);
+ virtual void SAL_CALL dragEnter( const DragSourceDragEvent& dsde )
+ throw(RuntimeException);
+ virtual void SAL_CALL dragExit( const DragSourceEvent& dse )
+ throw(RuntimeException);
+ virtual void SAL_CALL dragOver( const DragSourceDragEvent& dsde )
+ throw(RuntimeException);
+ virtual void SAL_CALL dropActionChanged( const DragSourceDragEvent& dsde )
+ throw(RuntimeException);
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/win/dnd/targetlistener.cxx b/vcl/workben/win/dnd/targetlistener.cxx
new file mode 100644
index 000000000..0a93d3945
--- /dev/null
+++ b/vcl/workben/win/dnd/targetlistener.cxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "targetlistener.hxx"
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
+#include <com/sun/star/datatransfer/DataFlavor.hpp>
+
+using namespace com::sun::star::datatransfer::dnd::DNDConstants;
+using namespace com::sun::star::datatransfer;
+
+DropTargetListener::DropTargetListener(HWND hEdit):m_hEdit( hEdit)
+{
+}
+DropTargetListener::~DropTargetListener()
+{
+}
+
+void SAL_CALL DropTargetListener::disposing( const EventObject& Source )
+ throw(RuntimeException)
+{
+
+}
+
+void SAL_CALL DropTargetListener::drop( const DropTargetDropEvent& e )
+ throw(RuntimeException)
+{
+ e.Context->rejectDrop();
+
+ DataFlavor flavor( OUString(OUString("text/plain;charset=windows-1252")),
+ OUString(L"Text plain"), cppu::UnoType<Sequence<sal_Int8>>::get() );
+
+ Any anyData= e.Transferable->getTransferData( flavor);
+ Sequence<sal_Int8> seq= *( Sequence<sal_Int8>*)anyData.getValue();
+ SendMessage( m_hEdit, WM_SETTEXT, 0, (LPARAM) seq.getConstArray() );
+}
+
+void SAL_CALL DropTargetListener::dragEnter( const DropTargetDragEnterEvent& dtde )
+ throw(RuntimeException)
+{
+ //If one drags something that is not moveable
+ if( !(dtde.SourceActions & dtde.DropAction) )
+ dtde.Context->acceptDrag( ACTION_COPY);
+}
+
+void SAL_CALL DropTargetListener::dragExit( const DropTargetEvent& dte )
+ throw(RuntimeException)
+{
+}
+
+void SAL_CALL DropTargetListener::dragOver( const DropTargetDragEvent& dtde )
+ throw(RuntimeException)
+{
+ if( !(dtde.SourceActions & dtde.DropAction) )
+ dtde.Context->acceptDrag( ACTION_COPY);
+}
+
+void SAL_CALL DropTargetListener::dropActionChanged( const DropTargetDragEvent& dtde )
+ throw(RuntimeException)
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/win/dnd/targetlistener.hxx b/vcl/workben/win/dnd/targetlistener.hxx
new file mode 100644
index 000000000..f42fac33a
--- /dev/null
+++ b/vcl/workben/win/dnd/targetlistener.hxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/datatransfer/dnd/XDropTargetListener.hpp>
+#include <com/sun/star/datatransfer/dnd/DropTargetDropEvent.hpp>
+#include <com/sun/star/datatransfer/dnd/DropTargetDragEvent.hpp>
+#include <com/sun/star/datatransfer/dnd/DropTargetDragEnterEvent.hpp>
+
+using namespace ::com::sun::star::datatransfer;
+using namespace ::com::sun::star::datatransfer::dnd;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+class DropTargetListener: public WeakImplHelper<XDropTargetListener>
+{
+ // this is a window where dropped data are shown as text (only text)
+ HWND m_hEdit;
+public:
+ explicit DropTargetListener(HWND hEdit);
+ ~DropTargetListener();
+
+ virtual void SAL_CALL disposing( const EventObject& Source )
+ throw(RuntimeException);
+
+ virtual void SAL_CALL drop( const DropTargetDropEvent& dtde )
+ throw(RuntimeException);
+ virtual void SAL_CALL dragEnter( const DropTargetDragEnterEvent& dtde )
+ throw(RuntimeException);
+ virtual void SAL_CALL dragExit( const DropTargetEvent& dte )
+ throw(RuntimeException);
+ virtual void SAL_CALL dragOver( const DropTargetDragEvent& dtde )
+ throw(RuntimeException);
+ virtual void SAL_CALL dropActionChanged( const DropTargetDragEvent& dtde )
+ throw(RuntimeException);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/win/dnd/transferable.cxx b/vcl/workben/win/dnd/transferable.cxx
new file mode 100644
index 000000000..924c03176
--- /dev/null
+++ b/vcl/workben/win/dnd/transferable.cxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "transferable.hxx"
+
+// ctor
+
+CTransferable::CTransferable( wchar_t* dataString ) :
+ m_seqDFlv( 1 ),
+ m_Data( dataString )
+{
+ DataFlavor df;
+
+ /*
+ df.MimeType = L"text/plain; charset=unicode";
+ df.DataType = cppu::UnoType<OUString>::get();
+
+ m_seqDFlv[0] = df;
+ */
+
+ //df.MimeType = L"text/plain; charset=windows1252";
+ df.MimeType = L"text/plain";
+ df.DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
+
+ m_seqDFlv[0] = df;
+}
+
+// getTransferData
+
+Any SAL_CALL CTransferable::getTransferData( const DataFlavor& aFlavor )
+ throw(UnsupportedFlavorException, IOException, RuntimeException)
+{
+ Any anyData;
+
+ /*if ( aFlavor == m_seqDFlv[0] )
+ {
+ anyData = makeAny( m_Data );
+ }
+ else*/ if ( aFlavor == m_seqDFlv[0] )
+ {
+ OString aStr( m_Data.getStr( ), m_Data.getLength( ), 1252 );
+ Sequence< sal_Int8 > sOfChars( aStr.getLength( ) );
+ sal_Int32 lenStr = aStr.getLength( );
+
+ for ( sal_Int32 i = 0; i < lenStr; ++i )
+ sOfChars[i] = aStr[i];
+
+ anyData = makeAny( sOfChars );
+ }
+
+ return anyData;
+}
+
+// getTransferDataFlavors
+
+Sequence< DataFlavor > SAL_CALL CTransferable::getTransferDataFlavors( )
+ throw(RuntimeException)
+{
+ return m_seqDFlv;
+}
+
+// isDataFlavorSupported
+
+sal_Bool SAL_CALL CTransferable::isDataFlavorSupported( const DataFlavor& aFlavor )
+ throw(RuntimeException)
+{
+ sal_Int32 nLength = m_seqDFlv.getLength( );
+ sal_Bool bRet = sal_False;
+
+ for ( sal_Int32 i = 0; i < nLength; ++i )
+ {
+ if ( m_seqDFlv[i] == aFlavor )
+ {
+ bRet = sal_True;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+// lostOwnership
+
+void SAL_CALL CTransferable::lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans )
+ throw(RuntimeException)
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/win/dnd/transferable.hxx b/vcl/workben/win/dnd/transferable.hxx
new file mode 100644
index 000000000..c1606cab8
--- /dev/null
+++ b/vcl/workben/win/dnd/transferable.hxx
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <cppuhelper/servicefactory.hxx>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+#include <osl/diagnose.h>
+
+#include <stdio.h>
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#include <objbase.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <memory>
+
+#include <process.h>
+
+#include "../../source/win32/ImplHelper.hxx"
+
+// my defines
+
+#define TEST_CLIPBOARD
+#define RDB_SYSPATH "d:\\projects\\src616\\dtrans\\wntmsci7\\bin\\applicat.rdb"
+#define WINCLIPBOARD_SERVICE_NAME L"com.sun.star.datatransfer.clipboard.SystemClipboard"
+#define WRITE_CB
+#define EVT_MANUAL_RESET TRUE
+#define EVT_INIT_NONSIGNALED FALSE
+#define EVT_NONAME ""
+
+// namespaces
+
+using namespace ::cppu;
+using namespace ::com::sun::star::datatransfer;
+using namespace ::com::sun::star::datatransfer::clipboard;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+
+class CTransferable : public WeakImplHelper< XClipboardOwner, XTransferable >
+{
+public:
+ CTransferable( ){};
+ explicit CTransferable( wchar_t* dataString);
+
+ // XTransferable
+
+ virtual Any SAL_CALL getTransferData( const DataFlavor& aFlavor ) throw(UnsupportedFlavorException, IOException, RuntimeException);
+ virtual Sequence< DataFlavor > SAL_CALL getTransferDataFlavors( ) throw(RuntimeException);
+ virtual sal_Bool SAL_CALL isDataFlavorSupported( const DataFlavor& aFlavor ) throw(RuntimeException);
+
+ // XClipboardOwner
+
+ virtual void SAL_CALL lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans ) throw(RuntimeException);
+
+private:
+ Sequence< DataFlavor > m_seqDFlv;
+ OUString m_Data;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/win/dtrans/XTDo.cxx b/vcl/workben/win/dtrans/XTDo.cxx
new file mode 100644
index 000000000..f8da707d9
--- /dev/null
+++ b/vcl/workben/win/dtrans/XTDo.cxx
@@ -0,0 +1,358 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <osl/diagnose.h>
+
+#include "../DTransHelper.hxx"
+
+#include "XTDo.hxx"
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#include <ole2.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include <memory>
+
+using namespace ::std;
+
+// OTWrapperDataObject
+
+/*
+ in the constructor we enumerate all formats offered by the transferable
+ and convert the formats into formatetc structures
+ if the transferable supports text in different charsets we use either
+ the charset equal to the charset of the current thread or an arbitrary
+ charset supported by the transferable and the system
+ if the transferable supports only unicodetext we offer in addition to
+ this text in the charset of the current thread
+ in order to allow the consumer of the clipboard to query for the charset
+ of the text in the clipboard we offer a CF_LOCALE
+*/
+CXTDataObject::CXTDataObject( ) :
+ m_nRefCnt( 0 )
+{
+
+}
+
+// IUnknown->QueryInterface
+
+STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
+{
+ OSL_ASSERT( NULL != ppvObject );
+
+ if ( NULL == ppvObject )
+ return E_INVALIDARG;
+
+ HRESULT hr = E_NOINTERFACE;
+
+ *ppvObject = NULL;
+
+ if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
+ {
+ *ppvObject = static_cast< IUnknown* >( this );
+ ( (LPUNKNOWN)*ppvObject )->AddRef( );
+ hr = S_OK;
+ }
+
+ return hr;
+}
+
+// IUnknown->AddRef
+
+STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
+{
+ return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
+}
+
+// IUnknown->Release
+
+STDMETHODIMP_(ULONG) CXTDataObject::Release( )
+{
+ // we need a helper variable because it's
+ // not allowed to access a member variable
+ // after an object is destroyed
+ ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
+
+ if ( 0 == nRefCnt )
+ {
+ delete this;
+ }
+
+ return nRefCnt;
+}
+
+/*------------------------------------------------------------------------
+
+ IDataObject->GetData
+ we deliver data only into global memory
+
+ algo:
+ 1. convert the given formatect struct into a valid dataflavor
+ 2. if the transferable directly supports the requested format
+ 2.1. if text data requested add a trailing '\0' in order to prevent
+ problems (windows needs '\0' terminated strings
+ 2.2. we expect unicode data as Sequence< sal_Unicode > and all other
+ text and raw data as Sequence< sal_Int8 >
+
+------------------------------------------------------------------------*/
+
+STDMETHODIMP CXTDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
+{
+ if ( ( NULL == pFormatetc ) || ( NULL == pmedium ) )
+ return E_INVALIDARG;
+
+ HRESULT hr = E_FAIL;
+
+ if ( CF_TEXT == pFormatetc->cfFormat )
+ {
+ CHGlobalHelper hGlobHlp( TRUE );
+
+ char pBuff[] = "Test OleClipboard";
+ hGlobHlp.Write( pBuff, sizeof( pBuff ), NULL );
+
+ pmedium->tymed = TYMED_HGLOBAL;
+ pmedium->hGlobal = hGlobHlp.GetHGlobal( );
+ pmedium->pUnkForRelease = NULL;
+
+ hr = S_OK;
+ }
+
+ return hr;
+}
+
+// IDataObject->EnumFormatEtc
+
+STDMETHODIMP CXTDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
+{
+ if ( ( NULL == ppenumFormatetc ) || ( DATADIR_SET == dwDirection ) )
+ return E_INVALIDARG;
+
+ *ppenumFormatetc = NULL;
+
+ HRESULT hr = E_FAIL;
+
+ if ( DATADIR_GET == dwDirection )
+ {
+ *ppenumFormatetc = new CEnumFormatEtc( this );
+ static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
+ hr = S_OK;
+ }
+
+ return hr;
+}
+
+// IDataObject->QueryGetData
+
+STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc )
+{
+ return E_NOTIMPL;
+}
+
+// IDataObject->GetDataHere
+
+STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM )
+{
+ return E_NOTIMPL;
+}
+
+// IDataObject->GetCanonicalFormatEtc
+
+STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC )
+{
+ return E_NOTIMPL;
+}
+
+// IDataObject->SetData
+
+STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL )
+{
+ return E_NOTIMPL;
+}
+
+// IDataObject->DAdvise
+
+STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * )
+{
+ return E_NOTIMPL;
+}
+
+// IDataObject->DUnadvise
+
+STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
+{
+ return E_NOTIMPL;
+}
+
+// IDataObject->EnumDAdvise
+
+STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * )
+{
+ return E_NOTIMPL;
+}
+
+CXTDataObject::operator IDataObject*( )
+{
+ return static_cast< IDataObject* >( this );
+}
+
+CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj ) :
+ m_nRefCnt( 0 ),
+ m_pUnkDataObj( pUnkDataObj ),
+ m_nCurrPos( 0 )
+{
+}
+
+// IUnknown->QueryInterface
+
+STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject )
+{
+ if ( NULL == ppvObject )
+ return E_INVALIDARG;
+
+ HRESULT hr = E_NOINTERFACE;
+
+ *ppvObject = NULL;
+
+ if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IEnumFORMATETC ) == iid ) )
+ {
+ *ppvObject = static_cast< IUnknown* >( this );
+ static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
+ hr = S_OK;
+ }
+
+ return hr;
+}
+
+// IUnknown->AddRef
+
+STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
+{
+ // keep the dataobject alive
+ m_pUnkDataObj->AddRef( );
+ return InterlockedIncrement( &m_nRefCnt );
+}
+
+// IUnknown->Release
+
+STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( )
+{
+ // release the outer dataobject
+ m_pUnkDataObj->Release( );
+
+ // we need a helper variable because it's
+ // not allowed to access a member variable
+ // after an object is destroyed
+ ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt );
+ if ( 0 == nRefCnt )
+ delete this;
+
+ return nRefCnt;
+}
+
+// IEnumFORMATETC->Next
+
+STDMETHODIMP CEnumFormatEtc::Next( ULONG celt, LPFORMATETC rgelt, ULONG* pceltFetched )
+{
+ if ( ( 0 != celt ) && ( NULL == rgelt ) )
+ return E_INVALIDARG;
+
+ ULONG ulFetched = 0;
+ ULONG ulToFetch = celt;
+ HRESULT hr = S_FALSE;
+
+ while( m_nCurrPos < 1 )
+ {
+ rgelt->cfFormat = CF_TEXT;
+ rgelt->ptd = NULL;
+ rgelt->dwAspect = DVASPECT_CONTENT;
+ rgelt->lindex = -1;
+ rgelt->tymed = TYMED_HGLOBAL;
+
+ ++m_nCurrPos;
+ ++rgelt;
+ --ulToFetch;
+ ++ulFetched;
+ }
+
+ if ( ulFetched == celt )
+ hr = S_OK;
+
+ if ( NULL != pceltFetched )
+ {
+ *pceltFetched = ulFetched;
+ }
+
+ return hr;
+}
+
+// IEnumFORMATETC->Skip
+
+STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt )
+{
+ HRESULT hr = S_FALSE;
+
+ /*
+ if ( ( m_nCurrPos + celt ) < m_nClipFormats )
+ {
+ m_nCurrPos += celt;
+ hr = S_OK;
+ }
+ */
+
+ return hr;
+}
+
+// IEnumFORMATETC->Reset
+
+STDMETHODIMP CEnumFormatEtc::Reset( )
+{
+ m_nCurrPos = 0;
+ return S_OK;
+}
+
+// IEnumFORMATETC->Clone
+
+STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
+{
+ OSL_ASSERT( NULL != ppenum );
+
+ if ( NULL == ppenum )
+ return E_INVALIDARG;
+
+ HRESULT hr = E_FAIL;
+
+ *ppenum = NULL;
+
+ CEnumFormatEtc* pCEnumFEtc = new CEnumFormatEtc( m_pUnkDataObj );
+ if ( NULL != pCEnumFEtc )
+ {
+ pCEnumFEtc->m_nCurrPos = m_nCurrPos;
+ *ppenum = static_cast< IEnumFORMATETC* >( pCEnumFEtc );
+ static_cast< LPUNKNOWN >( *ppenum )->AddRef( );
+ hr = NOERROR;
+ }
+
+ return hr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/win/dtrans/XTDo.hxx b/vcl/workben/win/dtrans/XTDo.hxx
new file mode 100644
index 000000000..095987a49
--- /dev/null
+++ b/vcl/workben/win/dtrans/XTDo.hxx
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#include <ole2.h>
+#include <objidl.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <vector>
+
+class EnumFormatEtc;
+
+/*--------------------------------------------------------------------------
+ - the function principle of the windows clipboard:
+ a data provider offers all formats he can deliver on the clipboard
+ a clipboard client ask for the available formats on the clipboard
+ and decides if there is a format he can use
+ if there is one, he requests the data in this format
+
+ - This class inherits from IDataObject and so can be placed on the
+ OleClipboard. The class wraps a transferable object which is the
+ original DataSource
+ - DataFlavors offered by this transferable will be translated into
+ appropriate clipboard formats
+ - if the transferable contains text data always text and unicodetext
+ will be offered or vice versa
+ - text data will be automatically converted between text and unicode text
+ - although the transferable may support text in different charsets
+ (codepages) only text in one codepage can be offered by the clipboard
+
+----------------------------------------------------------------------------*/
+
+class CXTDataObject : public IDataObject
+{
+public:
+ CXTDataObject( );
+
+ // ole interface implementation
+
+ //IUnknown interface methods
+ STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject);
+ STDMETHODIMP_( ULONG ) AddRef( );
+ STDMETHODIMP_( ULONG ) Release( );
+
+ // IDataObject interface methods
+ STDMETHODIMP GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium );
+ STDMETHODIMP GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium );
+ STDMETHODIMP QueryGetData( LPFORMATETC pFormatetc );
+ STDMETHODIMP GetCanonicalFormatEtc( LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut );
+ STDMETHODIMP SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease );
+ STDMETHODIMP EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc );
+ STDMETHODIMP DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD* pdwConnection );
+ STDMETHODIMP DUnadvise( DWORD dwConnection );
+ STDMETHODIMP EnumDAdvise( LPENUMSTATDATA* ppenumAdvise );
+
+ operator IDataObject*( );
+
+private:
+
+private:
+ LONG m_nRefCnt;
+};
+
+class CEnumFormatEtc : public IEnumFORMATETC
+{
+public:
+ explicit CEnumFormatEtc( LPUNKNOWN pUnkDataObj );
+
+ // IUnknown
+ STDMETHODIMP QueryInterface( REFIID iid, LPVOID* ppvObject );
+ STDMETHODIMP_( ULONG ) AddRef( );
+ STDMETHODIMP_( ULONG ) Release( );
+
+ //IEnumFORMATETC
+ STDMETHODIMP Next( ULONG celt, LPFORMATETC rgelt, ULONG* pceltFetched );
+ STDMETHODIMP Skip( ULONG celt );
+ STDMETHODIMP Reset( );
+ STDMETHODIMP Clone( IEnumFORMATETC** ppenum );
+
+private:
+ LONG m_nRefCnt;
+ LPUNKNOWN m_pUnkDataObj;
+ ULONG m_nCurrPos;
+};
+
+typedef CEnumFormatEtc *PCEnumFormatEtc;
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/win/dtrans/makefile.mk b/vcl/workben/win/dtrans/makefile.mk
new file mode 100644
index 000000000..3c82289f8
--- /dev/null
+++ b/vcl/workben/win/dtrans/makefile.mk
@@ -0,0 +1,81 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+PRJ=..$/..$/..
+
+PRJNAME= dtrans
+TARGET= testwincb
+TARGET1= testmshl
+LIBTARGET= NO
+TARGETTYPE= CUI
+USE_BOUNDCHK=
+TESTCB=TRUE
+
+.IF "$(USE_BOUNDCHK)"=="TR"
+bndchk=tr
+stoponerror=tr
+.ENDIF
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(TESTCB)"=="TRUE"
+
+CFLAGS+=-D_WIN32_DCOM -EHsc -Ob0
+
+# --- Files --------------------------------------------------------
+
+OBJFILES= $(OBJ)$/test_wincb.obj
+APP1TARGET= $(TARGET)
+APP1OBJS= $(OBJ)$/test_wincb.obj
+
+APP1STDLIBS= $(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(USER32LIB) \
+ $(OLE32LIB)\
+ $(COMDLG32LIB)
+
+APP1LIBS= $(SLB)$/dtutils.lib
+
+APP1NOSAL= TRUE
+
+.ENDIF
+
+.IF "$(TESTCB)"==""
+
+CFLAGS+=/D_WIN32_DCOM /EHsc /Ob0
+
+OBJFILES= $(OBJ)$/testmarshal.obj
+APP1TARGET= $(TARGET1)
+APP1OBJS= $(OBJ)$/testmarshal.obj
+
+APP1STDLIBS= $(SALLIB)\
+ $(USER32LIB)\
+ $(OLE32LIB)\
+ comsupp.lib\
+ $(OLEAUT32LIB)
+
+APP1LIBS=
+APP1NOSAL= TRUE
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+.INCLUDE : target.mk
diff --git a/vcl/workben/win/dtrans/test_wincb.cxx b/vcl/workben/win/dtrans/test_wincb.cxx
new file mode 100644
index 000000000..96839e22a
--- /dev/null
+++ b/vcl/workben/win/dtrans/test_wincb.cxx
@@ -0,0 +1,287 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "../misc/ImplHelper.hxx"
+
+#include <cppuhelper/servicefactory.hxx>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp>
+#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+#include <osl/diagnose.h>
+
+#include <stdio.h>
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#include <objbase.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <memory>
+
+#include <process.h>
+
+// my defines
+
+#define TEST_CLIPBOARD
+#define RDB_SYSPATH "d:\\projects\\src623\\dtrans\\wntmsci7\\bin\\applicat.rdb"
+#define WINCLIPBOARD_SERVICE_NAME L"com.sun.star.datatransfer.clipboard.SystemClipboard"
+#define WRITE_CB
+#define EVT_MANUAL_RESET TRUE
+#define EVT_INIT_NONSIGNALED FALSE
+#define EVT_NONAME ""
+
+// namespaces
+
+using namespace ::std;
+using namespace ::cppu;
+using namespace ::com::sun::star::datatransfer;
+using namespace ::com::sun::star::datatransfer::clipboard;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+
+// globales
+
+Reference< XTransferable > rXTransfRead;
+HANDLE g_hEvtThreadWakeup;
+
+class CClipboardListener : public WeakImplHelper < XClipboardListener >
+{
+public:
+ ~CClipboardListener( );
+
+ // XClipboardListener
+
+ virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException);
+ virtual void SAL_CALL changedContents( const ClipboardEvent& event ) throw( RuntimeException );
+};
+
+CClipboardListener::~CClipboardListener( )
+{
+}
+
+void SAL_CALL CClipboardListener::disposing( const EventObject& Source ) throw(RuntimeException)
+{
+
+}
+
+void SAL_CALL CClipboardListener::changedContents( const ClipboardEvent& event ) throw( RuntimeException )
+{
+ //MessageBox( NULL, TEXT("Clipboard content changed"), TEXT("Info"), MB_OK | MB_ICONINFORMATION );
+}
+
+class CTransferable : public WeakImplHelper< XClipboardOwner, XTransferable >
+{
+public:
+ CTransferable( );
+
+ // XTransferable
+
+ virtual Any SAL_CALL getTransferData( const DataFlavor& aFlavor )
+ throw(UnsupportedFlavorException, IOException, RuntimeException);
+
+ virtual Sequence< DataFlavor > SAL_CALL getTransferDataFlavors( ) throw(RuntimeException);
+
+ virtual sal_Bool SAL_CALL isDataFlavorSupported( const DataFlavor& aFlavor ) throw(RuntimeException);
+
+ // XClipboardOwner
+
+ virtual void SAL_CALL lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans )
+ throw(RuntimeException);
+
+private:
+ Sequence< DataFlavor > m_FlavorList;
+ OUString m_Data;
+};
+
+// ctor
+
+CTransferable::CTransferable( ) :
+ m_FlavorList( 1 ),
+ m_Data( OUString("I bought a new bike!") )
+{
+ DataFlavor df;
+
+ //df.MimeType = L"text/plain;charset=utf-16";
+ //df.DataType = cppu::UnoType<OUString>::get();
+
+ df.MimeType = L"text/plain;charset=Windows1252";
+ df.DataType = cppu::UnoType<Sequence< sal_Int8 >>::get();
+
+ m_FlavorList[0] = df;
+}
+
+// getTransferData
+
+Any SAL_CALL CTransferable::getTransferData( const DataFlavor& aFlavor )
+ throw(UnsupportedFlavorException, IOException, RuntimeException)
+{
+ Any anyData;
+
+ /*
+ if ( aFlavor.MimeType == m_FlavorList[0].MimeType )
+ anyData = makeAny( m_Data );
+ */
+ if ( aFlavor.MimeType.equalsIgnoreCase( m_FlavorList[0].MimeType ) )
+ {
+ OString text(
+ m_Data.getStr( ),
+ m_Data.getLength( ),
+ RTL_TEXTENCODING_ASCII_US );
+
+ Sequence< sal_Int8 > textStream( text.getLength( ) + 1 );
+
+ memcpy( textStream.getArray( ), text.getStr( ), textStream.getLength( ) );
+
+ anyData = makeAny( textStream );
+ }
+ else
+ throw UnsupportedFlavorException( );
+
+ return anyData;
+}
+
+// getTransferDataFlavors
+
+Sequence< DataFlavor > SAL_CALL CTransferable::getTransferDataFlavors( )
+ throw(RuntimeException)
+{
+ return m_FlavorList;
+}
+
+// isDataFlavorSupported
+
+sal_Bool SAL_CALL CTransferable::isDataFlavorSupported( const DataFlavor& aFlavor )
+ throw(RuntimeException)
+{
+ sal_Int32 nLength = m_FlavorList.getLength( );
+
+ for ( sal_Int32 i = 0; i < nLength; ++i )
+ if ( m_FlavorList[i].MimeType == aFlavor.MimeType )
+ return sal_True;
+
+ return sal_False;
+}
+
+// lostOwnership
+
+void SAL_CALL CTransferable::lostOwnership(
+ const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans )
+ throw(RuntimeException)
+{
+ //MessageBox( NULL, TEXT("No longer clipboard owner"), TEXT("Info"), MB_OK | MB_ICONINFORMATION );
+}
+
+// main
+
+int SAL_CALL main( int nArgc, char* Argv[] )
+{
+ // create a multi-threaded apartment; we can test only
+ // with a multithreaded apartment because for a single
+ // threaded apartment we need a message loop to deliver
+ // messages to our XTDataObject
+ //HRESULT hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
+ (void)CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
+
+ char buff[6];
+
+ LCID lcid = MAKELCID( MAKELANGID( LANG_GERMAN, SUBLANG_GERMAN ), SORT_DEFAULT );
+
+ BOOL bValid = IsValidLocale( lcid, LCID_SUPPORTED );
+ GetLocaleInfoA( lcid, LOCALE_IDEFAULTANSICODEPAGE, buff, sizeof( buff ) );
+
+ // get the global service-manager
+
+ Reference< XMultiServiceFactory > g_xFactory( createRegistryServiceFactory( RDB_SYSPATH ) );
+
+ // Print a message if an error occurred.
+ if ( !g_xFactory.is( ) )
+ {
+ OSL_FAIL("Can't create RegistryServiceFactory");
+ return(-1);
+ }
+
+ // try to get an Interface to a XFilePicker Service
+
+ Reference< XTransferable > rXTransf( static_cast< XTransferable* >( new CTransferable ) );
+
+ Reference< XClipboard >xClipboard( g_xFactory->createInstance( WINCLIPBOARD_SERVICE_NAME ), UNO_QUERY );
+ if ( !xClipboard.is( ) )
+ {
+ OSL_FAIL( "Error creating Clipboard Service" );
+ return(-1);
+ }
+
+ Reference< XClipboardNotifier > xClipNotifier( xClipboard, UNO_QUERY );
+ Reference< XClipboardListener > rXClipListener( static_cast< XClipboardListener* >( new CClipboardListener() ) );
+ xClipNotifier->addClipboardListener( rXClipListener );
+
+ MessageBox( NULL, TEXT("Go"), TEXT("INFO"), MB_OK|MB_ICONINFORMATION);
+
+ // set new clipboard content
+ xClipboard->setContents( rXTransf, Reference< XClipboardOwner >( rXTransf, UNO_QUERY ) );
+
+ /*
+ MessageBox( NULL, TEXT("Clear content"), TEXT("INFO"), MB_OK|MB_ICONINFORMATION);
+
+ Reference< XClipboardOwner > rXClipOwner;
+ Reference< XTransferable > rXEmptyTransf;
+ xClipboard->setContents( rXEmptyTransf, rXClipOwner );
+ */
+
+ MessageBox( NULL, TEXT("Stop"), TEXT("INFO"), MB_OK|MB_ICONINFORMATION);
+
+ // flush the clipboard content
+ Reference< XFlushableClipboard > rXFlushableClip( xClipboard, UNO_QUERY );
+ rXFlushableClip->flushClipboard( );
+ rXFlushableClip.clear();
+
+ xClipNotifier->removeClipboardListener( rXClipListener );
+ rXClipListener.clear();
+ xClipNotifier.clear();
+
+ // shutdown the service manager
+
+ // Cast factory to XComponent
+ Reference< XComponent > xComponent( g_xFactory, UNO_QUERY );
+
+ if ( !xComponent.is() )
+ OSL_FAIL("Error shutting down");
+
+ // Dispose and clear factory
+ xComponent->dispose();
+ xComponent.clear();
+
+ g_xFactory.clear();
+
+ CoUninitialize( );
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/win/dtrans/testmarshal.cxx b/vcl/workben/win/dtrans/testmarshal.cxx
new file mode 100644
index 000000000..8ef53c0f4
--- /dev/null
+++ b/vcl/workben/win/dtrans/testmarshal.cxx
@@ -0,0 +1,212 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+#include <stdio.h>
+#if defined _MSC_VER
+#pragma warning(push,1)
+#endif
+#include <windows.h>
+#include <objbase.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <memory>
+
+#include <process.h>
+#include "XTDo.hxx"
+
+// my defines
+
+#define WRITE_CB
+#define EVT_MANUAL_RESET TRUE
+#define EVT_INIT_NONSIGNALED FALSE
+#define EVT_NONAME ""
+#define WAIT_MSGLOOP
+#define RAW_MARSHALING
+
+// namespaces
+
+using namespace ::std;
+
+// globales
+
+HANDLE g_hEvtThreadWakeup;
+
+#ifdef RAW_MARSHALING
+ HGLOBAL g_hGlob;
+#else
+ IStream* g_pStm;
+#endif
+
+// a thread in another apartment to test apartment transparency
+
+DWORD WINAPI ThreadProc(_In_ LPVOID pParam)
+{
+ // setup another apartment
+ HRESULT hr = OleInitialize( NULL );
+
+ WaitForSingleObject( g_hEvtThreadWakeup, INFINITE );
+
+ IDataObject* pIDo = NULL;
+
+#ifdef RAW_MARSHALING
+
+ IStream* pStm = NULL;
+ hr = CreateStreamOnHGlobal( g_hGlob, FALSE, &pStm );
+ if ( SUCCEEDED( hr ) )
+ {
+ hr = CoUnmarshalInterface(
+ pStm,
+ __uuidof( IDataObject ),
+ (void**)&pIDo );
+
+ hr = pStm->Release( );
+ }
+
+#else
+
+ hr = CoGetInterfaceAndReleaseStream(
+ g_pStm,
+ __uuidof( IDataObject ),
+ (void**)&pIDo
+ );
+
+#endif
+
+ IEnumFORMATETC* pIEEtc;
+ hr = pIDo->EnumFormatEtc( DATADIR_GET, &pIEEtc );
+
+ hr = OleIsCurrentClipboard( pIDo );
+
+ hr = OleFlushClipboard( );
+
+ OleUninitialize( );
+
+ return 0;
+}
+
+// main
+
+int SAL_CALL main( int nArgc, char* Argv[] )
+{
+ HRESULT hr = OleInitialize( NULL );
+
+ g_hEvtThreadWakeup = CreateEvent( 0,
+ EVT_MANUAL_RESET,
+ EVT_INIT_NONSIGNALED,
+ EVT_NONAME );
+
+ DWORD uThreadId;
+
+ // create a thread in another apartment
+ HANDLE hThread = CreateThread( NULL, 0, ThreadProc, NULL, 0, &uThreadId );
+
+ IDataObject* pIDo = new CXTDataObject( );
+
+ hr = OleSetClipboard( pIDo );
+ hr = E_FAIL;
+
+ hr = OleIsCurrentClipboard( pIDo );
+
+ //hr = OleGetClipboard( &pIDo );
+ if ( SUCCEEDED( hr ) )
+ {
+#ifdef RAW_MARSHALING
+
+ IStream* pStm = NULL;
+
+ hr = CreateStreamOnHGlobal( 0, FALSE, &pStm );
+ if ( SUCCEEDED( hr ) )
+ {
+ hr = CoMarshalInterface(
+ pStm,
+ __uuidof( IDataObject ),
+ pIDo,
+ MSHCTX_INPROC,
+ 0,
+ MSHLFLAGS_NORMAL );
+ if ( SUCCEEDED( hr ) )
+ hr = GetHGlobalFromStream( pStm, &g_hGlob );
+
+ hr = pStm->Release( );
+ }
+
+#else
+
+ hr = CoMarshalInterThreadInterfaceInStream(
+ __uuidof( IDataObject ),
+ pIDo,
+ &g_pStm );
+
+#endif
+
+ if ( SUCCEEDED( hr ) )
+ {
+ // wakeup the thread and waiting util it ends
+ SetEvent( g_hEvtThreadWakeup );
+
+#ifdef WAIT_MSGLOOP
+
+ BOOL bContinue = TRUE;
+
+ while( bContinue )
+ {
+ DWORD dwResult = WaitForMultipleObjects(
+ 1,
+ &hThread,
+ TRUE,
+ 0 );
+
+ if ( WAIT_OBJECT_0 == dwResult )
+ {
+ bContinue = FALSE;
+ }
+ else
+ {
+ MSG msg;
+ while( PeekMessage(
+ &msg,
+ NULL,
+ 0,
+ 0,
+ PM_REMOVE ) )
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ } // while
+
+#endif
+
+ } // if
+ } // if
+
+ OleFlushClipboard( );
+
+ OleUninitialize( );
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */