/* -*- 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 .
*/
Reference<XAccessibleContext> pRContext = pXAcc->getAccessibleContext(); if (!pRContext.is()) returnfalse;
Reference<Interface> pRXI(pRContext, UNO_QUERY); if (!pRXI.is()) returnfalse;
*ppXI = pRXI.get(); returntrue;
}
// Since there's no specific XInterface for table cells, this // method checks that the accessible's parent is a table // (implements XAccessibleTable) and pXAcc's context implements // XAccessibleComponent. bool queryTableCell(XAccessible* pXAcc, XInterface** ppXI)
{
XInterface* pXInterface = nullptr;
constbool bSupportsInterface = queryXInterface<XAccessibleComponent>(pXAcc, &pXInterface); if (!bSupportsInterface) returnfalse;
void lcl_addIA2State(AccessibleStates& rStates, sal_Int64 nUnoState, sal_Int16 nRole)
{ switch (nUnoState)
{ case css::accessibility::AccessibleStateType::ACTIVE:
rStates |= IA2_STATE_ACTIVE; break; case css::accessibility::AccessibleStateType::ARMED:
rStates |= IA2_STATE_ARMED; break; case css::accessibility::AccessibleStateType::CHECKABLE: // STATE_SYSTEM_PRESSED is used instead of STATE_SYSTEM_CHECKED for these button // roles (s. AccObject::GetMSAAStateFromUNO), so don't set CHECKABLE state for them if (nRole != AccessibleRole::PUSH_BUTTON && nRole != AccessibleRole::TOGGLE_BUTTON)
rStates |= IA2_STATE_CHECKABLE; break; case css::accessibility::AccessibleStateType::DEFUNC:
rStates |= IA2_STATE_DEFUNCT; break; case css::accessibility::AccessibleStateType::EDITABLE:
rStates |= IA2_STATE_EDITABLE; break; case css::accessibility::AccessibleStateType::HORIZONTAL:
rStates |= IA2_STATE_HORIZONTAL; break; case css::accessibility::AccessibleStateType::ICONIFIED:
rStates |= IA2_STATE_ICONIFIED; break; case css::accessibility::AccessibleStateType::MANAGES_DESCENDANTS:
rStates |= IA2_STATE_MANAGES_DESCENDANTS; break; case css::accessibility::AccessibleStateType::MODAL:
rStates |= IA2_STATE_MODAL; break; case css::accessibility::AccessibleStateType::MULTI_LINE:
rStates |= IA2_STATE_MULTI_LINE; break; case css::accessibility::AccessibleStateType::OPAQUE:
rStates |= IA2_STATE_OPAQUE; break; case css::accessibility::AccessibleStateType::SINGLE_LINE:
rStates |= IA2_STATE_SINGLE_LINE; break; case css::accessibility::AccessibleStateType::STALE:
rStates |= IA2_STATE_STALE; break; case css::accessibility::AccessibleStateType::TRANSIENT:
rStates |= IA2_STATE_TRANSIENT; break; case css::accessibility::AccessibleStateType::VERTICAL:
rStates |= IA2_STATE_VERTICAL; break; default: // no match break;
}
}
/** * Returns the Parent IAccessible interface pointer to AT. * It should add reference, and the client should release the component. * It should return E_FAIL when the parent point is null. * @param ppdispParent [in,out] used to return the parent interface point. * when the point is null, should return null. * @return S_OK if successful and E_FAIL if the m_pIParent is NULL.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accParent(IDispatch **ppdispParent)
{
SolarMutexGuard g;
/** * Returns child count of current COM object. * @param pcountChildren [in,out] used to return the children count. * @return S_OK if successful.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accChildCount(long *pcountChildren)
{
SolarMutexGuard g;
Reference<XAccessibleContext> const pRContext =
m_xAccessible->getAccessibleContext(); if( pRContext.is() )
{
sal_Int64 nChildCount = pRContext->getAccessibleChildCount(); if (nChildCount > std::numeric_limits<long>::max())
{ // return error code if child count exceeds max long value // (for Calc sheets which report all cells as children); // tdf#153131: Windows Speech Recognition and apparently some other // tools querying information via the a11y API seem to query all children unconditionally, // so returning a large number (like std::numeric_limits<long>::max) would cause a freeze
SAL_WARN("iacc2", "CMAccessible::get_accChildCount: Child count exceeds maximum long value"); return S_FALSE;
}
*pcountChildren = nChildCount;
}
return S_OK;
} catch(...) { return E_FAIL; }
}
/** * Returns child interface pointer for AT according to input child ID. * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, * the child ID specify child index from 0 to children count, 0 stands for object self. * @param ppdispChild, [in,out] use to return the child interface point. * @return S_OK if successful and S_FALSE if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accChild(VARIANT varChild, IDispatch **ppdispChild)
{
SolarMutexGuard g;
/** * Returns the accessible name of the current COM object self or its one child to AT. * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, * the child ID specify child index from 0 to children count, 0 stands for object self. * @param pszName, [in,out] use to return the name of the proper object. * @return S_OK if successful and S_FALSE if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accName(VARIANT varChild, BSTR *pszName)
{
SolarMutexGuard g;
/** * Returns the accessible value of the current COM object self or its one child to AT. * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, * the child ID specify child index from 0 to children count, 0 stands for object self. * @param pszValue, [in,out] use to return the value of the proper object. * @return S_OK if successful and S_FALSE if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accValue(VARIANT varChild, BSTR *pszValue)
{
SolarMutexGuard g;
/** * Returns the accessible description of the current COM object self or its one child to AT. * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, * the child ID specify child index from 0 to children count, 0 stands for object self. * @param pszDescription, [in,out] use to return the description of the proper object. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accDescription(VARIANT varChild, BSTR *pszDescription)
{
SolarMutexGuard g;
/** * Returns the accessible role of the current COM object self or its one child to AT. * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, * the child ID specify child index from 0 to children count, 0 stands for object self. * @param pvarRole, [in,out] use to return the role of the proper object. * @return S_OK if successful and S_FALSE if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accRole(VARIANT varChild, VARIANT *pvarRole)
{
SolarMutexGuard g;
/** * Returns the accessible state of the current COM object self or its one child to AT. * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, * the child ID specify child index from 0 to children count, 0 stands for object self. * @param pvarState, [in,out] use to return the state of the proper object. * @return S_OK if successful and S_FALSE if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accState(VARIANT varChild, VARIANT *pvarState)
{
SolarMutexGuard g;
/** * Returns the accessible helpString of the current COM object self or its one child to AT. * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, * the child ID specify child index from 0 to children count, 0 stands for object self. * @param pszHelp, [in,out] use to return the helpString of the proper object. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accHelp(VARIANT, BSTR *)
{ return E_NOTIMPL;
}
/** * Returns the accessible HelpTopic of the current COM object self or its one child to AT. * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, * the child ID specify child index from 0 to children count, 0 stands for object self. * @param pszHelpFile, [in,out] use to return the HelpTopic of the proper object. * @param pidTopic, use to return the HelpTopic ID of the proper object. * @return S_OK if successful and E_FAIL if failure. * Not implemented yet
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accHelpTopic(BSTR *, VARIANT, long *)
{ return E_NOTIMPL;
}
staticbool GetMnemonicChar( const OUString& aStr, sal_Unicode* wStr)
{ for (sal_Int32 i = 0;; i += 2) {
i = aStr.indexOf('~', i); if (i == -1 || i == aStr.getLength() - 1) { returnfalse;
} auto c = aStr[i + 1]; if (c != '~') {
*wStr = c; returntrue;
}
}
}
/** * Returns the accessible keyboard shortcut of the current COM object self or its one child to AT. * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, * the child ID specify child index from 0 to children count, 0 stands for object self. * @param pszKeyboardShortcut, [in,out] use to return the kbshortcut of the proper object. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accKeyboardShortcut(VARIANT varChild, BSTR *pszKeyboardShortcut)
{
SolarMutexGuard g;
/** * Returns the current focused child to AT. * @param pvarChild, [in,out] vt member of pvarChild must be VT_I4,and lVal member stores the child ID, * the child ID specify child index from 0 to children count, 0 stands for object self. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accFocus(VARIANT *pvarChild)
{
SolarMutexGuard g;
try { if (m_isDestroy) return S_FALSE;
if(pvarChild == nullptr)
{ return E_INVALIDARG;
} if( m_dFocusChildID==UACC_NO_FOCUS )
{
pvarChild->vt = VT_EMPTY;//no focus on the object and its children return S_OK;
} //if the descendant of current object has focus indicated by m_dFocusChildID, return the IDispatch of this focused object else
{
IMAccessible* pIMAcc = g_pAccObjectManager->GetIAccessibleFromResID(m_dFocusChildID); if (pIMAcc == nullptr)
{ return E_FAIL;
}
pIMAcc->AddRef();
pvarChild->vt = VT_DISPATCH;
pvarChild->pdispVal = pIMAcc;
} return S_OK;
} catch(...) { return E_FAIL; }
}
/** * Returns the selection of the current COM object to AT. * @param pvarChildren,[in,out] * if selection num is 0,return VT_EMPTY for vt, * if selection num is 1,return VT_I4 for vt,and child index for lVal * if selection num >1,return VT_UNKNOWN for vt, and IEnumVariant* for punkVal * @return S_OK if successful and S_FALSE if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accSelection(VARIANT *pvarChildren)
{
SolarMutexGuard g;
/** * Returns the location of the current COM object self or its one child to AT. * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, * the child ID specify child index from 0 to children count, 0 stands for object self. * @param pxLeft, [in,out] use to return the x-coordination of the proper object. * @param pyTop, [in,out] use to return the y-coordination of the proper object. * @param pcxWidth, [in,out] use to return the x-coordination width of the proper object. * @param pcyHeight, [in,out] use to return the y-coordination height of the proper object. * @return S_OK if successful and S_FALSE if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varChild)
{
SolarMutexGuard g;
/** * Returns the current focused child to AT. * @param navDir, the direction flag of the navigation. * @param varStart, the start child id of this navigation action. * @param pvarEndUpAt, [in,out] the end up child of this navigation action. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEndUpAt)
{
SolarMutexGuard g;
try { if (m_isDestroy) return S_FALSE;
if(pvarEndUpAt == nullptr)
{ return E_INVALIDARG;
}
HRESULT ret = E_FAIL; switch (navDir)
{ case NAVDIR_FIRSTCHILD:
ret = GetFirstChild(varStart,pvarEndUpAt); break; case NAVDIR_LASTCHILD:
ret = GetLastChild(varStart,pvarEndUpAt); break; case NAVDIR_NEXT:
ret = GetNextSibling(varStart,pvarEndUpAt); break; case NAVDIR_PREVIOUS:
ret = GetPreSibling(varStart,pvarEndUpAt); break; case NAVDIR_DOWN://do not implement temporarily break; case NAVDIR_UP://do not implement temporarily break; case NAVDIR_LEFT://do not implement temporarily break; case NAVDIR_RIGHT://do not implement temporarily break; default: break;
} return ret;
// convert from screen to object-local coordinates
css::awt::Point aTopLeft = xComponent->getLocationOnScreen();
css::awt::Point aPoint(xLeft - aTopLeft.X, yTop - aTopLeft.Y);
Reference<XAccessible> xAccAtPoint = xComponent->getAccessibleAtPoint(aPoint); if (!xAccAtPoint.is()) return S_FALSE;
IAccessible* pRet = get_IAccessibleFromXAccessible(xAccAtPoint.get()); if (!pRet)
{
g_pAccObjectManager->InsertAccObj(xAccAtPoint.get(), m_xAccessible.get(), m_hwnd);
pRet = get_IAccessibleFromXAccessible(xAccAtPoint.get());
} if (!pRet) return S_FALSE;
/** * Get The other Interface from CMAccessible. * @param guidService, must be IID_IAccessible here. * @param riid, the IID interface . * @return S_OK if successful and S_FALSE if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::QueryService(REFGUID guidService, REFIID riid, void** ppvObject)
{ if( InlineIsEqualGUID(guidService, IID_IAccessible) ) return QueryInterface(riid, ppvObject); return S_FALSE;
}
/** * No longer supported according to IAccessible doc. * Servers should return E_NOTIMPL
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::put_accName(VARIANT, BSTR)
{ return E_NOTIMPL;
}
/** * Set the accessible value of the current COM object self or its one child from UNO. * @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, * the child ID specify child index from 0 to children count, 0 stands for object self. * @param szValue, the value used to set the value of the proper object. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::put_accValue(VARIANT varChild, BSTR szValue)
{
SolarMutexGuard g;
/** * Set the accessible role of the current COM object self from UNO. * @param pRole, the role value used to set the role of the current object. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccRole(unsignedshort pRole)
{ // internal IMAccessible - no mutex meeded
m_iRole = pRole; return S_OK;
}
/** * Add one state into the current state set for the current COM object from UNO. * @param pXSate, the state used to set the name of the current object. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::DecreaseState(DWORD pXSate)
{ // internal IMAccessible - no mutex meeded
m_dState &= (~pXSate); return S_OK;
}
/** * Delete one state into the current state set for the current COM object from UNO. * @param pXSate, the state used to set the name of the current object. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::IncreaseState(DWORD pXSate)
{ // internal IMAccessible - no mutex meeded
m_dState |= pXSate; return S_OK;
}
/** * Set state into the current state set for the current COM object from UNO. * @param pXSate, the state used to set the name of the current object. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::SetState(DWORD pXSate)
{ // internal IMAccessible - no mutex meeded
m_dState = pXSate; return S_OK;
}
/** * Set the accessible value of the current COM object self from UNO. * @param pszAccValue, the name used to set the value of the current object. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccValue(const OLECHAR __RPC_FAR *pszAccValue)
{ // internal IMAccessible - no mutex meeded
/** * Set the HWND value of the current COM object self from UNO. It should set the parent IAccessible * Object through the method AccessibleObjectFromWindow(...). * @param hwnd, the HWND used to set the value of the current object. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccWindowHandle(HWND hwnd)
{ // internal IMAccessible - no mutex meeded
/** * Set accessible focus by specifying child ID * @param dChildID, the child id identifies the focus child. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccFocus(long dChildID)
{ // internal IMAccessible - no mutex meeded
try { if (m_isDestroy) return S_FALSE;
if(dChildID==CHILDID_SELF)
{ if(m_pIParent)
{
m_pIParent->Put_XAccFocus(m_dChildID);
}
} else
{
m_dFocusChildID = dChildID; //traverse all ancestors to set the focused child ID so that when the get_accFocus is called on //any of the ancestors, this id can be used to get the IAccessible of focused object. if(m_pIParent)
{
m_pIParent->Put_XAccFocus(dChildID);
}
} return S_OK;
} catch(...) { return E_FAIL; }
}
/** * Set accessible parent object for the current COM object if * the current object is a child of some COM object * @param pIParent, the parent of the current object. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccParent(IMAccessible __RPC_FAR *pIParent)
{ // internal IMAccessible - no mutex meeded
m_pIParent = pIParent;
if(pIParent)
m_pIParent->AddRef();
return S_OK;
}
/** * Set unique child id to COM * @param dChildID, the id of the current object. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccChildID(long dChildID)
{ // internal IMAccessible - no mutex meeded
m_dChildID = dChildID; return S_OK;
}
/** * Set AccObjectWinManager object pointer to COM * @param pManager, the AccObjectWinManager pointer. * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccObjectManager(hyper pManager)
{ // internal IMAccessible - no mutex meeded
/** * When a UNO control disposing, it disposes its listeners, * then notify AccObject in bridge management, then notify * COM that the XAccessible is invalid, so set m_xAccessible as NULL * @return S_OK if successful and E_FAIL if failure.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::NotifyDestroy()
{ // internal IMAccessible - no mutex meeded
/** * for descendantmanager circumstance,provide child interface when navigate * @param varCur, the current child. * @param eDirection, the navigation direction. * @return IMAccessible*, the child of the end up node.
*/
IMAccessible* CMAccessible::GetNavigateChildForDM(VARIANT varCur, NavigationDirection eDirection)
{
XAccessibleContext* pChildContext = GetContextByXAcc(pChildXAcc); if(pChildContext == nullptr)
{ return nullptr;
} const sal_Int64 delta = (eDirection == NavigationDirection::NEXT_CHILD) ? 1 : -1; //currently, getAccessibleIndexInParent is error in UNO for //some kind of List,such as ValueSet, the index will be less 1 than //what should be, need to fix UNO code const sal_Int64 index = pChildContext->getAccessibleIndexInParent() + delta; if((index>=0)&&(index<=count-1))
{
pRChildXAcc = pXContext->getAccessibleChild(index);
} break;
} default: break;
}
/** *the following 4 private methods are for accNavigate implementation
*/
/** * Return first child for parent container, process differently according * to whether it is descendant manage * @param varStart, the start child id of this navigation action. * @param pvarEndUpAt, [in,out] the end up child of this navigation action. * @return S_OK if successful and E_FAIL if failure.
*/
HRESULT CMAccessible::GetFirstChild(VARIANT varStart,VARIANT* pvarEndUpAt)
{
/** * Return last child for parent container, process differently according * to whether it is descendant manage * @param varStart, the start child id of this navigation action. * @param pvarEndUpAt, [in,out] the end up child of this navigation action. * @return S_OK if successful and E_FAIL if failure.
*/
HRESULT CMAccessible::GetLastChild(VARIANT varStart,VARIANT* pvarEndUpAt)
{
/** * The method GetNextSibling is general, whatever it is descendant manage or not * Get the next sibling object. * @param varStart, the start child id of this navigation action. * @param pvarEndUpAt, [in,out] the end up child of this navigation action. * @return S_OK if successful and E_FAIL if failure.
*/
HRESULT CMAccessible::GetNextSibling(VARIANT varStart,VARIANT* pvarEndUpAt)
{
/** *the method GetPreSibling is general, whatever it is descendant manage or not * @param varStart, the start child id of this navigation action. * @param pvarEndUpAt, [in,out] the end up child of this navigation action. * @return S_OK if successful and E_FAIL if failure.
*/
HRESULT CMAccessible::GetPreSibling(VARIANT varStart,VARIANT* pvarEndUpAt)
{
/** * Get XAccessibleContext directly from UNO by the stored XAccessible pointer * @param pXAcc, UNO XAccessible object point. * @return XAccessibleContext*, the context of the pXAcc.
*/
XAccessibleContext* CMAccessible::GetContextByXAcc( XAccessible* pXAcc )
{
Reference< XAccessibleContext > pRContext; if( pXAcc == nullptr) return nullptr;
/** * When COM is created, UNO set XAccessible pointer to it * in order to COM can operate UNO information * @param pXAcc, the XAccessible object of current object. * @return S_OK if successful.
*/
COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::SetXAccessible(hyper pXAcc)
{ // internal IMAccessible - no mutex meeded
/** * accSelect method has many optional flags, needs to process comprehensively * Mozilla and Microsoft do not implement SELFLAG_EXTENDSELECTION flag. * The implementation of this flag is a little trouble-shooting,so we also * do not implement it now
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ 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.20Bemerkung:
¤
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.