共用方式為


為提供者實作 IAccessibleEx

本節說明如何實 作 IAccessibleEx 介面,將 Microsoft 消費者介面自動化 提供者功能新增至 Microsoft Active Accessibility 伺服器。

實作 IAccessibleEx 之前,請考慮下列需求:

實作 IAccessibleEx 需要下列主要步驟:

實作 IServiceProvider 介面

由於控制項的 IAccessibleEx 實作 可能位於不同的 物件中,用戶端應用程式無法依賴 QueryInterface 來取得這個介面。 相反地,用戶端應該呼叫 IServiceProvider::QueryService 。 在下列這個方法的範例實作中,假設 IAccessibleEx 未實作于個別物件上,因此方法只會呼叫 QueryInterface

           
HRESULT CListboxAccessibleObject::QueryService(REFGUID guidService, REFIID riid, LPVOID *ppvObject)
{
    if (ppvObject == NULL)
    {
        return E_INVALIDARG;
    }
    *ppvObject = NULL;
    if (guidService == __uuidof(IAccessibleEx))
    {
        return QueryInterface(riid, ppvObject);
    }
    else 
    {
        return E_NOINTERFACE;
    }
};      

實作 IAccessibleEx 介面

在 Microsoft Active Accessibility 中,UI 元素一律由 IAccessible 介面和子識別碼識別。 IAccessible 的單 一實例可以代表多個 UI 元素。

因為每個 IAccessibleEx 實例只代表單一 UI 元素,因此每個 IAccessible 和子識別碼組都必須對應至單 一 IAccessibleEx 實例。 IAccessibleEx 包含兩種方法來處理此對應:

下列範例顯示 自訂清單檢視中專案的 GetObjectForChild GetIAccessiblePair 方法實作。 方法可讓消費者介面自動化將 IAccessible 和子識別碼組對應至對應的 IAccessibleEx 實例。

           
HRESULT CListboxAccessibleObject::GetObjectForChild(
    long idChild, IAccessibleEx **ppRetVal)
{ 
    VARIANT vChild;
    vChild.vt = VT_I4;
    vChild.lVal = idChild;
    HRESULT hr = ValidateChildId(vChild);
    if (FAILED(hr))
    {
        return E_INVALIDARG;
    }
    // List item accessible objects are stored as an array of
    // pointers; for the purpose of this example it is assumed that 
    // the list contents will not change. Accessible objects are
    // created only when needed.
    if (itemProviders[idChild - 1] == NULL)
    {
        // Create an object that supports UI Automation and
        // IAccessibleEx for the item.
        itemProviders[idChild - 1] = 
          new CListItemAccessibleObject(idChild, 
          g_pListboxControl);
        if (itemProviders[idChild - 1] == NULL)
        {
            return E_OUTOFMEMORY;
        }
    }
    IAccessibleEx* pAccEx = static_cast<IAccessibleEx*>
      (itemProviders[idChild - 1]);
    if (pAccEx != NULL)
    {
      pAccEx->AddRef();
    }
    *ppRetVal = pAccEx;
    return S_OK; 
}

HRESULT CListItemAccessibleObject::GetIAccessiblePair(
    IAccessible **ppAcc, long *pidChild)
{ 
    if (ppAcc == NULL || pidChild == NULL)
    {
        return E_INVALIDARG;   
    }

                CListboxAccessibleObject* pParent = 
        m_control->GetAccessibleObject();

    HRESULT hr = pParent->QueryInterface( 
        __uuidof(IAccessible), (void**)ppAcc);
    if (FAILED(hr))
    {
        *pidChild = 0;
        return E_NOINTERFACE;
    }
    *pidChild = m_childID; 
    return S_OK; 
}
}

如果可存取的物件實作不使用子識別碼,仍然可以實作方法,如下列程式碼片段所示。

           

    // This sample implements IAccessibleEx on the same object; it could use a tear-off
    // or inner object instead.
    class MyAccessibleImpl: public IAccessible,
                        public IAccessibleEx,
                        public IRawElementProviderSimple
    {
    public:
    ...
   HRESULT STDMETHODCALLTYPE GetObjectForChild( long idChild, IAccessibleEx **ppRetVal )
    {
        // This implementation does not support child IDs.
        *ppRetVal = NULL;
        return S_OK;
    }

    HRESULT STDMETHODCALLTYPE GetIAccessiblePair( IAccessible ** ppAcc, long * pidChild )
    {
        // This implementation assumes that IAccessibleEx is implemented on same object as
        // IAccessible.
        *ppAcc = static_cast<IAccessible *>(this);
        (*ppAcc)->AddRef();
        *pidChild = CHILDID_SELF;
        return S_OK;
    }

實作 IRawElementProviderSimple 介面

伺服器會使用 IRawElementProviderSimple 來公開消費者介面自動化屬性和控制模式的相關資訊。 IRawElementProviderSimple 包含下列方法:

IAccessibleEx 伺服器會藉由實 作 IRawElementProviderSimple::GetPatternProvider 來公開控制項模式。 這個方法會採用指定控制項模式的整數參數。 如果不支援模式,伺服器會 傳回 Null 。 如果支援控制項模式介面,伺服器會傳回 IUnknown ,用戶端接著呼叫 QueryInterface 以取得適當的控制項模式。

IAccessibleEx 伺服器可以藉由實 作 IRawElementProviderSimple::GetPropertyValue 並提供整數 PROPERTYID,以支援消費者介面自動化屬性(例如 LabeledBy 和 IsRequiredForForm)。 這項技術僅適用于未包含在控制項模式介面中的消費者介面自動化屬性。 與控制項模式介面相關聯的屬性會透過控制項模式介面方法公開。 例如,SelectionItem 控制項模式中的 IsSelected 屬性會以 ISelectionItemProvider::get_IsSelected 公開。