diff options
author | David Ostrovsky <david@ostrovsky.org> | 2013-11-02 15:22:17 +0100 |
---|---|---|
committer | David Ostrovsky <david@ostrovsky.org> | 2013-11-02 22:27:44 +0100 |
commit | cd3a8aa5b515112c2c651831c4f6d31e6c5318cb (patch) | |
tree | 7dfc64ab900893ed8ca7e3c6e08a8b9eb72c5a7d /winaccessibility/source/UAccCOM/MAccessible.cxx | |
parent | Add custom target to process IA2 COM idl files (diff) | |
download | core-cd3a8aa5b515112c2c651831c4f6d31e6c5318cb.tar.gz core-cd3a8aa5b515112c2c651831c4f6d31e6c5318cb.zip |
Rename the file to have cxx extension
Change-Id: I3b4f2d1de39c27066dc9573e6f22d1646c2eade2
Diffstat (limited to 'winaccessibility/source/UAccCOM/MAccessible.cxx')
-rw-r--r-- | winaccessibility/source/UAccCOM/MAccessible.cxx | 3262 |
1 files changed, 3262 insertions, 0 deletions
diff --git a/winaccessibility/source/UAccCOM/MAccessible.cxx b/winaccessibility/source/UAccCOM/MAccessible.cxx new file mode 100644 index 000000000000..6216ac393d41 --- /dev/null +++ b/winaccessibility/source/UAccCOM/MAccessible.cxx @@ -0,0 +1,3262 @@ +/************************************************************** + * + * 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 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + *************************************************************/ + +#include "stdafx.h" +#include "UAccCOM2.h" +#include "MAccessible.h" + +#include <algorithm> +#include "AccAction.h" + +#include <com/sun/star/accessibility/XAccessibleText.hpp> +#include <com/sun/star/accessibility/XAccessibleEditableText.hpp> +#include <com/sun/star/accessibility/XAccessibleImage.hpp> +#include <com/sun/star/accessibility/XAccessibleTable.hpp> +#include <com/sun/star/accessibility/XAccessibleExtendedComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp> +#include <com/sun/star/accessibility/XAccessibleHyperText.hpp> +#include <com/sun/star/accessibility/XAccessibleHyperlink.hpp> +#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/XAccessibleGroupPosition.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> +#include <com/sun/star/accessibility/XAccessibleExtendedAttributes.hpp> +#include <com/sun/star/style/LineSpacing.hpp> +#include <com/sun/star/style/TabStop.hpp> +#include <com/sun/star/container/XIndexReplace.hpp> + +#include "AccessibleRole.h" + + +using namespace com::sun::star::accessibility::AccessibleStateType; + +// IA2 states mapping, and name +// maintenance the consistency, change one array, change the three all +long IA2_STATES[] = + { + IA2_STATE_ACTIVE, // = 0x1; + IA2_STATE_ARMED, // = 0x2; + IA2_STATE_DEFUNCT, // = 0x4; + IA2_STATE_EDITABLE, // = 0x8; + IA2_STATE_HORIZONTAL, // = 0x10; + IA2_STATE_ICONIFIED, // = 0x20; + IA2_STATE_INVALID_ENTRY, // = 0x80; + IA2_STATE_MANAGES_DESCENDANTS, // = 0x100; + IA2_STATE_MODAL, // = 0x200; + IA2_STATE_MULTI_LINE, // = 0x400; + IA2_STATE_OPAQUE, // = 0x800; + IA2_STATE_REQUIRED, // = 0x2000; + IA2_STATE_SELECTABLE_TEXT, // = 0x3000; + IA2_STATE_SINGLE_LINE, // = 0x4000; + IA2_STATE_STALE, // = 0x8000; + IA2_STATE_SUPPORTS_AUTOCOMPLETION, // = 0x10000; + IA2_STATE_TRANSIENT, //= 0x20000; + IA2_STATE_VERTICAL // = 0x40000; + }; +/* + +<=== map ===> + +*/ +short UNO_STATES[] = + { + ACTIVE, // = (sal_Int16)1; + ARMED, // = (sal_Int16)2; + DEFUNC, // = (sal_Int16)5; + EDITABLE, // = (sal_Int16)6; + HORIZONTAL, // = (sal_Int16)12; + ICONIFIED, // = (sal_Int16)13; + -1, //IA2_STATE_INVALID_ENTRY + MANAGES_DESCENDANTS, // = (sal_Int16)15; + MODAL, // = (sal_Int16)16; + MULTI_LINE, // = (sal_Int16)17; + OPAQUE, // = (sal_Int16)19; + -1, //IA2_STATE_REQUIRED + -1, //IA2_STATE_SELECTABLE_TEXT + SINGLE_LINE, // = (sal_Int16)26; + STALE, // = (sal_Int16)27; + -1, //IA2_STATE_SUPPORTS_AUTOCOMPLETION + TRANSIENT, //IA2_STATE_TRANSIENT + VERTICAL // = (sal_Int16)29; + }; + +// <=== map ===> + +BSTR IA2_STATES_NAME[] = + { + _T("Active"), + _T("Armed"), + _T("Defunct"), + _T("Editable"), + _T("Horizontal"), + _T("Iconified"), + _T("Invalid Entry"), + _T("Manages Decendents"), + _T("Modal"), + _T("Multi Line"), + _T("Opaque"), + _T("Required"), + _T("Selectable Text"), + _T("Single Line"), + _T("Stale"), + _T("Supports Autocompletion"), + _T("Transient"), + _T("Vertical") + }; + +// IA2 states mapping, and name +// maintenance the consistency. change one, change them all + +BSTR UNO_ALL_STATES[] = + { + _T("INVALID"), // INVALID ( 0 ) + _T("ACTIVE"), // ACTIVE ( 1 ) + _T("ARMED"), // ARMED ( 2 ) + _T("BUSY"), // BUSY ( 3 ) + _T("CHECKED"), // CHECKED ( 4 ) + _T("DEFUNC"), // DEFUNC ( 5 ) + _T("EDITABLE"), // EDITABLE ( 6 ) + _T("ENABLED"), // ENABLED ( 7 ) + _T("EXPANDABLE"), // EXPANDABLE ( 8 ) + _T("EXPANDED"), // EXPANDED ( 9 ) + _T("FOCUSABLE"), // FOCUSABLE ( 10 ) + _T("FOCUSED"), // FOCUSED ( 11 ) + _T("HORIZONTAL"), // HORIZONTAL ( 12 ) + _T("ICONIFIED"), // ICONIFIED ( 13 ) + _T("INDETERMINATE"), // INDETERMINATE ( 14 ) + _T("MANAGES_DESCENDANTS"),// MANAGES_DESCENDANTS ( 15 ) + _T("MODAL"), // MODAL ( 16 ) + _T("MULTI_LINE"), // MULTI_LINE ( 17 ) + _T("MULTI_SELECTABLE"), // MULTI_SELECTABLE ( 18 ) + _T("OPAQUE"), // OPAQUE ( 19 ) + _T("PRESSED"), // PRESSED ( 20 ) + _T("RESIZABLE"), // RESIZABLE ( 21 ) + _T("SELECTABLE"), // SELECTABLE ( 22 ) + _T("SELECTED"), // SELECTED ( 23 ) + _T("SENSITIVE"), // SENSITIVE ( 24 ) + _T("SHOWING"), // SHOWING ( 25 ) + _T("SINGLE_LINE"), // SINGLE_LINE ( 26 ) + _T("STALE"), // STALE ( 27 ) + _T("TRANSIENT"), // TRANSIENT ( 28 ) + _T("VERTICAL"), // VERTICAL ( 29 ) + _T("VISIBLE"), // VISIBLE ( 30 ) + _T("MOVEABLE"), // MOVEABLE ( 31 ) + _T("OFFSCREEN"), // OFFSCREEN ( 32 ) + _T("COLLAPSE"), // COLLAPSE ( 33 ) + _T("DEFAULT") // DEFAULT ( 34 ) + }; + + +using namespace com::sun::star::accessibility::AccessibleRole; + + + +#define QUERYXINTERFACE(ainterface) \ +{ \ + if(pXAcc == NULL) \ + return FALSE; \ + pRContext = pXAcc->getAccessibleContext(); \ + if( !pRContext.is() ) \ + { \ + return FALSE; \ + } \ + Reference<X##ainterface> pRXI(pRContext,UNO_QUERY);\ + if( !pRXI.is() ) \ + { \ + return FALSE; \ + } \ + *ppXI = (XInterface*)pRXI.get(); \ + return TRUE; \ +} + +#define ISDESTROY() \ + if(m_isDestroy) \ + return S_FALSE; + + +AccObjectManagerAgent* CMAccessible::g_pAgent = NULL; + +CMAccessible::CMAccessible(): + m_iRole(0x00), + m_dState(0x00), + m_dChildID(0x00), + m_dFocusChildID(UACC_NO_FOCUS), + m_hwnd(NULL), + m_pIParent(NULL), + m_pszName(NULL), + m_pszValue(NULL), + m_pszDescription(NULL), + m_isDestroy(FALSE), + m_pszActionDescription(NULL), + m_pXAction(NULL), + m_bRequiresSave(FALSE), + pUNOInterface(NULL) +{ + m_sLocation.m_dLeft=0; + m_sLocation.m_dTop = 0; + m_sLocation.m_dWidth=0; + m_sLocation.m_dHeight=0; + CEnumVariant::Create(&m_pEnumVar); +} + +CMAccessible::~CMAccessible() +{ + if(m_pszName!=NULL) + { + SAFE_SYSFREESTRING(m_pszName); + m_pszName=NULL; + } + if(m_pszValue!=NULL) + { + SAFE_SYSFREESTRING(m_pszValue); + m_pszValue=NULL; + } + if(m_pszDescription!=NULL) + { + SAFE_SYSFREESTRING(m_pszDescription); + m_pszDescription=NULL; + } + + if(m_pszActionDescription!=NULL) + { + SAFE_SYSFREESTRING(m_pszActionDescription); + m_pszActionDescription=NULL; + } + + if(m_pIParent) + { + m_pIParent->Release(); + m_pIParent=NULL; + } + pRef = NULL; + m_pEnumVar->Release(); + m_containedObjects.clear(); + pRContext = NULL; +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::get_accParent(IDispatch **ppdispParent) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(ppdispParent == NULL) + { + return E_INVALIDARG; + } + + if(m_pIParent) + { + *ppdispParent = m_pIParent; + (*ppdispParent)->AddRef(); + return S_OK; + } + else if(m_hwnd) + { + HRESULT hr = AccessibleObjectFromWindow(m_hwnd, OBJID_WINDOW, IID_IAccessible, (void**)ppdispParent); + if( ! SUCCEEDED( hr ) || ! ppdispParent ) + { + return S_FALSE; + } + return S_OK; + } + return S_FALSE; + + LEAVE_PROTECTED_BLOCK +} + +/** +* Returns child count of current COM object. +* @param pcountChildren [in,out] used to return the children count. +* @return S_OK if successful. +*/ +STDMETHODIMP CMAccessible::get_accChildCount(long *pcountChildren) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pcountChildren == NULL) + { + return E_INVALIDARG; + } + + if(!pUNOInterface) + return S_FALSE; + + Reference< XAccessibleContext > pRContext = pUNOInterface->getAccessibleContext(); + if( pRContext.is() ) + { + *pcountChildren = pRContext->getAccessibleChildCount(); + } + + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::get_accChild(VARIANT varChild, IDispatch **ppdispChild) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(ppdispChild == NULL) + { + return E_INVALIDARG; + } + if(varChild.vt==VT_I4) + { + //get child interface pointer due to child ID + if(varChild.lVal==CHILDID_SELF) + { + AddRef(); + *ppdispChild = this; + return S_OK; + } + *ppdispChild = GetChildInterface(varChild.lVal); + (*ppdispChild)->AddRef(); + return (*ppdispChild)?S_OK:S_FALSE; + } + return S_FALSE; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::get_accName(VARIANT varChild, BSTR *pszName) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pszName == NULL) + { + return E_INVALIDARG; + } + if(varChild.vt==VT_I4) + { + if(varChild.lVal==CHILDID_SELF) + { + SAFE_SYSFREESTRING(*pszName); + *pszName = SysAllocString(m_pszName); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->get_accName(varChild,pszName); + } + return S_FALSE; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::get_accValue(VARIANT varChild, BSTR *pszValue) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if( pszValue == NULL ) + { + return E_INVALIDARG; + } + if( varChild.vt==VT_I4 ) + { + if(varChild.lVal==CHILDID_SELF) + { + if(m_dState & STATE_SYSTEM_PROTECTED) + return E_ACCESSDENIED; + + if ( m_pszValue !=NULL && wcslen(m_pszValue) == 0 ) + return S_OK; + + SAFE_SYSFREESTRING(*pszValue); + *pszValue = SysAllocString(m_pszValue); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->get_accValue(varChild,pszValue); + } + return S_FALSE; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::get_accDescription(VARIANT varChild, BSTR *pszDescription) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pszDescription == NULL) + { + return E_INVALIDARG; + } + if(varChild.vt==VT_I4) + { + if(varChild.lVal==CHILDID_SELF) + { + SAFE_SYSFREESTRING(*pszDescription); + *pszDescription = SysAllocString(m_pszDescription); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->get_accDescription(varChild,pszDescription); + } + return S_FALSE; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::get_accRole(VARIANT varChild, VARIANT *pvarRole) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pvarRole == NULL) + { + return E_INVALIDARG; + } + if(varChild.vt == VT_I4) + { + + if(varChild.lVal == CHILDID_SELF) + { + if( m_iRole < IA2_ROLE_CAPTION ) + { + VariantInit(pvarRole); + pvarRole->vt = VT_I4; + pvarRole->lVal = m_iRole; + } + else + { + VariantInit(pvarRole); + pvarRole->vt = VT_I4; + pvarRole->lVal = ROLE_SYSTEM_CLIENT; + } + return S_OK; + } + + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->get_accRole(varChild,pvarRole); + } + return S_FALSE; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::get_accState(VARIANT varChild, VARIANT *pvarState) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pvarState == NULL) + { + return E_INVALIDARG; + } + if(varChild.vt==VT_I4) + { + if(varChild.lVal == CHILDID_SELF) + { + if(pUNOInterface) + { + Reference< XAccessibleContext > pContext = pUNOInterface->getAccessibleContext(); + if(pContext.is()) + { + // add the STATE_SYSTEM_LINKED state + Reference< XAccessibleHypertext > pRHypertext(pContext,UNO_QUERY); + if(pRHypertext.is()) + { + if( pRHypertext->getHyperLinkCount() > 0 ) + m_dState |= STATE_SYSTEM_LINKED; + else + m_dState &= ~STATE_SYSTEM_LINKED; + } + else + m_dState &= ~STATE_SYSTEM_LINKED; + } + } + + VariantInit(pvarState); + pvarState->vt = VT_I4; + pvarState->lVal = m_dState; + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->get_accState(varChild,pvarState); + } + return S_FALSE; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +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 +*/ +STDMETHODIMP CMAccessible::get_accHelpTopic(BSTR *, VARIANT, long *) +{ + return E_NOTIMPL; +} + +static void GetMnemonicChar( const ::rtl::OUString& aStr, WCHAR* wStr) +{ + int nLen = aStr.pData->length; + int i = 0; + WCHAR* text = aStr.pData->buffer; + + while ( i < nLen ) + { + if ( text[i] == L'~' ) + if ( text[i+1] != L'~' ) + { + wStr[0] = text[i+1]; + break; + } + i++; + } +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::get_accKeyboardShortcut(VARIANT varChild, BSTR *pszKeyboardShortcut) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + + ISDESTROY() + // #CHECK# + if(pszKeyboardShortcut == NULL) + { + return E_INVALIDARG; + } + + if(varChild.vt==VT_I4) + { + if(varChild.lVal == CHILDID_SELF) + { + if( pUNOInterface ) + { + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if( !pRContext.is() ) + return S_FALSE; + + Reference<XAccessibleAction> pRXI(pRContext,UNO_QUERY); + + OLECHAR wString[64]={0}; + + if( pRXI.is() && pRXI->getAccessibleActionCount() >= 1) + { + Reference< XAccessibleKeyBinding > binding = pRXI->getAccessibleActionKeyBinding(0); + if( binding.is() ) + { + long nCount = binding->getAccessibleKeyBindingCount(); + if(nCount >= 1) + { + CAccAction::GetkeyBindingStrByXkeyBinding( binding->getAccessibleKeyBinding(0),wString ); + } + } + } + if(wString[0] == 0) + { + Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet(); + if(!pRrelationSet.is()) + { + return S_FALSE; + } + + long nRelCount = pRrelationSet->getRelationCount(); + + // Modified by Steve Yin, for SODC_1552 + if( /*nRelCount <= 0 &&*/ m_iRole == ROLE_SYSTEM_TEXT ) + { + VARIANT varParentRole; + VariantInit( &varParentRole ); + + m_pIParent->get_accRole(varChild, &varParentRole); + + if( m_pIParent && varParentRole.lVal == ROLE_SYSTEM_COMBOBOX ) // edit in comoboBox + { + m_pIParent->get_accKeyboardShortcut(varChild, pszKeyboardShortcut); + return S_OK; + } + } + + AccessibleRelation *paccRelation = NULL; + AccessibleRelation accRelation; + for(int i=0; i<nRelCount ; i++) + { + if( pRrelationSet->getRelation(i).RelationType == 6 ) + { + accRelation = pRrelationSet->getRelation(i); + paccRelation = &accRelation; + } + } + + if(paccRelation == NULL) + return S_FALSE; + + Sequence< Reference< XInterface > > xTargets = paccRelation->TargetSet; + Reference<XInterface> pRAcc = xTargets[0]; + + XAccessible* pXAcc = (XAccessible*)pRAcc.get(); + + Reference<XAccessibleContext> pRLebelContext = pXAcc->getAccessibleContext(); + if(!pRLebelContext.is()) + return S_FALSE; + + pRrelationSet = pRLebelContext->getAccessibleRelationSet(); + nRelCount = pRrelationSet->getRelationCount(); + + paccRelation = NULL; + for(int j=0; j<nRelCount ; j++) + { + if( pRrelationSet->getRelation(j).RelationType == 5 ) + { + accRelation = pRrelationSet->getRelation(j); + paccRelation = &accRelation; + } + } + + if(paccRelation) + { + xTargets = paccRelation->TargetSet; + pRAcc = xTargets[0]; + if(pUNOInterface != (XAccessible*)pRAcc.get()) + return S_FALSE; + } + + Reference<XAccessibleExtendedComponent> pRXIE(pRLebelContext,UNO_QUERY); + if(!pRXIE.is()) + return S_FALSE; + + ::rtl::OUString ouStr = pRXIE->getTitledBorderText(); + WCHAR key[2] = {NULL}; + GetMnemonicChar(ouStr, key); + if(key[0] != 0) + { + wcscat(wString, L"Alt+"); + wcscat(wString, key); + } + else + return S_FALSE; + } + + SAFE_SYSFREESTRING(*pszKeyboardShortcut); + *pszKeyboardShortcut = SysAllocString(wString); + + return S_OK; + } + else + { + return S_FALSE; + } + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + + return pChild->get_accKeyboardShortcut(varChild,pszKeyboardShortcut); + } + return S_FALSE; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::get_accFocus(VARIANT *pvarChild) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pvarChild == NULL) + { + 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 = NULL; + g_pAgent->GetIAccessibleFromResID(m_dFocusChildID,&pIMAcc); + pIMAcc->AddRef(); + pvarChild->vt = VT_DISPATCH; + pvarChild->pdispVal = pIMAcc; + + } + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::get_accSelection(VARIANT *pvarChildren) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pvarChildren == NULL) + { + return E_INVALIDARG; + } + switch(m_pEnumVar->GetCountOfElements()) + { + case 0: + pvarChildren->vt = VT_EMPTY; + break; + case 1: + VARIANT varTmp[1]; + ULONG count; + VariantInit(&varTmp[0]); + m_pEnumVar->Next(1,varTmp,&count); + if(count!=1) + return S_FALSE; + pvarChildren->vt = VT_I4; + pvarChildren->lVal = varTmp[0].lVal; + VariantClear(&varTmp[0]); + m_pEnumVar->Reset(); + break; + default: + pvarChildren->vt = VT_UNKNOWN; + m_pEnumVar->AddRef(); + pvarChildren->punkVal = m_pEnumVar; + break; + } + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varChild) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pxLeft == NULL || pyTop == NULL || pcxWidth == NULL || pcyHeight == NULL) + { + return E_INVALIDARG; + } + + if(varChild.vt==VT_I4) + { + if(varChild.lVal==CHILDID_SELF) + { + + if(pUNOInterface) + { + Reference< XAccessibleContext > pRContext = pUNOInterface->getAccessibleContext(); + if( !pRContext.is() ) + return S_FALSE; + Reference< XAccessibleComponent > pRComponent(pRContext,UNO_QUERY); + if( !pRComponent.is() ) + return S_FALSE; + + ::com::sun::star::awt::Point pCPoint = pRComponent->getLocationOnScreen(); + ::com::sun::star::awt::Size pCSize = pRComponent->getSize(); + *pxLeft = pCPoint.X; + *pyTop = pCPoint.Y; + *pcxWidth = pCSize.Width; + *pcyHeight = pCSize.Height; + return S_OK; + } + else + { + *pxLeft = m_sLocation.m_dLeft; + *pyTop = m_sLocation.m_dTop; + *pcxWidth = m_sLocation.m_dWidth; + *pcyHeight = m_sLocation.m_dHeight; + return S_OK; + } + } + + } + return S_FALSE; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEndUpAt) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pvarEndUpAt == NULL) + { + 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; + + LEAVE_PROTECTED_BLOCK +} + +STDMETHODIMP CMAccessible::accHitTest(long xLeft, long yTop, VARIANT *pvarChild) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pvarChild == NULL) + { + return E_INVALIDARG; + } + long x, y, w, h; + VARIANT varSelf; + VariantInit(&varSelf); + varSelf.vt = VT_I4; + varSelf.lVal = CHILDID_SELF; + accLocation(&x,&y,&w,&h,varSelf); + if( (x < xLeft && (x + w) >xLeft) && (y < yTop && (y + h) >yTop) ) + { + int i, nCount; + pvarChild->vt = VT_EMPTY; + Reference< XAccessibleContext > pRContext = GetContextByXAcc(pUNOInterface); + nCount = pRContext->getAccessibleChildCount(); + if(nCount > 256) + return E_FAIL; + IMAccessible* child = NULL; + for( i = 0; i<nCount; i++) + { + + child = GetChildInterface(i + 1); + if(child && child->accHitTest(xLeft,yTop,pvarChild) == S_OK) + break; + } + + if(pvarChild->vt == VT_DISPATCH) + return S_OK; + + if( i < nCount) + { + pvarChild->vt = VT_DISPATCH; + pvarChild->pdispVal = child; + child->AddRef(); + } + else + { + pvarChild->vt = VT_I4; + pvarChild->lVal = CHILDID_SELF; + } + return S_OK; + } + return S_FALSE; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::QueryService(REFGUID guidService, REFIID riid, void** ppvObject) +{ + if( InlineIsEqualGUID(guidService, IID_IAccessible) ) + return QueryInterface(riid, ppvObject); + return S_FALSE; +} + +/** +* Set the accessible name 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 szName, the name used to set the name of the proper object. +* @return S_OK if successful and E_FAIL if failure. +*/ +STDMETHODIMP CMAccessible::put_accName(VARIANT varChild, BSTR szName) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + if(varChild.vt==VT_I4) + { + if(varChild.lVal==CHILDID_SELF) + { + SAFE_SYSFREESTRING(m_pszName); + m_pszName=SysAllocString(szName); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->put_accName(varChild,szName); + } + return E_FAIL; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::put_accValue(VARIANT varChild, BSTR szValue) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + if(varChild.vt==VT_I4) + { + if(varChild.lVal==CHILDID_SELF) + { + SysAllocString(m_pszValue); + m_pszValue=SysAllocString(szValue); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->put_accValue(varChild,szValue); + } + return E_FAIL; + + LEAVE_PROTECTED_BLOCK +} + +/** +* Set the accessible name of the current COM object self from UNO. +* @param pszName, the name value used to set the name of the current object. +* @return S_OK if successful and E_FAIL if failure. +*/ +STDMETHODIMP CMAccessible::Put_XAccName(const OLECHAR __RPC_FAR *pszName) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pszName == NULL) + { + return E_INVALIDARG; + } + + SAFE_SYSFREESTRING(m_pszName);//?? + m_pszName = SysAllocString(pszName); + if(m_pszName==NULL) + return E_FAIL; + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::Put_XAccRole(unsigned short pRole) +{ + 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. +*/ +STDMETHODIMP CMAccessible::DecreaseState(DWORD pXSate) +{ + 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. +*/ +STDMETHODIMP CMAccessible::IncreaseState(DWORD pXSate) +{ + 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. +*/ +STDMETHODIMP CMAccessible::SetState(DWORD pXSate) +{ + m_dState = pXSate; + return S_OK; +} + + + +/** +* Set the accessible description of the current COM object self from UNO. +* @param pszDescription, the name used to set the description of the current object. +* @return S_OK if successful and E_FAIL if failure. +*/ +STDMETHODIMP CMAccessible::Put_XAccDescription(const OLECHAR __RPC_FAR *pszDescription) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pszDescription == NULL) + { + return E_INVALIDARG; + } + + SAFE_SYSFREESTRING(m_pszDescription); + m_pszDescription = SysAllocString(pszDescription); + + if(m_pszDescription==NULL) + return E_FAIL; + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::Put_XAccValue(const OLECHAR __RPC_FAR *pszAccValue) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pszAccValue == NULL) + { + return E_INVALIDARG; + } + SAFE_SYSFREESTRING(m_pszValue); + m_pszValue = SysAllocString(pszAccValue); + if(m_pszValue==NULL) + return E_FAIL; + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::Put_XAccWindowHandle(HWND hwnd) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + m_hwnd = hwnd; + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** +* 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. +*/ +STDMETHODIMP CMAccessible::Put_XAccFocus(long dChildID) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + + 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; + + LEAVE_PROTECTED_BLOCK +} + +/** + *Set accessible object location for the current COM object + * @param sLocation, the location of the current object. + * @return S_OK if successful and E_FAIL if failure. + */ +STDMETHODIMP CMAccessible::Put_XAccLocation(const Location sLocation) +{ + + this->m_sLocation = sLocation; + return S_OK; +} + +/** + * 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. + */ +STDMETHODIMP CMAccessible::Put_XAccParent(IMAccessible __RPC_FAR *pIParent) +{ + this->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. + */ +STDMETHODIMP CMAccessible::Put_XAccChildID(long dChildID) +{ + + this->m_dChildID = dChildID; + return S_OK; +} + +/** + * Set AccObjectManagerAgent object pointer to COM + * @param pAgent, the AccObjectManagerAgent point. + * @return S_OK if successful and E_FAIL if failure. + */ +STDMETHODIMP CMAccessible::Put_XAccAgent(long pAgent) +{ + g_pAgent = (AccObjectManagerAgent*)pAgent; + return S_OK; +} + +/** + * 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 pUNOInterface as NULL + * @param isDestroy, true is it need to be destroyed. + * @return S_OK if successful and E_FAIL if failure. + */ +STDMETHODIMP CMAccessible::NotifyDestroy(BOOL isDestroy) +{ + + m_isDestroy = isDestroy; + pUNOInterface = NULL; + return S_OK; +} + +/** + *private methods that help implement public functions + */ + +/** + * Return child interface pointer by child ID,note: need to call AddRef() + * @param lChildID, specify child index,which AT(such as Inspect32) gives. + * @return IMAccessible*, pointer to the corresponding child object. + */ +IMAccessible* CMAccessible::GetChildInterface(long dChildID)//for test +{ + + long dChildIndex = 0; + if(dChildID<0) + { + if(g_pAgent) + { + IMAccessible* pIMAcc = NULL; + g_pAgent->GetIAccessibleFromResID(dChildID,&pIMAcc); + return pIMAcc; + } + return NULL; + } + else + { + Reference< XAccessibleContext > pRContext = pUNOInterface->getAccessibleContext(); + if( !pRContext.is() ) + return NULL; + + if(dChildID<1 || dChildID>pRContext->getAccessibleChildCount()) + return NULL; + + IAccessible* pChild = NULL; + Reference< XAccessible > pXChild = pRContext->getAccessibleChild(dChildID-1); + BOOL isGet = get_IAccessibleFromXAccessible((long)pXChild.get(),&pChild); + + if(!isGet) + { + g_pAgent->InsertAccObj(pXChild.get(),pUNOInterface,(long)m_hwnd); + isGet = get_IAccessibleFromXAccessible((long)pXChild.get(),&pChild); + } + + if(isGet) + { + IMAccessible* pIMAcc = (IMAccessible*)pChild; + return pIMAcc; + } + } + + return NULL; +} + +/** + * For List, tree and table,these roles belong to manage_decendant in UNO, + * need to process specifically when navigate + * @return BOOL, if it is decendantmanager, return true. + */ +BOOL CMAccessible::IsDecendantManage() +{ + + return (m_iRole==ROLE_SYSTEM_LIST)||(m_iRole==ROLE_SYSTEM_OUTLINE)||(m_iRole==ROLE_SYSTEM_TABLE); +} + +/** + * for decendantmanager circumstance,provide child interface when navigate + * @param varCur, the current child. + * @param flags, the navigation direction. + * @return IMAccessible*, the child of the end up node. + */ +IMAccessible* CMAccessible::GetNavigateChildForDM(VARIANT varCur, short flags) +{ + + XAccessibleContext* pXContext = GetContextByXAcc(pUNOInterface); + if(pXContext==NULL) + { + return NULL; + } + + int count = pXContext->getAccessibleChildCount(); + if(count<1) + { + return NULL; + } + + IMAccessible* pCurChild = NULL; + XAccessible* pChildXAcc = NULL; + Reference<XAccessible> pRChildXAcc; + XAccessibleContext* pChildContext = NULL; + int index = 0,delta=0; + switch(flags) + { + case DM_FIRSTCHILD: + pRChildXAcc = pXContext->getAccessibleChild(0); + break; + case DM_LASTCHILD: + pRChildXAcc = pXContext->getAccessibleChild(count-1); + break; + case DM_NEXTCHILD: + case DM_PREVCHILD: + pCurChild = GetChildInterface(varCur.lVal); + if(pCurChild==NULL) + { + return NULL; + } + pCurChild->GetUNOInterface((long*)&pChildXAcc); + if(pChildXAcc==NULL) + { + return NULL; + } + pChildContext = GetContextByXAcc(pChildXAcc); + if(pChildContext == NULL) + { + return NULL; + } + delta = (flags==DM_NEXTCHILD)?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 + index = pChildContext->getAccessibleIndexInParent()+delta; + if((index>=0)&&(index<=count-1)) + { + pRChildXAcc = pXContext->getAccessibleChild(index); + } + break; + default: + break; + } + + if(!pRChildXAcc.is()) + { + return NULL; + } + pChildXAcc = pRChildXAcc.get(); + g_pAgent->InsertAccObj(pChildXAcc,pUNOInterface); + return g_pAgent->GetIMAccByXAcc(pChildXAcc); +} + +/** + *the following 4 private methods are for accNavigate implementation + */ + +/** + * Return first child for parent container, process differently according + * to whether it is decendant 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) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pvarEndUpAt == NULL) + { + return E_INVALIDARG; + } + if(varStart.vt != VT_I4) + { + pvarEndUpAt->vt = VT_EMPTY; + return E_INVALIDARG; + } + + pvarEndUpAt->pdispVal = GetNavigateChildForDM(varStart, DM_FIRSTCHILD); + if(pvarEndUpAt->pdispVal) + { + pvarEndUpAt->pdispVal->AddRef(); + pvarEndUpAt->vt = VT_DISPATCH; + return S_OK; + } + + pvarEndUpAt->vt = VT_EMPTY; + return E_FAIL; + + LEAVE_PROTECTED_BLOCK +} + +/** + * Return last child for parent container, process differently according + * to whether it is decendant 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) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pvarEndUpAt == NULL) + { + return E_INVALIDARG; + } + if(varStart.vt != VT_I4) + { + pvarEndUpAt->vt = VT_EMPTY; + return E_INVALIDARG; + } + + pvarEndUpAt->pdispVal = GetNavigateChildForDM(varStart, DM_LASTCHILD); + if(pvarEndUpAt->pdispVal) + { + pvarEndUpAt->pdispVal->AddRef(); + pvarEndUpAt->vt = VT_DISPATCH; + return S_OK; + } + pvarEndUpAt->vt = VT_EMPTY; + return E_FAIL; + + LEAVE_PROTECTED_BLOCK +} + +/** + * The method GetNextSibling is general, whatever it is decendant 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) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + if(varStart.vt != VT_I4) + { + pvarEndUpAt->vt = VT_EMPTY; + return E_INVALIDARG; + } + + Reference< XAccessibleContext > pRContext = GetContextByXAcc(pUNOInterface); + if(pRContext.is()) + { + varStart.iVal = sal_Int16(pRContext->getAccessibleIndexInParent() + 2); + if(m_pIParent) + if( m_pIParent->get_accChild(varStart,&pvarEndUpAt->pdispVal) == S_OK) + { + pvarEndUpAt->vt = VT_DISPATCH; + return S_OK; + } + } + pvarEndUpAt->vt = VT_EMPTY; + return E_FAIL; + + LEAVE_PROTECTED_BLOCK +} + +/** + *the method GetPreSibling is general, whatever it is decendant 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) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pvarEndUpAt == NULL) + { + return E_INVALIDARG; + } + if(varStart.vt != VT_I4) + { + pvarEndUpAt->vt = VT_EMPTY; + return E_INVALIDARG; + } + + Reference< XAccessibleContext > pRContext = GetContextByXAcc(pUNOInterface); + if(pRContext.is()) + { + varStart.iVal = sal_Int16(pRContext->getAccessibleIndexInParent()); + if(m_pIParent && varStart.iVal > 0) + if( m_pIParent->get_accChild(varStart,&pvarEndUpAt->pdispVal) == S_OK) + { + pvarEndUpAt->vt = VT_DISPATCH; + return S_OK; + } + } + pvarEndUpAt->vt = VT_EMPTY; + return E_FAIL; + + LEAVE_PROTECTED_BLOCK +} + +/** + * For IAccessible2 implementation methods + */ +STDMETHODIMP CMAccessible::get_nRelations( long __RPC_FAR *nRelations) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + + // #CHECK# + if(nRelations == NULL) + { + return E_INVALIDARG; + } + + *nRelations = 0; + + if( !pRContext.is() ) + return E_FAIL; + Reference<XAccessibleRelationSet> pRrelationSet = pRContext.get()->getAccessibleRelationSet(); + if(!pRrelationSet.is()) + { + *nRelations = 0; + return S_OK; + } + + *nRelations = pRrelationSet->getRelationCount(); + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +STDMETHODIMP CMAccessible::get_relation( long relationIndex, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(relation == NULL) + { + return E_INVALIDARG; + } + + if( !pRContext.is() ) + return E_FAIL; + + + long nMax = 0; + long nReal = 0; + get_nRelations(&nMax); + + *relation = (IAccessibleRelation*)::CoTaskMemAlloc(sizeof(IAccessibleRelation)); + + // #CHECK Memory Allocation# + if(*relation == NULL) + { + return E_FAIL; + } + + if( relationIndex < nMax ) + { + + + Reference<XAccessibleRelationSet> pRrelationSet = pRContext.get()->getAccessibleRelationSet(); + if(!pRrelationSet.is()) + { + + return E_FAIL; + } + + IAccessibleRelation* pRelation = NULL; + HRESULT hr = CoCreateInstance( CLSID_AccRelation, NULL, CLSCTX_SERVER , + IID_IAccessibleRelation, + (void **)&pRelation); + if(SUCCEEDED(hr)) + { + IUNOXWrapper* wrapper = NULL; + hr = pRelation->QueryInterface(IID_IUNOXWrapper, (void**)&wrapper); + if(SUCCEEDED(hr)) + { + AccessibleRelation accRelation = pRrelationSet->getRelation(relationIndex); + wrapper->put_XSubInterface((long)&accRelation); + wrapper->Release(); + *relation = pRelation; + return S_OK; + } + + } + } + + return E_FAIL; + + LEAVE_PROTECTED_BLOCK +} + +STDMETHODIMP CMAccessible::get_relations( long, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation, long __RPC_FAR *nRelations) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + + // #CHECK# + if(relation == NULL || nRelations == NULL) + { + return E_INVALIDARG; + } + // #CHECK XInterface# + + if( !pRContext.is() ) + return E_FAIL; + + Reference<XAccessibleRelationSet> pRrelationSet = pRContext.get()->getAccessibleRelationSet(); + if(!pRrelationSet.is()) + { + *nRelations = 0; + return S_OK; + } + + long nCount = pRrelationSet->getRelationCount(); + + *relation = (IAccessibleRelation*)::CoTaskMemAlloc(nCount*sizeof(IAccessibleRelation)); + + // #CHECK Memory Allocation# + if(*relation == NULL) + { + return E_FAIL; + } + + for(int i=0; i<nCount ; i++) + { + IAccessibleRelation* pRelation = NULL; + HRESULT hr = CoCreateInstance( CLSID_AccRelation, NULL, CLSCTX_SERVER , + IID_IAccessibleRelation, + (void **)&pRelation); + if(SUCCEEDED(hr)) + { + IUNOXWrapper* wrapper = NULL; + hr = pRelation->QueryInterface(IID_IUNOXWrapper, (void**)&wrapper); + if(SUCCEEDED(hr)) + { + AccessibleRelation accRelation = pRrelationSet->getRelation(i); + wrapper->put_XSubInterface((long)&accRelation); + wrapper->Release(); + } + (relation)[i] = pRelation; + } + } + + *nRelations = nCount; + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +STDMETHODIMP CMAccessible::role(long __RPC_FAR *role) +{ + ENTER_PROTECTED_BLOCK + + (*role) = m_iRole; + + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + + +STDMETHODIMP CMAccessible:: get_nActions(long __RPC_FAR *nActions) +{ + + try + { + ISDESTROY() + // #CHECK# + if(nActions == NULL) + { + return E_INVALIDARG; + } + *nActions = 0L; + IAccessibleAction* pAcc = NULL; + HRESULT hr = QueryInterface(IID_IAccessibleAction, (void**)&pAcc); + if( hr == S_OK ) + { + pAcc->nActions(nActions); + pAcc->Release(); + } + + return S_OK; + } + catch(...) + { + *nActions = 0L; + return S_OK; + } +} + + +STDMETHODIMP CMAccessible:: scrollToPoint(enum IA2CoordinateType, long, long) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + return E_NOTIMPL; + LEAVE_PROTECTED_BLOCK + +} +STDMETHODIMP CMAccessible:: scrollTo(enum IA2ScrollType) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + + return E_NOTIMPL; + + LEAVE_PROTECTED_BLOCK +} + +static XAccessible* getTheParentOfMember(XAccessible* pXAcc) +{ + // #CHECK# + if(pXAcc == NULL) + { + return NULL; + } + Reference<XAccessibleContext> pRContext = pXAcc->getAccessibleContext(); + Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet(); + long nRelations = pRrelationSet->getRelationCount(); + for(int i=0 ; i<nRelations ; i++) + { + AccessibleRelation accRelation = pRrelationSet->getRelation(i); + if(accRelation.RelationType == 7) + { + Sequence< Reference< XInterface > > xTargets = accRelation.TargetSet; + return (XAccessible*)xTargets[0].get(); + } + } + return NULL; +} + +STDMETHODIMP CMAccessible:: get_groupPosition(long __RPC_FAR *groupLevel,long __RPC_FAR *similarItemsInGroup,long __RPC_FAR *positionInGroup) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(groupLevel == NULL || similarItemsInGroup == NULL || positionInGroup == NULL) + { + return E_INVALIDARG; + } + + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if(!pRContext.is()) + return E_FAIL; + long Role = pRContext->getAccessibleRole(); + + *groupLevel = 0; + *similarItemsInGroup = 0; + *positionInGroup = 0; + + if (Role != AccessibleRole::DOCUMENT) + { + Reference< XAccessibleGroupPosition > xGroupPosition( pRContext, UNO_QUERY ); + if ( xGroupPosition.is() ) + { + Sequence< sal_Int32 > rSeq = xGroupPosition->getGroupPosition( makeAny( pRContext ) ); + sal_Int32* pSeq = rSeq.getArray(); + if ( pSeq ) + { + *groupLevel = pSeq[0]; + *similarItemsInGroup = pSeq[1]; + *positionInGroup = pSeq[2]; + return S_OK; + } + return S_OK; + } + } + + Reference< XAccessible> pParentAcc = pRContext->getAccessibleParent(); + if( !pParentAcc.is() ) + { + return S_OK; + } + + Reference<XAccessibleContext> pRParentContext = pParentAcc->getAccessibleContext(); + + int level = 0; + int index = 0; + int number = 0; + + if( Role == RADIO_BUTTON ) + { + Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet(); + long nRel = pRrelationSet->getRelationCount(); + for(int i=0 ; i<nRel ; i++) + { + AccessibleRelation accRelation = pRrelationSet->getRelation(i); + if(accRelation.RelationType == 7) + { + Sequence< Reference< XInterface > > xTargets = accRelation.TargetSet; + int nCount = xTargets.getLength(); + + Reference<XInterface> pRAcc = xTargets[0]; + for(int j=0; j<pRParentContext->getAccessibleChildCount(); j++) + { + if( getTheParentOfMember(pRParentContext->getAccessibleChild(j).get()) + == (XAccessible*)pRAcc.get() && + pRParentContext->getAccessibleChild(j)->getAccessibleContext()->getAccessibleRole() == RADIO_BUTTON) + number++; + if(pRParentContext->getAccessibleChild(j).get() == pUNOInterface) + index = number; + } + } + } + *groupLevel = 1; + *similarItemsInGroup = number; + *positionInGroup = index; + return S_OK; + } + + else if ( COMBO_BOX == Role ) + { + *groupLevel = 1; + *similarItemsInGroup = 0; + *positionInGroup = -1; + + long nCount = pRContext->getAccessibleChildCount(); + if( 2 != nCount) + { + return S_OK; + } + Reference<XAccessible> xList=pRContext->getAccessibleChild(1); + if (!xList.is()) + { + return S_OK; + } + Reference<XAccessibleContext> xListContext(xList,UNO_QUERY); + if (!xListContext.is()) + { + return S_OK; + } + Reference<XAccessibleSelection> xListSel(xList,UNO_QUERY); + if (!xListSel.is()) + { + return S_OK; + } + *similarItemsInGroup = xListContext->getAccessibleChildCount(); + if (*similarItemsInGroup > 0 ) + { + try + { + Reference<XAccessible> xChild = xListSel->getSelectedAccessibleChild(0); + if (xChild.is()) + { + Reference<XAccessibleContext> xChildContext(xChild,UNO_QUERY); + if (xChildContext.is()) + { + *positionInGroup=xChildContext->getAccessibleIndexInParent() + 1 ; + return S_OK; + } + } + } + catch(...) + {} + } + return S_OK; + } + else if ( PAGE_TAB == Role ) + { + *groupLevel = 1; + *similarItemsInGroup = pRParentContext->getAccessibleChildCount(); + + if (*similarItemsInGroup > 0 ) + { + *positionInGroup=pRContext->getAccessibleIndexInParent() + 1 ; + } + else + { + *positionInGroup = -1; + } + return S_OK; + } + + + BOOL isFound = FALSE; + while( pParentAcc.is() && !isFound) + { + level++; + pRParentContext = pParentAcc->getAccessibleContext(); + Role = pRParentContext->getAccessibleRole(); + if( (Role == TREE) || (Role == LIST) ) + isFound = TRUE; + pParentAcc = pRParentContext->getAccessibleParent(); + } + + if( isFound ) + { + Reference< XAccessible> pTempAcc = pRContext->getAccessibleParent(); + pRParentContext = pTempAcc->getAccessibleContext(); + *groupLevel = level; + *similarItemsInGroup = pRParentContext->getAccessibleChildCount(); + *positionInGroup = pRContext->getAccessibleIndexInParent() + 1; + } + else + { + *groupLevel = 0; + *similarItemsInGroup = 0; + *positionInGroup = 0; + } + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +STDMETHODIMP CMAccessible:: get_extendedStates( long, BSTR __RPC_FAR *__RPC_FAR *, long __RPC_FAR *) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + + return E_NOTIMPL; + + LEAVE_PROTECTED_BLOCK +} + + +STDMETHODIMP CMAccessible:: get_uniqueID(long __RPC_FAR *uniqueID) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(uniqueID == NULL) + { + return E_INVALIDARG; + } + *uniqueID = m_dChildID; + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +STDMETHODIMP CMAccessible:: get_windowHandle(HWND __RPC_FAR *windowHandle) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(windowHandle == NULL) + { + return E_INVALIDARG; + } + + HWND nHwnd = m_hwnd; + IAccessible* pParent = m_pIParent; + CMAccessible* pChild = this; + while((nHwnd==0) && pParent) + { + pChild = (CMAccessible*)pParent; + if(pChild) + { + pParent = (IAccessible*)pChild->m_pIParent; + nHwnd = (HWND)pChild->m_hwnd; + } + else + pParent = NULL; + } + + *windowHandle = nHwnd; + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** + * 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 == NULL) + return NULL; + + pRContext = pXAcc->getAccessibleContext(); + if( !pRContext.is() ) + return NULL; + return pRContext.get(); +} + +/** + * Return the member variable m_pXAccessibleSelection, instead of + * get XAccessibleSelection according to XAccessibleContext because if so,it will + * depend on the UNO implementation code,so when COM is created, put XAccessibleSelection + * by bridge management system + * @return XAccessibleSelection*, the selection of the current object. + */ +Reference< XAccessibleSelection > CMAccessible::GetSelection() +{ + if( pUNOInterface == NULL ) + return NULL; + Reference< XAccessibleContext > pRContext = pUNOInterface->getAccessibleContext(); + if(pRContext.is()) + { + Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY); + return pRSelection; + } + return NULL; +} + +/** + * Select one XAccessible item, for accSelect implementation + * @param pItem, the item should be selected. + * @return S_OK if successful. + */ +HRESULT CMAccessible::SelectChild(XAccessible* pItem) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + XAccessibleContext* pParentContext = GetContextByXAcc( pUNOInterface ); + XAccessibleContext* pContext = GetContextByXAcc( pItem ); + if( pParentContext == NULL || pContext == NULL ) + return E_FAIL; + + Reference< XAccessibleSelection > pRSelection = GetSelection(); + if( !pRSelection.is() ) + return E_FAIL; + long Index = pContext->getAccessibleIndexInParent(); + pRSelection->selectAccessibleChild( Index ); + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** + * Deselect one XAccessible item, for accSelect implimentation + * @param pItem, the item should be deselected. + * @return S_OK if successful. + */ +HRESULT CMAccessible::DeSelectChild(XAccessible* pItem) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + XAccessibleContext* pParentContext = GetContextByXAcc( pUNOInterface ); + ; + XAccessibleContext* pContext = GetContextByXAcc( pItem ); + if( pParentContext == NULL || pContext == NULL ) + return E_INVALIDARG; + + Reference< XAccessibleSelection > pRSelection = GetSelection(); + if( !pRSelection.is() ) + return E_FAIL; + long Index = pContext->getAccessibleIndexInParent(); + pRSelection->deselectAccessibleChild( Index ); + + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** + * Select multiple XAccessible items,for implementation of accSelect + * @param pItem, the items should be selected. + * @param size, the size of the items. + * @return S_OK if successful. + */ +HRESULT CMAccessible::SelectMutipleChidren( XAccessible** pItem,int size ) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pItem == NULL) + { + return E_INVALIDARG; + } + for(int index = 0;index < size;index++) + { + SelectChild( pItem[index] ); + } + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** + * Deselect multiple XAccessible items,for implementation of accSelect + * @param pItem, the items should be selected. + * @param size, the size of the items. + * @return S_OK if successful. + */ +HRESULT CMAccessible::DeSelectMutipleChildren( XAccessible** pItem,int size ) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pItem == NULL) + { + return E_INVALIDARG; + } + for(int index = 0;index < size;index++) + { + DeSelectChild( pItem[index] ); + } + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** + * 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. + */ +STDMETHODIMP CMAccessible::SetXAccessible(long pXAcc) +{ + pUNOInterface = (XAccessible*)pXAcc; + pRef = pUNOInterface; + m_pEnumVar->PutSelection(/*XAccessibleSelection*/(long)pUNOInterface); + + pRContext = pUNOInterface->getAccessibleContext(); + pRContextInterface = (XAccessibleContext*)pRContext.is(); + + return S_OK; +} + +/** + * 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 + * @param flagsSelect, the selection flag of the select action. + * @param varChild, the child object pointer of current action. + * @return S_OK if successful. + */ +STDMETHODIMP CMAccessible::accSelect(long flagsSelect, VARIANT varChild) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + if( (flagsSelect&SELFLAG_ADDSELECTION) && + (SELFLAG_REMOVESELECTION&flagsSelect) ) + return E_INVALIDARG; + + if ( (flagsSelect&SELFLAG_TAKESELECTION) && + ( + (flagsSelect&SELFLAG_ADDSELECTION) || + (flagsSelect&SELFLAG_REMOVESELECTION) || + (flagsSelect&SELFLAG_EXTENDSELECTION ) + ) + ) + return E_INVALIDARG; + + if ( varChild.vt != VT_I4 ) + return E_INVALIDARG; + + IMAccessible* pSelectAcc; + if( varChild.lVal == CHILDID_SELF ) + { + pSelectAcc = this; + pSelectAcc->AddRef(); + } + else + { + pSelectAcc = GetChildInterface(varChild.lVal); + } + + if( pSelectAcc == NULL ) + return E_INVALIDARG; + + if( flagsSelect&SELFLAG_TAKEFOCUS ) + { + long pTempUNO = 0; + pSelectAcc->GetUNOInterface( &pTempUNO); + + if( pTempUNO == NULL ) + return NULL; + + Reference< XAccessibleContext > pRContext = ( (XAccessible*)pTempUNO)->getAccessibleContext(); + Reference< XAccessibleComponent > pRComponent(pRContext,UNO_QUERY); + Reference< XAccessible > pRParentXAcc = pRContext->getAccessibleParent(); + Reference< XAccessibleContext > pRParentContext = pRParentXAcc->getAccessibleContext(); + Reference< XAccessibleComponent > pRParentComponent(pRParentContext,UNO_QUERY); + Reference< XAccessibleSelection > pRParentSelection(pRParentContext,UNO_QUERY); + + + pRComponent->grabFocus(); + + if( flagsSelect & SELFLAG_TAKESELECTION ) + { + pRParentSelection->clearAccessibleSelection(); + pRParentSelection->selectAccessibleChild( pRContext->getAccessibleIndexInParent() ); + } + + if( flagsSelect & SELFLAG_ADDSELECTION ) + { + pRParentSelection->selectAccessibleChild( pRContext->getAccessibleIndexInParent() ); + } + + if( flagsSelect & SELFLAG_REMOVESELECTION ) + { + pRParentSelection->deselectAccessibleChild( pRContext->getAccessibleIndexInParent() ); + } + + if( flagsSelect & SELFLAG_EXTENDSELECTION ) + { + long indexInParrent = pRContext->getAccessibleIndexInParent(); + + if( pRParentSelection->isAccessibleChildSelected( indexInParrent + 1 ) || + pRParentSelection->isAccessibleChildSelected( indexInParrent - 1 ) ) + { + pRParentSelection->selectAccessibleChild( indexInParrent ); + } + } + + } + + pSelectAcc->Release(); + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +/** + * Return XAccessible interface pointer when needed + * @param pXAcc, [in, out] the Uno interface of the current object. + * @return S_OK if successful. + */ +STDMETHODIMP CMAccessible::GetUNOInterface(long* pXAcc) +{ + // #CHECK# + if(pXAcc == NULL) + return E_INVALIDARG; + + *pXAcc = (long)pUNOInterface; + return S_OK; +} + +/** + * Helper method for Implementation of get_accDefaultAction + * @param pAction, the default action point of the current object. + * @return S_OK if successful. + */ +STDMETHODIMP CMAccessible::SetDefaultAction(long pAction) +{ + m_pXAction = (XAccessibleAction*)pAction; + return S_OK; +} + +/** + * This method is called when AT open some UI elements initially + * the UI element takes the default action defined here + * @param varChild, the child id of the defaultaction. + * @param pszDefaultAction,[in/out] the description of the current action. + * @return S_OK if successful. + */ +HRESULT STDMETHODCALLTYPE CMAccessible::get_accDefaultAction(VARIANT varChild, BSTR *pszDefaultAction) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(pszDefaultAction == NULL) + { + return E_INVALIDARG; + } + if(varChild.vt==VT_I4) + { + if(varChild.lVal==CHILDID_SELF) + { + if( m_pXAction == NULL ) + return DISP_E_MEMBERNOTFOUND; + SAFE_SYSFREESTRING(*pszDefaultAction); + *pszDefaultAction = SysAllocString(m_pszActionDescription); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->get_accDefaultAction(varChild,pszDefaultAction); + } + return S_FALSE; + + LEAVE_PROTECTED_BLOCK +} + +/** + * AT call this method to operate application + * @param varChild, the child id of the action object. + * @return S_OK if successful. + */ +HRESULT STDMETHODCALLTYPE CMAccessible::accDoDefaultAction(VARIANT varChild) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + if( varChild.vt != VT_I4 ) + return E_INVALIDARG; + if( m_pXAction == NULL ) + return E_FAIL; + if( m_pXAction->getAccessibleActionCount() == 0 ) + return E_FAIL; + + if(varChild.lVal==CHILDID_SELF) + { + if(m_pXAction->getAccessibleActionCount() > 0) + m_pXAction->doAccessibleAction(0); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->accDoDefaultAction( varChild ); + + LEAVE_PROTECTED_BLOCK +} + +/** + * UNO set description information for action to COM. + * @param szAction, the action description of the current object. + * @return S_OK if successful. + */ +STDMETHODIMP CMAccessible::Put_ActionDescription( const OLECHAR* szAction) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(szAction == NULL) + { + return E_INVALIDARG; + } + SAFE_SYSFREESTRING(m_pszActionDescription ); + m_pszActionDescription = SysAllocString( szAction ); + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +BOOL CMAccessible::GetXInterfaceFromXAccessible(XAccessible* pXAcc, XInterface** ppXI, int index) +{ + Reference< XAccessibleContext > pRContext; + + switch(index) + { + case XI_COMPONENT: + QUERYXINTERFACE(AccessibleComponent) + break; + case XI_TEXT: + QUERYXINTERFACE(AccessibleText) + break; + case XI_EDITABLETEXT: + QUERYXINTERFACE(AccessibleEditableText) + break; + case XI_TABLE: + QUERYXINTERFACE(AccessibleTable) + break; + case XI_SELECTION: + QUERYXINTERFACE(AccessibleSelection) + break; + case XI_EXTENDEDCOMP: + QUERYXINTERFACE(AccessibleExtendedComponent) + break; + case XI_KEYBINDING: + QUERYXINTERFACE(AccessibleKeyBinding) + break; + case XI_ACTION: + QUERYXINTERFACE(AccessibleAction) + break; + case XI_VALUE: + QUERYXINTERFACE(AccessibleValue) + break; + case XI_HYPERTEXT: + QUERYXINTERFACE(AccessibleHypertext) + break; + case XI_HYPERLINK: + QUERYXINTERFACE(AccessibleHyperlink) + break; + case XI_IMAGE: + QUERYXINTERFACE(AccessibleImage) + break; + default: + break; + } + + return FALSE; +} + +HRESULT WINAPI CMAccessible::SmartQI(void* pv, REFIID iid, void** ppvObject) +{ + ENTER_PROTECTED_BLOCK + ISDESTROY() + if( ImplIsEqualGUID(iid,IID_IAccIdentity) || + ImplIsEqualGUID(iid,IID_IStdMarshalInfo) || + ImplIsEqualGUID(iid,IID_IMarshal) || + ImplIsEqualGUID(iid,IID_IExternalConnection)|| + ImplIsEqualGUID(iid,IID_IOleWindow)) + return E_FAIL; + + + _UNO_AGGMAP_ENTRY* pMap = _GetAggEntries(); + while(pMap && pMap->piid) + { + if(ImplIsEqualGUID(iid, *pMap->piid)) + { + XInterface* pXI = NULL; + BOOL bFound = GetXInterfaceFromXAccessible(pUNOInterface,&pXI,pMap->XIFIndex); + if(!bFound) + { + return E_FAIL; + } + + XGUIDToComObjHash::iterator pIndTemp = m_containedObjects.find( iid ); + if ( pIndTemp != m_containedObjects.end() ) + { + return pIndTemp->second.p->QueryInterface( iid, ppvObject ); + } + else + { + HRESULT hr = pMap->pfnCreateInstance(pv, iid, ppvObject); + if(hr == S_OK) + { + m_containedObjects.insert(XGUIDToComObjHash::value_type(*pMap->piid,(IUnknown*)*ppvObject)); + IUNOXWrapper* wrapper = NULL; + ((IUnknown*)*ppvObject)->QueryInterface(IID_IUNOXWrapper, (void**)&wrapper); + if(wrapper) + { + wrapper->put_XInterface((long)pUNOInterface); + wrapper->Release(); + } + return S_OK; + } + } + return E_FAIL; + } + pMap++; + } + return E_FAIL; + + LEAVE_PROTECTED_BLOCK +} + +BOOL CMAccessible::get_IAccessibleFromXAccessible(long pXAcc, IAccessible **ppIA) +{ + + ENTER_PROTECTED_BLOCK + + // #CHECK# + if(ppIA == NULL) + { + return E_INVALIDARG; + } + BOOL isGet = FALSE; + if(g_pAgent) + isGet = g_pAgent->GetIAccessibleFromXAccessible((XAccessible*)pXAcc,ppIA); + + if(isGet) + return TRUE; + else + return FALSE; + + LEAVE_PROTECTED_BLOCK +} + +void CMAccessible::get_OLECHARFromAny(Any& pAny, OLECHAR* pChar) +{ + // #CHECK# + if(pChar == NULL) + return; + + switch(pAny.getValueTypeClass()) + { + case TypeClass_CHAR: + { + sal_Int8 val; + pAny >>= val; + swprintf( pChar, L"%d", val); + break; + } + case TypeClass_BOOLEAN: + { + sal_Bool val; + pAny >>= val; + swprintf( pChar, L"%d", val); + break; + } + case TypeClass_BYTE: + { + sal_Int8 val; + pAny >>= val; + swprintf( pChar, L"%d", val); + break; + } + case TypeClass_SHORT: + { + SHORT val; + pAny >>= val; + swprintf( pChar, L"%d", val); + break; + } + case TypeClass_UNSIGNED_SHORT: + { + USHORT val; + pAny >>= val; + swprintf( pChar, L"%d", val); + break; + } + case TypeClass_LONG: + { + LONG val; + pAny >>= val; + swprintf( pChar, L"%ld", val); + break; + } + case TypeClass_UNSIGNED_LONG: + { + ULONG val; + pAny >>= val; + swprintf( pChar, L"%ld", val); + break; + } + case TypeClass_FLOAT: + { + FLOAT val; + pAny >>= val; + swprintf( pChar, L"%.3f", val); + break; + } + case TypeClass_DOUBLE: + { + DOUBLE val; + pAny >>= val; + swprintf( pChar, L"%.6lf", val); + break; + } + case TypeClass_STRING: + { + ::rtl::OUString val; + pAny >>= val; + wcscpy(pChar, val.getStr()); + break; + } + case TypeClass_SEQUENCE: + { + if(pAny.getValueType() == getCppuType( (Sequence< ::rtl::OUString > *)0 ) ) + { + Sequence < ::rtl::OUString > val; + pAny >>= val; + + ::rtl::OUString pString; + + int count = val.getLength(); + + for( int iIndex = 0;iIndex < count;iIndex++ ) + { + pString += val[iIndex]; + } + wcscpy(pChar, pString.getStr()); + } + else if (pAny.getValueType() == getCppuType( (Sequence< ::com::sun::star::style::TabStop >* )0 ) ) + { + Sequence < ::com::sun::star::style::TabStop > val; + pAny >>= val; + int count = val.getLength(); + + for( int iIndex = 0;iIndex < count;iIndex++ ) + { + OLECHAR pAttrs[512] = {NULL}; + + OLECHAR pAttrsPosition[512] = {NULL}; + OLECHAR pAttrsDescimalChar[512] = {NULL}; + OLECHAR pAttrsFillChar[512] = {NULL}; + + ::com::sun::star::style::TabStop sigleVal = val[iIndex]; + + swprintf( pAttrsPosition, L"Position=%ld,TabAlign=%ld", + sigleVal.Position, sigleVal.Alignment); + + if(sigleVal.DecimalChar==';' || sigleVal.DecimalChar == ':' || sigleVal.DecimalChar == ',' || + sigleVal.DecimalChar == '=' || sigleVal.DecimalChar == '\\') + swprintf( pAttrsDescimalChar, L"DecimalChar=\\%c",sigleVal.DecimalChar); + else + swprintf( pAttrsDescimalChar, L"DecimalChar=%c",sigleVal.DecimalChar); + + if(sigleVal.FillChar==';' || sigleVal.FillChar == ':' || sigleVal.FillChar == ',' || + sigleVal.FillChar == '=' || sigleVal.FillChar == '\\') + swprintf( pAttrsFillChar, L"FillChar=\\%c",sigleVal.FillChar); + else + swprintf( pAttrsFillChar, L"FillChar=%c",sigleVal.FillChar); + + swprintf( pAttrs, L"%s,%s,%s,",pAttrsPosition,pAttrsDescimalChar,pAttrsFillChar); + + wcscat(pChar,pAttrs); + } + } + break; + } + case TypeClass_ENUM: + { + if (pAny.getValueType() == getCppuType( (::com::sun::star::awt::FontSlant* )0 ) ) + { + com::sun::star::awt::FontSlant val; + pAny >>= val; + swprintf( pChar, L"%d", val); + } + } + case TypeClass_STRUCT: + { + if (pAny.getValueType() == getCppuType( (::com::sun::star::style::LineSpacing* )0 ) ) + { + com::sun::star::style::LineSpacing val; + pAny >>= val; + swprintf( pChar, L"Mode=%ld,Height=%ld,", val.Mode, val.Height); + } + else if (pAny.getValueType() == getCppuType( (com::sun::star::accessibility::TextSegment *)0 ) ) + { + com::sun::star::accessibility::TextSegment val; + pAny >>= val; + ::rtl::OUString realVal(val.SegmentText); + wcscpy(pChar, realVal.getStr()); + } + break; + } + case TypeClass_VOID: + case TypeClass_HYPER: + case TypeClass_UNSIGNED_HYPER: + case TypeClass_TYPE: + case TypeClass_ANY: + case TypeClass_TYPEDEF: + case TypeClass_UNION: + case TypeClass_EXCEPTION: + case TypeClass_ARRAY: + case TypeClass_INTERFACE: + case TypeClass_SERVICE: + case TypeClass_MODULE: + case TypeClass_INTERFACE_METHOD: + case TypeClass_INTERFACE_ATTRIBUTE: + case TypeClass_UNKNOWN: + case TypeClass_PROPERTY: + case TypeClass_CONSTANT: + case TypeClass_CONSTANTS: + case TypeClass_SINGLETON: + case TypeClass_MAKE_FIXED_SIZE: + break; + default: + break; + } +} + +void CMAccessible::get_OLECHAR4Numbering(const Any& pAny, short numberingLevel,const OUString& numberingPrefix,OLECHAR* pChar) +{ + if(pChar == NULL) + return; + Reference< ::com::sun::star::container::XIndexReplace > pXIndex; + if((pAny>>=pXIndex) && (numberingLevel !=-1))//numbering level is -1,means invalid value + { + Any aAny = pXIndex->getByIndex(numberingLevel); + Sequence< ::com::sun::star::beans::PropertyValue > aProps; + aAny >>= aProps; + const ::com::sun::star::beans::PropertyValue* pPropArray = aProps.getConstArray(); + sal_Int32 nCount = aProps.getLength(); + swprintf(pChar,L"Numbering:NumberingLevel=%d,",numberingLevel); + for( sal_Int32 i=0; i<nCount; i++ ) + { + ::com::sun::star::beans::PropertyValue rProp = pPropArray[i]; + if( (rProp.Name.compareTo(OUString::createFromAscii("BulletChar"))==0)|| + (rProp.Name.compareTo(OUString::createFromAscii("GraphicURL"))==0)|| + (rProp.Name.compareTo(OUString::createFromAscii("NumberingType"))==0)) + { + OLECHAR propStr[512] = {NULL}; + swprintf(propStr,L"%s=",rProp.Name.getStr()); + OLECHAR pTemp[256] = {NULL}; + CMAccessible::get_OLECHARFromAny(rProp.Value,pTemp); + if(rProp.Name.compareTo(OUString::createFromAscii("GraphicURL"))==0) + { + OLECHAR* pOccur = wcschr(pTemp,':'); + if(pOccur) + *pOccur = '.'; + } + wcscat(propStr,pTemp); + wcscat(pChar,propStr); + wcscat(pChar,L","); + + if(rProp.Name.compareTo(OUString::createFromAscii("NumberingType"))==0) + { + if(numberingPrefix.getLength()!=0) + { + swprintf(pTemp,L"NumberingPrefix=%s,",numberingPrefix.getStr()); + wcscat(pChar,pTemp); + } + } + } + } + } + + //Because now have three types numbering level: + //1.real numbering list,numbering level>=0 and numbering Rule !=NULL; + //2.common paragraph, numbering level >=0, and numbering Rule == NULL; + //3.TOC paragraph, numbering level >0, and numbering Rule ==NULL; + // IAText:numberinglevel base on 0, but TOC's level base on 1, + // so NumberingLevel value will be decreased 1 in bridge code. + else if(numberingLevel >0) + { + swprintf(pChar,L"Numbering:NumberingLevel=%d,NumberingType=4,NumberingPrefix=,",numberingLevel-1); + } + else + { + swprintf(pChar,L"Numbering:"); + } +} + +void CMAccessible::ConvertAnyToVariant(const ::com::sun::star::uno::Any &rAnyVal, VARIANT *pvData) +{ + if(rAnyVal.hasValue()) + { + // Clear VARIANT variable. + VariantClear(pvData); + + // Set value according to value type. + switch(rAnyVal.getValueTypeClass()) + { + case TypeClass_CHAR: + pvData->vt = VT_UI1; + memcpy(&pvData->bVal, rAnyVal.getValue(), sizeof(sal_Char)); + break; + + case TypeClass_BOOLEAN: + pvData->vt = VT_BOOL; + memcpy(&pvData->boolVal, rAnyVal.getValue(), sizeof(sal_Bool)); + break; + + case TypeClass_BYTE: + pvData->vt = VT_UI1; + memcpy(&pvData->bVal, rAnyVal.getValue(), sizeof(sal_Int8)); + break; + + case TypeClass_SHORT: + pvData->vt = VT_I2; + memcpy(&pvData->iVal, rAnyVal.getValue(), sizeof(sal_Int16)); + break; + + case TypeClass_UNSIGNED_SHORT: + pvData->vt = VT_I2; + memcpy(&pvData->iVal, rAnyVal.getValue(), sizeof(sal_uInt16)); + break; + + case TypeClass_LONG: + pvData->vt = VT_I4; + memcpy(&pvData->lVal, rAnyVal.getValue(), sizeof(sal_Int32)); + break; + + case TypeClass_UNSIGNED_LONG: + pvData->vt = VT_I4; + memcpy(&pvData->lVal, rAnyVal.getValue(), sizeof(sal_uInt32)); + break; + + case TypeClass_FLOAT: + pvData->vt = VT_R4; + memcpy(&pvData->fltVal, rAnyVal.getValue(), sizeof(float)); + break; + + case TypeClass_DOUBLE: + pvData->vt = VT_R8; + memcpy(&pvData->dblVal, rAnyVal.getValue(), sizeof(double)); + break; + + case TypeClass_STRING: + { + pvData->vt = VT_BSTR; + ::rtl::OUString val; + rAnyVal >>= val; + pvData->bstrVal = SysAllocString((OLECHAR *)val.getStr()); + break; + } + + case TypeClass_VOID: + case TypeClass_HYPER: + case TypeClass_UNSIGNED_HYPER: + case TypeClass_TYPE: + case TypeClass_ANY: + case TypeClass_ENUM: + case TypeClass_TYPEDEF: + case TypeClass_STRUCT: + case TypeClass_UNION: + case TypeClass_EXCEPTION: + case TypeClass_SEQUENCE: + case TypeClass_ARRAY: + case TypeClass_INTERFACE: + { + Reference< XAccessible > pXAcc; + if(rAnyVal >>= pXAcc) + { + if(pXAcc.is()) + { + IAccessible* pIAcc = NULL; + get_IAccessibleFromXAccessible((long)pXAcc.get(), &pIAcc); + if(pIAcc == NULL) + { + Reference< XAccessibleContext > pXAccContext = pXAcc->getAccessibleContext(); + g_pAgent->InsertAccObj(pXAcc.get(),pXAccContext->getAccessibleParent().get()); + get_IAccessibleFromXAccessible((long)pXAcc.get(), &pIAcc); + } + if(pIAcc) + { + pIAcc->AddRef(); + + pvData->vt = VT_UNKNOWN; + pvData->pdispVal = (IAccessible2*)pIAcc; + break; + } + } + } + } + case TypeClass_SERVICE: + case TypeClass_MODULE: + case TypeClass_INTERFACE_METHOD: + case TypeClass_INTERFACE_ATTRIBUTE: + case TypeClass_UNKNOWN: + case TypeClass_PROPERTY: + case TypeClass_CONSTANT: + case TypeClass_CONSTANTS: + case TypeClass_SINGLETON: + case TypeClass_MAKE_FIXED_SIZE: + // Output the type string, if there is other uno value type. + pvData->vt = VT_BSTR; + pvData->bstrVal = SysAllocString(rAnyVal.getValueTypeName().getStr()); + break; + + default: + break; + } + } + else + { + VariantClear(pvData); + } +} + +STDMETHODIMP CMAccessible::Get_XAccChildID(long* childID) +{ + // #CHECK# + if(childID == NULL) + { + return E_FAIL; + } + *childID = m_dChildID; + return S_OK; +} +STDMETHODIMP CMAccessible:: get_states(AccessibleStates __RPC_FAR *states ) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK XInterface# + if( !pRContext.is() ) + return E_FAIL; + + Reference<XAccessibleStateSet> pRStateSet = pRContext.get()->getAccessibleStateSet(); + if(!pRStateSet.is()) + { + return S_OK; + } + Sequence<short> pStates = pRStateSet->getStates(); + + + long count = pStates.getLength() ; + *states = 0x0; + for( int i = 0; i < count; i++ ) + { + for( int j = 0; j < sizeof(UNO_STATES) / sizeof(UNO_STATES[0]); j++ ) + { + if( pStates[i] == UNO_STATES[j] ) + { + *states |= IA2_STATES[j]; + break; + } + } + } + return S_OK; + + + LEAVE_PROTECTED_BLOCK +} + +// return the UNO roles +STDMETHODIMP CMAccessible:: get_extendedRole( BSTR __RPC_FAR * ) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + + return E_NOTIMPL; + + LEAVE_PROTECTED_BLOCK +} + +STDMETHODIMP CMAccessible:: get_localizedExtendedRole( BSTR __RPC_FAR * ) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + return E_NOTIMPL; + + LEAVE_PROTECTED_BLOCK +} +STDMETHODIMP CMAccessible:: get_nExtendedStates( long __RPC_FAR * ) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + + return E_NOTIMPL; + + LEAVE_PROTECTED_BLOCK +} + + +STDMETHODIMP CMAccessible:: get_localizedExtendedStates( long, BSTR __RPC_FAR *__RPC_FAR *, long __RPC_FAR *) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + return E_NOTIMPL; + + LEAVE_PROTECTED_BLOCK +} + + +STDMETHODIMP CMAccessible:: get_indexInParent( long __RPC_FAR *accParentIndex) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + // #CHECK# + if(accParentIndex == NULL) + return E_INVALIDARG; + + // #CHECK XInterface# + if( !pRContext.is() ) + return E_FAIL; + + *accParentIndex = pRContext.get()->getAccessibleIndexInParent(); + return S_OK; + + + LEAVE_PROTECTED_BLOCK +} +STDMETHODIMP CMAccessible:: get_locale( IA2Locale __RPC_FAR *locale ) +{ + + CHECK_ENABLE_INF + ENTER_PROTECTED_BLOCK + ISDESTROY() + if(locale == NULL) + return E_INVALIDARG; + // #CHECK XInterface# + + if( !pRContext.is() ) + return E_FAIL; + + ::com::sun::star::lang::Locale unoLoc = pRContext.get()->getLocale(); + locale->language = SysAllocString((OLECHAR*)unoLoc.Language.getStr()); + locale->country = SysAllocString((OLECHAR*)unoLoc.Country.getStr()); + locale->variant = SysAllocString((OLECHAR*)unoLoc.Variant.getStr()); + + return S_OK; + + LEAVE_PROTECTED_BLOCK +} + +DWORD GetMSAAStateFromUNO(short xState) +{ + DWORD IState = STATE_SYSTEM_UNAVAILABLE; + switch( xState ) + { + case /*AccessibleStateType::*/AccessibleStateType::BUSY: + IState = STATE_SYSTEM_BUSY; + break; + case /*AccessibleStateType::*/AccessibleStateType::CHECKED: + IState = STATE_SYSTEM_CHECKED; + break; + case /*AccessibleStateType::*/AccessibleStateType::DEFUNC: + IState = STATE_SYSTEM_UNAVAILABLE; + break; + case /*AccessibleStateType::*/AccessibleStateType::EXPANDED: + IState = STATE_SYSTEM_EXPANDED; + break; + case /*AccessibleStateType::*/AccessibleStateType::FOCUSABLE: + IState = STATE_SYSTEM_FOCUSABLE; + break; + case /*AccessibleStateType::*/AccessibleStateType::FOCUSED: + IState = STATE_SYSTEM_FOCUSED; + break; + case /*AccessibleStateType::*/AccessibleStateType::INDETERMINATE: + IState = STATE_SYSTEM_MIXED; + break; + case /*AccessibleStateType::*/AccessibleStateType::MULTI_SELECTABLE: + IState = STATE_SYSTEM_MULTISELECTABLE; + break; + case /*AccessibleStateType::*/AccessibleStateType::PRESSED: + IState = STATE_SYSTEM_PRESSED; + break; + case /*AccessibleStateType::*/AccessibleStateType::RESIZABLE: + IState = STATE_SYSTEM_SIZEABLE; + break; + case /*AccessibleStateType::*/AccessibleStateType::SELECTABLE: + IState = STATE_SYSTEM_SELECTABLE; + break; + case /*AccessibleStateType::*/AccessibleStateType::SELECTED: + IState = STATE_SYSTEM_SELECTED; + break; + case /*AccessibleStateType::*/AccessibleStateType::ARMED: + IState = STATE_SYSTEM_FOCUSED; + break; + case /*AccessibleStateType::*/AccessibleStateType::EXPANDABLE: + IState = STATE_SYSTEM_COLLAPSED; + break; + default: + break; + } + return IState; +} + +STDMETHODIMP CMAccessible:: get_appName( BSTR __RPC_FAR *name) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + if(name == NULL) + return E_INVALIDARG; + + *name = SysAllocString(OLESTR("Hannover")); + return S_OK; + LEAVE_PROTECTED_BLOCK +} +STDMETHODIMP CMAccessible:: get_appVersion(BSTR __RPC_FAR *version) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + if(version == NULL) + return E_INVALIDARG; + *version=SysAllocString(OLESTR("3.0")); + return S_OK; + LEAVE_PROTECTED_BLOCK +} +STDMETHODIMP CMAccessible:: get_toolkitName(BSTR __RPC_FAR *name) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + if(name == NULL) + return E_INVALIDARG; + *name = SysAllocString(OLESTR(" ")); + return S_OK; + LEAVE_PROTECTED_BLOCK +} +STDMETHODIMP CMAccessible:: get_toolkitVersion(BSTR __RPC_FAR *version) +{ + + ENTER_PROTECTED_BLOCK + ISDESTROY() + if(version == NULL) + return E_INVALIDARG; + *version = SysAllocString(OLESTR(" ")); + return S_OK; + LEAVE_PROTECTED_BLOCK +} + + +STDMETHODIMP CMAccessible::get_attributes(/*[out]*/ BSTR *pAttr) +{ + CHECK_ENABLE_INF + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if( !pRContext.is() ) + { + return E_FAIL; + } + Reference<XAccessibleExtendedAttributes> pRXI(pRContext,UNO_QUERY); + if( !pRXI.is() ) + return E_FAIL; + else + { + com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessibleExtendedAttributes> pRXAttr; + pRXAttr = pRXI.get(); + ::com::sun::star::uno::Any anyVal = pRXAttr->getExtendedAttributes(); + + ::rtl::OUString val; + anyVal >>= val; + + if(*pAttr) + SAFE_SYSFREESTRING(*pAttr); + *pAttr = SysAllocString((OLECHAR *)val.getStr()); + + return S_OK; + } +} + |