Partager via


Hébergement d’un contrôle ActiveX sans fenêtre UI Automation

Découvrez comment créer un conteneur de contrôles capable d’héberger des contrôles Microsoft ActiveX sans fenêtre qui implémentent Microsoft UI Automation. En suivant les étapes décrites ici, vous pouvez vous assurer que tous les UI Automation contrôles sans fenêtre hébergés dans votre conteneur de contrôle sont accessibles aux applications clientes de technologie d’assistance (AT).

Bon à savoir

Technologies

Prérequis

  • C/C++
  • Microsoft Win32 et programmation COM (Component Object Model)
  • Contrôles ActiveX sans fenêtre
  • fournisseurs UI Automation

Instructions

Étape 1 : Fournissez l’interface IRawElementProviderSimple pour le compte du contrôle sans fenêtre.

Chaque fois que le système a besoin du pointeur IRawElementProviderSimple pour la racine d’un contrôle sans fenêtre, le système interroge le conteneur de contrôle. Pour récupérer le pointeur, le conteneur appelle l’implémentation du contrôle sans fenêtre de la méthode IServiceProvider::QueryService .

Si le conteneur de contrôle a une implémentation UI Automation, il peut renvoyer le pointeur IRawElementProviderSimple du contrôle sans fenêtre vers le système.

Si le conteneur de contrôle a une implémentation Microsoft Active Accessibility, appelez la fonction UiaIAccessibleFromProvider pour obtenir un pointeur d’interface IAccessible qui représente le contrôle, puis retournez le pointeur d’interface IAccessible vers le système.

Étape 2 : Implémenter l’interface IRawElementProviderWindowlessSite.

Un conteneur de contrôle implémente l’interface IRawElementProviderWindowlessSite pour permettre à un contrôle sans fenêtre basé sur UI Automation de communiquer ses informations d’accessibilité.

  1. Implémentez IRawElementProviderWindowlessSite::GetRuntimeIdPrefix.

    Un fragment de contrôle sans fenêtre doit créer un ID d’exécution unique pour lui-même. Pour créer son ID d’exécution, un fragment de contrôle sans fenêtre récupère une valeur de préfixe en appelant la méthode GetRuntimeIdPrefix du site de contrôle, puis ajoute au préfixe une valeur entière unique par rapport à tous les autres fragments du contrôle sans fenêtre.

    Le site de contrôle d’un contrôle sans fenêtre doit implémenter la méthode GetRuntimeIdPrefix en formant un SAFEARRAY qui contient la constante UiaAppendRuntimeId, suivie d’une valeur entière unique au site.

    Cet exemple montre comment retourner un préfixe d’ID d’exécution pour un contrôle sans fenêtre.

    IFACEMETHODIMP CProviderWindowlessSite::GetRuntimeIdPrefix(   
         SAFEARRAY **ppsaPrefix)   
    {   
        if (ppsaPrefix == NULL) 
        {
            return E_INVALIDARG;
        }
    
        // m_siteIndex is the index of the windowless control's
        // site. It is defined by the control container.
        int rId[] = { UiaAppendRuntimeId, m_siteIndex };
        SAFEARRAY *psa = SafeArrayCreateVector(VT_I4, 0, 2);  
        if (psa == NULL)
        {
            return E_OUTOFMEMORY;
        }
    
        for (LONG i = 0; i < 2; i++)
        {
            SafeArrayPutElement(psa, &i, (void*)&(rId[i]));
        }
    
        *ppsaPrefix = psa;  
        return S_OK;  
    }  
    
  2. Implémentez la méthode IRawElementProviderWindowlessSite::GetAdjacentFragment.

    Un contrôle qui implémente UI Automation doit retourner un pointeur vers le fournisseur de fragments parent du contrôle.

    Pour retourner le parent du fragment, un objet qui implémente l’interface IRawElementProviderFragment doit être en mesure d’implémenter la méthode Navigate . L’implémentation de La navigation est difficile pour un contrôle sans fenêtre, car il peut ne pas être en mesure de déterminer son emplacement dans l’arborescence accessible de l’objet parent. La méthode IRawElementProviderWindowlessSite::GetAdjacentFragment permet au contrôle sans fenêtre d’interroger son site pour le fragment adjacent, puis de renvoyer ce fragment au client appelé Navigate.

    Cet exemple montre comment un conteneur de contrôle récupère le fragment parent d’un contrôle sans fenêtre.

    IFACEMETHODIMP CProviderWindowlessSite::GetAdjacentFragment(
            enum NavigateDirection direction, IRawElementProviderFragment **ppFragment)   
    {
        if (ppFragment == NULL)
        {
            return E_INVALIDARG;
        }
    
        *ppFragment = NULL;
        HRESULT hr = S_OK;
    
        switch (direction)
        {
            case NavigateDirection_Parent:
                {  
                    IRawElementProviderSimple *pSimple = NULL;
    
                    // Call an application-defined function to retrieve the
                    // parent provider interface.
                    hr = GetParentProvider(&pSimple);  
                    if (SUCCEEDED(hr))  
                    {  
                        // Get the parent's IRawElementProviderFragment interface.
                        hr = pSimple->QueryInterface(IID_PPV_ARGS(ppFragment));  
                        pSimple->Release();  
                    } 
                }  
                break;  
    
            case NavigateDirection_FirstChild:
            case NavigateDirection_LastChild:
                hr = E_INVALIDARG;
                break;
    
            // Ignore NavigateDirection_NextSibling and NavigateDirection_PreviousSibling
            // because there are no adjacent fragments.
            default:  
                break;  
        }  
    
        return hr;  
    }   
    

Étape 3 : Facultatif : Implémenter l’interface IRawElementProviderHostingAccessibles.

Implémentez l’interface IRawElementProviderHostingAccessibles si votre conteneur de contrôle a une implémentation de fournisseur de UI Automation qui est à la racine d’une arborescence d’accessibilité qui inclut des contrôles ActiveX sans fenêtre qui prennent en charge l’accessibilité Active Microsoft. L’interface IRawElementProviderHostingAccessibles a une seule méthode, GetEmbeddedAccessibles, qui récupère les pointeurs d’interface IAccessible de tous les contrôles ActiveX basés sur l’accessibilité Active Microsoft hébergés par votre conteneur de contrôle.

Comment héberger un contrôle ActiveX sans fenêtre MSAA

Accessibilité du contrôle ActiveX sans fenêtre