📄 access.cpp
字号:
///////////////////////////////////////////////////////////////////////////////// Name: src/msw/ole/access.cpp// Purpose: implementation of wxIAccessible and wxAccessible// Author: Julian Smart// Modified by:// Created: 2003-02-12// RCS-ID: $Id: access.cpp,v 1.24 2006/11/04 11:14:57 VZ Exp $// Copyright: (c) 2003 Julian Smart// Licence: wxWindows licence///////////////////////////////////////////////////////////////////////////////// ============================================================================// declarations// ============================================================================// ----------------------------------------------------------------------------// headers// ----------------------------------------------------------------------------// For compilers that support precompilation, includes "wx.h".#include "wx/wxprec.h"#if defined(__BORLANDC__) #pragma hdrstop#endif#if wxUSE_OLE && wxUSE_ACCESSIBILITY#include "wx/access.h"#ifndef WX_PRECOMP #include "wx/msw/wrapwin.h" #include "wx/window.h" #include "wx/log.h"#endif// for some compilers, the entire ole2.h must be included, not only oleauto.h#if wxUSE_NORLANDER_HEADERS || defined(__WATCOMC__) #include <ole2.h>#endif#include <oleauto.h>#include <oleacc.h>#include <winable.h>#include "wx/msw/ole/oleutils.h"#ifndef CHILDID_SELF#define CHILDID_SELF 0#endif#ifndef OBJID_CLIENT#define OBJID_CLIENT 0xFFFFFFFC#endif// Convert to Windows roleint wxConvertToWindowsRole(wxAccRole wxrole);// Convert to Windows statelong wxConvertToWindowsState(long wxstate);// Convert to Windows selection flagint wxConvertToWindowsSelFlag(wxAccSelectionFlags sel);// Convert from Windows selection flagwxAccSelectionFlags wxConvertFromWindowsSelFlag(int sel);#if wxUSE_VARIANT// ----------------------------------------------------------------------------// wxIEnumVARIANT interface implementation// ----------------------------------------------------------------------------class wxIEnumVARIANT : public IEnumVARIANT{public: wxIEnumVARIANT(const wxVariant& variant); virtual ~wxIEnumVARIANT() { } DECLARE_IUNKNOWN_METHODS; // IEnumVARIANT STDMETHODIMP Next(ULONG celt, VARIANT *rgelt, ULONG *pceltFetched); STDMETHODIMP Skip(ULONG celt); STDMETHODIMP Reset(); STDMETHODIMP Clone(IEnumVARIANT **ppenum);private: wxVariant m_variant; // List of further variants int m_nCurrent; // Current enum position DECLARE_NO_COPY_CLASS(wxIEnumVARIANT)};// ----------------------------------------------------------------------------// wxIEnumVARIANT// ----------------------------------------------------------------------------BEGIN_IID_TABLE(wxIEnumVARIANT) ADD_IID(Unknown) ADD_IID(EnumVARIANT)END_IID_TABLE;IMPLEMENT_IUNKNOWN_METHODS(wxIEnumVARIANT)// wxVariant contains a list of further variants.wxIEnumVARIANT::wxIEnumVARIANT(const wxVariant& variant){ m_variant = variant;}STDMETHODIMP wxIEnumVARIANT::Next(ULONG celt, VARIANT *rgelt, ULONG *pceltFetched){ wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumVARIANT::Next")); if ( celt > 1 ) { // we only return 1 element at a time - mainly because I'm too lazy to // implement something which you're never asked for anyhow return S_FALSE; } if (m_variant.GetType() != wxT("list")) return S_FALSE; if ( m_nCurrent < (int) m_variant.GetList().GetCount() ) { if (!wxConvertVariantToOle(m_variant[m_nCurrent++], rgelt[0])) { return S_FALSE; } // TODO: should we AddRef if this is an object? * pceltFetched = 1; return S_OK; } else { // bad index return S_FALSE; }}STDMETHODIMP wxIEnumVARIANT::Skip(ULONG celt){ wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumVARIANT::Skip")); if (m_variant.GetType() != wxT("list")) return S_FALSE; m_nCurrent += celt; if ( m_nCurrent < (int) m_variant.GetList().GetCount() ) return S_OK; // no, can't skip this many elements m_nCurrent -= celt; return S_FALSE;}STDMETHODIMP wxIEnumVARIANT::Reset(){ wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumVARIANT::Reset")); m_nCurrent = 0; return S_OK;}STDMETHODIMP wxIEnumVARIANT::Clone(IEnumVARIANT **ppenum){ wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumVARIANT::Clone")); wxIEnumVARIANT *pNew = new wxIEnumVARIANT(m_variant); pNew->AddRef(); *ppenum = pNew; return S_OK;}#endif // wxUSE_VARIANT// ----------------------------------------------------------------------------// wxIAccessible implementation of IAccessible interface// ----------------------------------------------------------------------------class wxIAccessible : public IAccessible{public: wxIAccessible(wxAccessible *pAccessible); DECLARE_IUNKNOWN_METHODS;// IAccessible// Navigation and Hierarchy // Retrieves the child element or child object at a given point on the screen. // All visual objects support this method; sound objects do not support it. STDMETHODIMP accHitTest(long xLeft, long yLeft, VARIANT* pVarID); // Retrieves the specified object's current screen location. All visual objects must // support this method; sound objects do not support it. STDMETHODIMP accLocation ( long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varID); // Traverses to another user interface element within a container and retrieves the object. // All visual objects must support this method. STDMETHODIMP accNavigate ( long navDir, VARIANT varStart, VARIANT* pVarEnd); // Retrieves the address of an IDispatch interface for the specified child. // All objects must support this property. STDMETHODIMP get_accChild ( VARIANT varChildID, IDispatch** ppDispChild); // Retrieves the number of children that belong to this object. // All objects must support this property. STDMETHODIMP get_accChildCount ( long* pCountChildren); // Retrieves the IDispatch interface of the object's parent. // All objects support this property. STDMETHODIMP get_accParent ( IDispatch** ppDispParent);// Descriptive Properties and Methods // Performs the object's default action. Not all objects have a default // action. STDMETHODIMP accDoDefaultAction(VARIANT varID); // Retrieves a string that describes the object's default action. // Not all objects have a default action. STDMETHODIMP get_accDefaultAction ( VARIANT varID, BSTR* pszDefaultAction); // Retrieves a string that describes the visual appearance of the specified object. // Not all objects have a description. STDMETHODIMP get_accDescription ( VARIANT varID, BSTR* pszDescription); // Retrieves an object's Help property string. // Not all objects support this property. STDMETHODIMP get_accHelp ( VARIANT varID, BSTR* pszHelp); // Retrieves the full path of the WinHelp file associated with the specified // object and the identifier of the appropriate topic within that file. // Not all objects support this property. STDMETHODIMP get_accHelpTopic ( BSTR* pszHelpFile, VARIANT varChild, long* pidTopic); // Retrieves the specified object's shortcut key or access key, also known as // the mnemonic. All objects that have a shortcut key or access key support // this property. STDMETHODIMP get_accKeyboardShortcut ( VARIANT varID, BSTR* pszKeyboardShortcut); // Retrieves the name of the specified object. // All objects support this property. STDMETHODIMP get_accName ( VARIANT varID, BSTR* pszName); // Retrieves information that describes the role of the specified object. // All objects support this property. STDMETHODIMP get_accRole ( VARIANT varID, VARIANT* pVarRole); // Retrieves the current state of the specified object. // All objects support this property. STDMETHODIMP get_accState ( VARIANT varID, VARIANT* pVarState); // Retrieves the value of the specified object. // Not all objects have a value. STDMETHODIMP get_accValue ( VARIANT varID, BSTR* pszValue);// Selection and Focus // Modifies the selection or moves the keyboard focus of the // specified object. All objects that select or receive the // keyboard focus must support this method. STDMETHODIMP accSelect ( long flagsSelect, VARIANT varID ); // Retrieves the object that has the keyboard focus. All objects // that receive the keyboard focus must support this property. STDMETHODIMP get_accFocus ( VARIANT* pVarID); // Retrieves the selected children of this object. All objects // selected must support this property. STDMETHODIMP get_accSelection ( VARIANT * pVarChildren);// Obsolete STDMETHODIMP put_accName(VARIANT WXUNUSED(varChild), BSTR WXUNUSED(szName)) { return E_FAIL; } STDMETHODIMP put_accValue(VARIANT WXUNUSED(varChild), BSTR WXUNUSED(szName)) { return E_FAIL; }// IDispatch // Get type info STDMETHODIMP GetTypeInfo(unsigned int typeInfo, LCID lcid, ITypeInfo** ppTypeInfo); // Get type info count STDMETHODIMP GetTypeInfoCount(unsigned int* typeInfoCount); // Get ids of names STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR** names, unsigned int cNames, LCID lcid, DISPID* dispId); // Invoke STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, unsigned int *puArgErr );// Helpers // Gets the standard IAccessible interface for the given child or object. // Call Release if this is non-NULL. IAccessible* GetChildStdAccessible(int id); // Gets the IAccessible interface for the given child or object. // Call Release if this is non-NULL. IAccessible* GetChildAccessible(int id);private: wxAccessible *m_pAccessible; // pointer to C++ class we belong to DECLARE_NO_COPY_CLASS(wxIAccessible)};// ============================================================================// Implementation// ============================================================================// ----------------------------------------------------------------------------// wxIAccessible implementation// ----------------------------------------------------------------------------BEGIN_IID_TABLE(wxIAccessible) ADD_IID(Unknown) ADD_IID(Accessible) ADD_IID(Dispatch)END_IID_TABLE;IMPLEMENT_IUNKNOWN_METHODS(wxIAccessible)wxIAccessible::wxIAccessible(wxAccessible *pAccessible){ wxASSERT( pAccessible != NULL ); m_pAccessible = pAccessible;}// Retrieves the child element or child object at a given point on the screen.// All visual objects support this method; sound objects do not support it.STDMETHODIMP wxIAccessible::accHitTest(long xLeft, long yLeft, VARIANT* pVarID){ wxLogTrace(wxT("access"), wxT("accHitTest")); wxASSERT (m_pAccessible != NULL); if (!m_pAccessible) return E_FAIL; wxAccessible* childObject = NULL; int childId = 0; VariantInit(pVarID); wxAccStatus status = m_pAccessible->HitTest(wxPoint(xLeft, yLeft), & childId, & childObject); if (status == wxACC_FAIL) return E_FAIL; if (status == wxACC_NOT_IMPLEMENTED) { // Use standard interface instead. IAccessible* stdInterface = (IAccessible*)m_pAccessible->GetIAccessibleStd(); if (!stdInterface) return E_NOTIMPL; else return stdInterface->accHitTest(xLeft, yLeft, pVarID); } if (childObject) { if (childObject == m_pAccessible) { pVarID->vt = VT_I4; pVarID->lVal = CHILDID_SELF; return S_OK; } else { wxIAccessible* childIA = childObject->GetIAccessible(); if (!childIA) return E_NOTIMPL; if (childIA->QueryInterface(IID_IDispatch, (LPVOID*) & pVarID->pdispVal) != S_OK) return E_FAIL; pVarID->vt = VT_DISPATCH; return S_OK; } } else if (childId > 0) { pVarID->vt = VT_I4; pVarID->lVal = childId; return S_OK; } else { pVarID->vt = VT_EMPTY; return S_FALSE; } #if 0 // all cases above already cause some return action so below line // is unreachable and cause unnecessary warning return E_NOTIMPL; #endif}// Retrieves the specified object's current screen location. All visual objects must// support this method; sound objects do not support it.STDMETHODIMP wxIAccessible::accLocation ( long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varID){ wxLogTrace(wxT("access"), wxT("accLocation")); wxASSERT (m_pAccessible != NULL); if (!m_pAccessible) return E_FAIL; wxRect rect; wxAccStatus status = m_pAccessible->GetLocation(rect, varID.lVal); if (status == wxACC_FAIL) return E_FAIL; if (status == wxACC_NOT_IMPLEMENTED) { // Try to use child object directly. if (varID.lVal > 0) { IAccessible* childAccessible = GetChildAccessible(varID.lVal); if (childAccessible) { varID.lVal = 0; HRESULT hResult = childAccessible->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varID); childAccessible->Release(); return hResult; } else if (m_pAccessible->GetIAccessibleStd()) return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varID); } else if (m_pAccessible->GetIAccessibleStd()) return ((IAccessible*) m_pAccessible->GetIAccessibleStd())->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight, varID); } else { *pxLeft = rect.x; *pyTop = rect.y; *pcxWidth = rect.width; *pcyHeight = rect.height; return S_OK; } return E_NOTIMPL;}// Traverses to another user interface element within a container and retrieves the object.// All visual objects must support this method.STDMETHODIMP wxIAccessible::accNavigate ( long navDir, VARIANT varStart, VARIANT* pVarEnd){ wxASSERT (m_pAccessible != NULL); if (!m_pAccessible) return E_FAIL; wxLogTrace(wxT("access"), wxString(wxT("accNavigate for ")) + m_pAccessible->GetWindow()->GetClassInfo()->GetClassName()); if ((varStart.vt != VT_I4 && varStart.vt != VT_EMPTY) #if 0 // according to MSDN and sources varStart.vt is unsigned // so below line cause warning "Condition is always false" || varStart.vt < 0 #endif ) { wxLogTrace(wxT("access"), wxT("Invalid arg for accNavigate")); return E_INVALIDARG; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -