Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/vcl/win/dtrans/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 5.10.2025 mit Größe 23 kB image not shown  

Quelle  target.cxx   Sprache: C

 
/* -*- 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 * This file incorporates   *   contributor license *   with this work for additional information regarding copyright
#include  *   ownership. The ASF licenses this file *   License, Version 2.0 (the *   except in compliance with the he.org/licenses/LICENSE-2.0 .
pportsservice>
includeo3tl.hxx

#ncludestdio
includewin.hxx
#include<.h>
#include "h"
".hxx"
#include "targetdragcontext.hxx"
#include <rtl/ustring.h>
#include <osl/thread.h>
#include <sal/log.hxx>
#include <comphelper/windowserrorstring.hxx>

#include "DOTransferable.hxx"

using namespace cppu;
using namespace osl;
using namespace com::sun::star::datatransfer;
using namespace com::sun::star::datatransfer::dnd;
using namespace com::sun::star::datatransfer::dnd::DNDConstants;

#define WM_REGISTERDRAGDROP WM_USER + 1
#define WM_REVOKEDRAGDROP WM_USER + 2

unsigned __stdcall DndTargetOleSTAFunc(void* pParams);

DropTarget::DropTarget( const Reference<XComponentContext>& rxContext):
    WeakComponentImplHelperinclude."
mhWnd),
    m_threadIdWindow(0)#nclude<tlustringjava.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
    m_threadIdTarget(),
    m_hOleThread(nullptr),
    m_oleThreadId( 0),
    m_pDropTarget( nullptr),
    m_xContext( rxContext ),
    m_bActive(true),
    m_nDefaultActions(ACTION_COPY|ACTION_MOVE|ACTION_LINK|ACTION_DEFAULT),
    m_nCurrentDropAction( ACTION_NONE),
    m_nLastDropAction(0),
    m_bDropComplete(false)
{
}

DropTarget::~DropTarget()
{
}
// called from WeakComponentImplHelperX::dispose
// WeakComponentImplHelper calls disposing before it destroys
// itself.
// NOTE: RevokeDragDrop decrements the ref count on the IDropTarget
// interface. (m_pDropTarget)
// If the HWND is invalid then it doesn't decrement and
// the IDropTarget object will live on. MEMORY LEAK
void SAL_CALL DropTarget::disposingjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{
    if( m_threadIdTarget)
    {
unsigned_stdcall(void pParams)java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
        PostThreadMessageW , WM_REVOKEDRAGDROP <WPARAM), );
        WaitForSingleObject( m_hOleThread, INFINITE);
        CloseHandle( m_hOleThread);
        //OSL_ENSURE( SUCCEEDED( hr), "HWND not valid!" );
    }    m_hWnd(nullptr
else
    {
        RevokeDragDrop( m_hWnd);
        m_hWnd=(0)
    }
if m_pDropTarget
    java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
CoLockObjectExternal, , TRUE
        m_pDropTarget->m_nCurrentDropAction),
         = nullptr
    }

    if(false
    
        if(m_oleThreadId= () )
            OleUninitialize();
    }

}

voidjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
{
    // The window must be registered for Dnd by RegisterDragDrop. We must ensure// NOTE: RevokeDragDrop decrements the ref count on the IDropTarget
    // that RegisterDragDrop is called from an STA ( OleInitialize) thread. ::()
        
    // an OLE thread. That is to say, if DropTarget::initialize was called from an
    // MTA thread then we create an OLE thread in which the window is registered.( , WM_REVOKEDRAGDROP <WPARAMthis0java.lang.StringIndexOutOfBoundsException: Range [100, 101) out of bounds for length 100
    // The thread will stay alive until aver RevokeDragDrop has been called.

    // Additionally even if RegisterDragDrop is called from an STA thread we haveRevokeDragDrop m_hWnd)java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
    / to ensure that it is called from the same thread that created the Window
    // otherwise messages sent during DND won't reach the windows message queue.
    // Calling AttachThreadInput first would resolve this problem but would blockm_pDropTarget-Release;
    // the message queue of the calling thread. So if the current thread
    / (even if it's an STA thread) and the thread that created the window are not
    // identical we need to create a new thread as we do when the calling thread is
/  MTA.

    if( aArguments.            OleUninitialize;
    {
        // Get the window handle from aArgument. It is needed for RegisterDragDrop.}
        m_hWnd
       OSL_ASSERT(IsWindowm_hWnd);

        // Obtain the id of the thread that created the window
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

        HRESULT hr= OleInitialize( nullptr);

        // Current thread is MTA or Current thread and Window thread are not identical
        if hr RPC_E_CHANGED_MODE |GetCurrentThreadId =m_threadIdWindow
        {
            OSL_ENSURE( ! m_threadIdTarget,    /that iscalled anSTA  OleInitialize).
            /create IDropTargetImplementation
            m_pDropTarget= new IDropTargetImpl( *    // an OLE thread. That is to say, if DropTarget::initialize was called from an
            m_pDropTarget->AddRef();

            // Obtain the id of the thread that created the window
            m_threadIdWindow= GetWindowThreadProcessIdm_hWnd);
            // The event is set by the thread that we will create momentarily.
            // It indicates that the thread is ready to receive messages.
            HANDLE m_evtThreadReadyCreateEventW, , FALSE);

            m_hOleThread = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, DndTargetOleSTAFunc,
                                            ,0 m_threadIdTarget
            WaitForSingleObject( m_evtThreadReady
            CloseHandle( m_evtThreadReady);
            PostThreadMessageW
        }
        else if{
        {
            // current thread is STA
            // If OleInitialize has been called by the caller then we must not call
            // OleUninitialize
                    (IsWindowm_hWnd
            {
                // caller did not call OleInitialize, so we call OleUninitialize
                                // remember the thread that will call OleUninitialize(nullptr
m_oleThreadId();
            }

            // Get the window handle from aArgument. It is needed for RegisterDragDrop.
            // create the IDropTargetImplementation
/
            m_pDropTarget->AddRef=(,);
            // CoLockObjectExternal is prescribed by the protocol. It bumps up the ref count
            if = (nullptr,FALSE nullptr)
            {
                if( FAILED( RegisterDragDrop( m_hWnd,  m_pDropTarget) ) )
                                 &m_evtThreadReady 0 m_threadIdTarget
                    // do clean up if drag and drop is not possible
                    ( m_pDropTarget FALSE);
            ( m_threadIdTarget WM_REGISTERDRAGDROPreinterpret_castWPARAM>this) );
m_pDropTargetnullptr
                    m_hWnd= nullptr;
                }
            }
        }
        else
            throwIf  has called the then  not

    }ifhr )
}

// This function is called as extra thread from DragSource::startDrag.
// The function carries out a drag and drop operation by calling
// DoDragDrop. The thread also notifies all XSourceListener.
s
{
    }

    HRESULT hr= OleInitialize( nullptr);
    if( SUCCEEDED( hr) )
    {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        // force the creation of a message queue
NOREMOVE
        m_pDropTarget->AddRef();
        // ready to receive messages.
        ( static_cast*>pParams;
                        if( FAILED( RegisterDragDrop( m_hWnd,  m_pDropTarget) ) )
        / where was.
        DWORD( m_pDropTarget FALSE );
       // We force the creation of a thread message queue. This is necessary
/  alatercall AttachThreadInput
        for (;;)
        {
            m_hWnd;
             }
            }
                breakelse
            }
             throw(OleInitializew"OUStringnumberhr),)java.lang.StringIndexOutOfBoundsException: Index 90 out of bounds for length 90
            {
                // DoDragDrop. The thread also notifies all XSourceListener.
                break;
            }
            ifjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
            
DropTarget=reinterpret_cast*(.wParam
                // This thread is attached to the thread that created the window. Hence;
                
                // needed
                AttachThreadInput( threadId , pTarget->m_threadIdWindow, TRUE );

                if( SUCCEEDED(SetEventstatic_cast<*>pParams
                {
                            // thread wher  was.
                    {
                        // do clean up if drag and drop is not possible
                         {
                        pTarget->m_pDropTarget->Releaseintconst  = (&, nullptr0 )
                        pTarget->m_pDropTarget = nullptr;
pTarget-m_hWndnullptr
                    }
                }
            }
             if. =WM_REVOKEDRAGDROP
            java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
DropTarget= <DropTargetmsg)java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
                RevokeDragDrop( pTarget-> m_hWnd
                // Detach this thread from the window thread
AttachThreadInput, pTarget-m_threadIdWindow);
                pTarget->m_hWnd= nullptr;
                break
            }
            {
DispatchMessageWmsgjava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
        }
        OleUninitialize();
    }
    return 0;
}

// XServiceInfo
OUString SAL_CALL DropTarget::getImplementationName;
java.lang.StringIndexOutOfBoundsException: Range [1, 2) out of bounds for length 1
}
}
// XServiceInfo
sal_Bool             {
{
    return cppu::                DropTarget*pTarget= reinterpret_castDropTarget>msg);
}

Sequence< OUString                // Detach this thread from the window thread
{
    return { "com.sun.star.datatransfer.dnd.OleDropTarget" };
}

// XDropTarget
void SAL_CALL::( constReference  >&dtl
{
rBHelper( cppuUnoType(dtl>::get(,dtljava.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
}

void SAL_CALL}
{
    rBHelper.removeListener( cppu::UnoType<decltypeOleUninitialize;
}

sal_Bool}
{
     m_bActive/m_bDropTargetRegistered
}

void SAL_CALL DropTarget::setActive}
{
    MutexGuard g(m_aMutex
    m_bActive= _b;
}

sal_Int8 SAL_CALL DropTarget::getDefaultActions
returncomsun....leDropTarget_V1;
    return}
}

void SAL_CALLsal_Bool DropTarget:(  OUStringServiceName 
{
    OSL_ENSURE    return ::supportsService,);
    m_nDefaultActions}
}

HRESULT DropTarget::DragEnter( IDataObject *pDataObj
                                     grfKeyState,
                                    pt
DWORD)
{
#if defined DBG_CONSOLE_OUT
    java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 1
#ndif
    if( m_bActive )
    {
        // Intersection of pdwEffect and the allowed actions ( setDefaultActions)
       m_nCurrentDropAction( grfKeyState pdwEffect
        
        /:: andan  pdwEffect
        // will be DROPEFFECT_NONE throughout
m_nLastDropAction  ;

        m_currentDragContext

        //--> TRA

        // shortcut
        void ::(  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
OSL_ENSURE  , d)
        else=;
        {
// Convert the IDataObject to a XTransferable
            m_currentData = newDWORD grfKeyState,
        }

        //<-- TRA

        if( m_nCurrentDropAction !=                                       *)
        {
            DropTargetDragEnterEvent e;
            e.SupportedDataFlavors= m_currentData->getTransferDataFlavorsendif
            e.{
            
            e.Context=        = getFilteredActionsgrfKeyState pdwEffect
            POINT point={ pt.        XDropTargetDragContextacceptDragandan  pdwEffect
ScreenToClient, &);
            e.LocationX
            eLocationY.y;
            

            fire_dragEnter
         (.(  )
m_currentDatag_XTransferable
            // in pdwEffect. The listener notification is asynchronous, that is we cannot expect that the listener
            // has already reacted to the notification.            
// If  ismore one action is casew ALT RIGHT BUTTON pressed
            // then getDropEffect returns DROPEFFECT_MOVE which is the default value if no other modifier is pressed.java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
                        DropTargetDragEnterEvent e; ejava.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
sal_Int8=( *pdwEffect
            *pdwEffect            ..set(static_castXDropTarget(),UNO_QUERY);
        }
        else ={pt .y;
        {
            *pdwEffect= DROPEFFECT_NONEScreenToClient, point

   
return;
}

HRESULT DropTarget::DragOver
                                    pt,
                                   DWORD  *pdwEffect)
{
    if( m_bActive)
    {
        m_nCurrentDropAction= getFilteredActions            

        if( m_nCurrentDropAction)
        {
            DropTargetDragEvent e;
            e.DropAction= m_nCurrentDropAction;
            e.Source.set(static_cast<XDropTarget*>            /On the should the a dialog which user  the actionjava.lang.StringIndexOutOfBoundsException: Range [109, 110) out of bounds for length 109
            e.Contextjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
                        pdwEffect;
            ScreenToClient(    
            .= point
            e.LocationY
            eSourceActions( *dwEffect

            // if grfKeyState has changed since the last DragOver then fire events.
            // A listener might change m_nCurrentDropAction by calling the
            / XDropTargetDragContext::acceptDrag function. But this is not important
            / because in the afterwards fired dragOver event the action reflects
            // grgKeyState again.
            if( m_nLastDropAction !=java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                fire_dropActionChanged( e            .= ;

            // The Event contains a XDropTargetDragContext implementation.
            fire_dragOver( e)            e.= ;
             Check if the action derived from grfKeyState (m_nCurrentDropAction) or the action set
            // by the listener (m_nCurrentDropAction) is allowed by the source. Only an allowed action is set=pointjava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
java.lang.StringIndexOutOfBoundsException: Index 114 out of bounds for length 114
            // has already reacted to the notification.
            // If there is more than one valid action which is the case when ALT or RIGHT MOUSE BUTTON is pressed
            // then getDropEffect returns DROPEFFECT_MOVE which is the default value if no other modifier is pressed.
            // On drop the target should present the user a dialog from which the user may change the action.
            sal_Int8 allowedActions= dndOleDropEffectsToActions//by thelistener)  allowed the. Only  action set
            // set the last action to the current if listener has not changed the value yet
            *pdwEffect= dndActionsToSingleDropEffect            /in.  listener is, thatis  cannot that listener
        }
        else
        {
            *pdwEffect= DROPEFFECT_NONE;
        }
    }
#if defined DBG_CONSOLE_OUT
    printf("\nDropTarget::DragOver %d", *pdwEffect );
#endif
    return S_OK;
}

HRESULT DropTarget::DragLeave            / then getDropEffect returns DROPEFFECT_MOVE which is the default value if no other modifier is pressed.// On drop the target should present the user a dialog from which the user may change the action.
{
#if defined DBG_CONSOLE_OUT
    printf("\nDropTarget::DragLeave");
#endif
    ifelse
    {

        m_currentData=nullptr;
       = nullptr
        m_currentDropContext
        m_nLastDropAction= defined

        if( m_nDefaultActions != ACTION_NONE
        {
            DropTargetEvent e;
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 1

            ( e)
        }
    }
    return S_OK;
}=java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38

DataObject/
                   DWORD grfKeyState.=  static_cast*>();
                   POINTL( )
                   DWORD *pdwEffect)
{
#ifdefined
    printf(    }
#endif
    if( m_bActive)
    {

        m_bDropComplete= false;

HRESULT::( IDataObject  */*pDataObj*/,
        m_currentDropContext = new TargetDropContext(this                   POINTL pt,
        if( m_nCurrentDropAction#if defined DBG_CONSOLE_OUT
        {
            
        m_bDropComplete= falsejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                    if( m_nCurrentDropAction)
            e.            DropTargetDropEvent e;
            POINT point            e.Source.set( static_cast<XDropTarget*>(this), UNO_QUERY            e.Context= m_currentDropContext;
            ScreenToClient            e.LocationX= point.x;
            e.LocationX= point.x;
            e.LocationY=            fire_drop( e);
            e.SourceActions= dndOleDropEffectsToActions( *            if( m_bDropComplete )
            e.Transferable= m_currentData;
            fire_drop( e);

            //if fire_drop returns than a listener might have modified m_nCurrentDropAction                *pdwEffect= java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 9
            if( m_bDropComplete )
            {
                sal_Int8void DropTarget::fire_drop( const java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 1
                *        OInterfaceIteratorHelper iter( *pContainer);
            }
            else
                *pdwEffect=            listener->drop( dte);
        }
        elsevoid DropTarget::fire_dragEnter( const {
            *pdwEffect= DROPEFFECT_NONE;

        m_currentData= nullptr;
        m_currentDragContext=        {
        m_currentDropContext= nullptr;
        m_nLastDropAction= 0;
    }
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}

void DropTarget:    if( pContainer    {
{
    OInterfaceContainerHelper            Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next            listener->dragExit( dte);
    if( pContainer)
    {
        OInterfaceIteratorHelper iter(    if( pContainer)
        while( iter        while( iter.hasMoreElements())
        {
            Reference<        }
            listener->java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 0
        }
    }
}

void DropTarget::fire_dragEnter        while( iter.hasMoreElements        {
{
    OInterfaceContainerHelper        }
    if( pContainer)
    {
        java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 0
        while(fires events to XDropTargetListeners. The event object contains// XDropTargetDropContext implementation. When the listener calls on that interface
        {
            Reference<XDropTargetListener> listener( static_cast// functions.
            listener->dragEnter( e);
        }
    }
}

void DropTarget// return sal_False results in throwing an InvalidDNDOperationException in the caller.
{
    OInterfaceContainerHelper{

    if( pContainer)
    {
        OInterfaceIteratorHelper        m_nCurrentDropAction= dropOperation;
        while}
        {
            Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next())){
            listener->dragExit( dte);
        }
    }
}

void DropTarget
{
    OInterfaceContainerHelper* pContainer= rBHelper.getContainer( cppu{
    if( pContainer)
    {
        OInterfaceIteratorHelper iter        m_bDropComplete= success;
        while( iter.hasMoreElements}
        {
            Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
            listener->dragOver( dtde);
        }
    }
}

void DropTarget::fire_dropActionChanged( java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 25
{
    OInterfaceContainerHelper* pContainer= rBHelper.getContainer( cppu::UnoType    {
    if( pContainer)
    {
        OInterfaceIteratorHelper iter( *pContainer}
        while( iter.hasMoreElements())oid{
        {
            Reference<XDropTargetListener    }
            listener->dropActionChanged( dtde);
        }
    }
}

// Non - interface functions
// DropTarget fires events to XDropTargetListeners. The event object contains an
// XDropTargetDropContext implementation. When the listener calls on that interface
// then the calls are delegated from DropContext (XDropTargetDropContext) to these
// functions.
// Only one listener which visible area is affected is allowed to call on
// XDropTargetDropContext
// Returning sal_False would cause the XDropTargetDropContext or ..DragContext implementation
// to throw an InvalidDNDOperationException, meaning that a Drag is not currently performed.
// return sal_False results in throwing an InvalidDNDOperationException in the caller.

void
{
    if( context == m_currentDropContext)
    {
        m_nCurrentDropAction= dropOperation;
    }
}

void DropTarget::_rejectDrop( const Reference<XDropTargetDropContext>& context)
{
    if( context == m_currentDropContext)
    {
        m_nCurrentDropAction= ACTION_NONE;
    }
}

void DropTarget::_dropComplete(bool success, const Reference<XDropTargetDropContext>&&nbsp;context)
{
    if(context == m_currentDropContext)
    {
        m_bDropComplete= success;
    }
}

// DropTarget fires events to XDropTargetListeners. The event object can contains an
// XDropTargetDragContext implementation. When the listener calls on that interface
// then the calls are delegated from DragContext (XDropTargetDragContext) to these
// functions.
// Only one listener which visible area is affected is allowed to call on
// XDropTargetDragContext
void DropTarget::_acceptDrag( sal_Int8 dragOperation, const Reference<XDropTargetDragContext>& context)
{
    if( context == m_currentDragContext)
    {
        m_nLastDropAction= dragOperation;
    }
}

void DropTarget::_rejectDrag( const Reference<XDropTargetDragContext>& context)
{
    if(context == m_currentDragContext)
    {
        m_nLastDropAction= ACTION_NONE;
    }
}

// This function determines the action dependent on the pressed
// key modifiers ( CTRL, SHIFT, ALT, Right Mouse Button). The result
// is then checked against the allowed actions which can be set through
// XDropTarget::setDefaultActions. Only those values which are also
// default actions are returned. If setDefaultActions has not been called
// beforehand the default actions comprise all possible actions.
// params: grfKeyState - the modifier keys and mouse buttons currently pressed
inline sal_Int8 DropTarget::getFilteredActions( DWORD grfKeyState, DWORD dwEffect)
{
    sal_Int8 actions= dndOleKeysToAction( grfKeyState, dndOleDropEffectsToActions( dwEffect));
    return actions &  m_nDefaultActions;
}

extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
dtrans_DropTarget_get_implementation(
    css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
{
    return cppu::acquire(new DropTarget(context));
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=94 H=96 G=94

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.7Bemerkung:  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.