diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /vcl/workben/win | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vcl/workben/win')
-rw-r--r-- | vcl/workben/win/dnd/atlwindow.cxx | 238 | ||||
-rw-r--r-- | vcl/workben/win/dnd/atlwindow.hxx | 87 | ||||
-rw-r--r-- | vcl/workben/win/dnd/dndTest.cxx | 177 | ||||
-rw-r--r-- | vcl/workben/win/dnd/makefile.mk | 70 | ||||
-rw-r--r-- | vcl/workben/win/dnd/sourcelistener.cxx | 59 | ||||
-rw-r--r-- | vcl/workben/win/dnd/sourcelistener.hxx | 56 | ||||
-rw-r--r-- | vcl/workben/win/dnd/targetlistener.cxx | 78 | ||||
-rw-r--r-- | vcl/workben/win/dnd/targetlistener.hxx | 64 | ||||
-rw-r--r-- | vcl/workben/win/dnd/transferable.cxx | 105 | ||||
-rw-r--r-- | vcl/workben/win/dnd/transferable.hxx | 88 | ||||
-rw-r--r-- | vcl/workben/win/dtrans/XTDo.cxx | 358 | ||||
-rw-r--r-- | vcl/workben/win/dtrans/XTDo.hxx | 111 | ||||
-rw-r--r-- | vcl/workben/win/dtrans/makefile.mk | 81 | ||||
-rw-r--r-- | vcl/workben/win/dtrans/test_wincb.cxx | 287 | ||||
-rw-r--r-- | vcl/workben/win/dtrans/testmarshal.cxx | 212 |
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: */ |