comment utiliser UI Automation pour rendre un contrôle de ActiveX sans fenêtre Accessible

décrit comment utiliser l’API d’automatisation d’interface utilisateur de microsoft pour vous assurer que le contrôle microsoft ActiveX sans fenêtre est accessible aux applications clientes de la technologie d’assistance (AT).

Bon à savoir

Technologies

Prérequis

  • C/C++
  • Programmation Microsoft Win32 et COM (Component Object Model)
  • contrôles ActiveX sans fenêtre
  • Fournisseurs UI Automation

Instructions

Étape 1 : implémenter les interfaces du fournisseur UI Automation.

pour rendre votre application accessible, vous devez implémenter les interfaces du fournisseur UI Automation pour le contrôle ActiveX sans fenêtre, notamment IRawElementProviderSimple, IRawElementProviderFragment, IRawElementProviderFragmentRootet IRawElementProviderAdviseEvents. Vous devez implémenter ces interfaces comme vous le feriez pour un contrôle basé sur une fenêtre, sauf comme décrit dans les étapes suivantes. Pour plus d’informations sur l’implémentation des interfaces de fournisseur UIA, consultez le Guide du programmeur de fournisseur UI Automation.

Étape 2 : implémenter l’interface IServiceProvider.

Lorsqu’un client a besoin d’informations d’accessibilité sur votre contrôle sans fenêtre, le conteneur de contrôle appelle la méthode IServiceProvider :: QueryService de votre contrôle pour récupérer le pointeur d’interface IRawElementProviderSimple pour votre contrôle.

L’exemple suivant montre comment implémenter la méthode QueryService .

STDMETHODIMP CMyAccessibleUIAControl::QueryService(REFGUID guidService,
        REFIID riid, void **ppvObject)
{  
    if (ppvObject == NULL)
    {
        return E_INVALIDARG;
    }

    *ppvObject = NULL;  
    HRESULT hr = E_FAIL; 
 
    if (guidService == __uuidof(IRawElementProviderSimple))
    {  
        hr = QueryInterface(riid, ppvObject);  
    }  
    return hr;  
}

Étape 3 : implémentez la méthode IRawElementProviderFragment :: Navigate.

Quand la méthode IRawElementProviderFragment :: Navigate d’un contrôle sans fenêtre est appelée pour accéder au parent ou à un frère du fournisseur racine du contrôle sans fenêtre, votre méthode Navigate doit déléguer à la méthode IRawElementProviderWindowlessSite :: GetAdjacentFragment du conteneur de contrôle.

L’exemple suivant montre comment implémenter la méthode Navigate .

STDMETHODIMP CMyAccessibleUIAControl::Navigate(NavigateDirection direction,
     IRawElementProviderFragment **ppRetVal) 
{   
    if (ppRetVal == NULL)
    {
        return E_INVALIDARG;
    }

    *ppRetVal = NULL;  
    HRESULT hr = E_FAIL;
    IRawElementProviderWindowlessSite *pWindowlessSite = NULL;  
    
    if (direction == NavigateDirection_Parent)  
    {  
        // Query the control container's windowless site 
        // for the parent.
         if (SUCCEEDED(m_pClientSite->QueryInterface(
                IID_PPV_ARGS(&pWindowlessSite))))  
        {  
            hr =  pWindowlessSite->GetAdjacentFragment(direction, ppRetVal);  
        }  
    }  

    else if (direction == NavigateDirection_FirstChild)  
    {  
        // GetFragmentForChild is an application-defined function that 
        // retrieves the first or last child fragment.
        hr =  GetFragmentForChild(FIRST, ppRetVal);  
    }  

    else if (direction == NavigateDirection_LastChild)  
    {  
        hr = GetFragmentForChild(LAST, ppRetVal);  
    }  

    SafeRelease(&pWindowlessSite);
    return S_OK;   
}

Étape 4 : implémentez la méthode IRawElementProviderFragment :: GetRuntimeId.

Lorsque votre contrôle sans fenêtre reçoit un appel à sa méthode IRawElementProviderFragment :: GetRuntimeId , le contrôle doit effectuer les opérations suivantes :

  1. Récupérez un préfixe d’ID d’exécution en appelant la méthode IRawElementProviderWindowlessSite :: GetRuntimeIdPrefix du site de contrôle.
  2. Créez un ID d’exécution unique pour le contrôle en ajoutant un entier au préfixe d’ID d’exécution.
  3. Retourne l’ID d’exécution à l’appelant.

L’exemple suivant montre comment implémenter la méthode GetRuntimeId .

STDMETHODIMP CMyAccessibleUIAControl::GetRuntimeId(SAFEARRAY **ppRetVal)  
{   
    if (ppRetVal == NULL)
    {
        return E_INVALIDARG;
    }

    *ppRetVal = NULL;  
    HRESULT hr = E_FAIL;
    IRawElementProviderWindowlessSite *pWindowlessSite = NULL;  

    if (SUCCEEDED(m_pClientSite->QueryInterface(IID_PPV_ARGS(&pWindowlessSite))))  
    {  
        // Create a safe array to hold runtime ID.
        SAFEARRAY *psa = SafeArrayCreateVector(VT_I4, 1, 3);  
        if (psa == NULL)
        {
            hr = E_OUTOFMEMORY;
        }

        // Retrieve the runtime ID prefix from the control container. The prefix
        // consists of UiaAppendRuntimeId followed by the windowless site ID.
        if (SUCCEEDED(hr))
        {    
            hr = pWindowlessSite->GetRuntimeIdPrefix(&psa);  
        } 

        if (SUCCEEDED(hr))
        {
        // Append this fragment's ID to the retrieved runtime ID prefix.
            long i = 2;
            hr = SafeArrayPutElement(psa, &i, (void*)&m_Id);        
        }

        if (SUCCEEDED(hr))
        {
            *ppRetVal = psa;  
        }
    }

    SafeRelease(&pWindowlessSite);
    return hr;  
}

utiliser MSAA pour rendre un contrôle de ActiveX sans fenêtre Accessible

accessibilité des contrôles ActiveX sans fenêtre