Compartir a través de


Server-Side UI Automation Provider Implementation

Actualización: noviembre 2007

En esta sección se describe cómo implementar un proveedor de Automatización de la interfaz de usuario de servidor para un control personalizado.

La implementación de elementos de Windows Presentation Foundation (WPF) y elementos que no son de WPF (como los diseñados para formularios Windows Forms) difiere considerablemente. Los elementos de WPF proporcionan compatibilidad con Automatización de la interfaz de usuario a través de una clase que se deriva de AutomationPeer. Los elementos que no son de WPF proporcionan la compatibilidad mediante implementaciones de interfaces de proveedor.

Este tema contiene las secciones siguientes.

  • Consideraciones de seguridad
  • Implementación de proveedores mediante elementos de Windows Presentation Foundation
  • Implementación de proveedores en elementos que no son de WPF
  • Temas relacionados

Consideraciones de seguridad

Los proveedores deben escribirse de modo que funcionen en un entorno de confianza parcial. Dado que UIAutomationClient.dll no está configurado para ejecutarse en situaciones de confianza parcial, el código del proveedor no debe hacer referencia a ese ensamblado. De lo contrario, el código podrá ejecutarse en entornos de plena confianza, pero no en entornos de confianza parcial.

En particular, no utilice los campos de las clases de UIAutomationClient.dll, tales como los contenidos en AutomationElement. En su lugar, utilice los campos equivalentes de las clases de UIAutomationTypes.dll, como AutomationElementIdentifiers.

Implementación de proveedores mediante elementos de Windows Presentation Foundation

Para obtener más información acerca de este tema, vea Automatización de la interfaz de usuario de un control personalizado de WPF.

Implementación de proveedores en elementos que no son de WPF

Los controles personalizados que no forman parte del marco de trabajo de WPF, pero que se han escrito en código administrado (en la mayoría de los casos se trata de controles de formularios Windows Forms), proporcionan compatibilidad con la Automatización de la interfaz de usuario mediante la implementación de interfaces. Cada elemento debe implementar al menos una de las interfaces mostradas en la primera tabla de la sección siguiente. Además, si el elemento admite uno o más patrones de control, debe implementar la interfaz adecuada para cada patrón de control.

El proyecto de proveedor de Automatización de la interfaz de usuario debe hacer referencia a los ensamblados siguientes:

  • UIAutomationProviders.dll

  • UIAutomationTypes.dll

  • WindowsBase.dll

Este tema contiene las subsecciones siguientes.

  • Interfaces de proveedores
  • Requisitos para los proveedores que no son WPF
  • Valores de propiedades en los proveedores que no son WPF
  • Eventos en los proveedores que no son WPF
  • Navegación en los proveedores que no son WPF
  • Cambio de elemento primario para proveedores que no son WPF
  • Cambio de posición de proveedores que no son WPF

Interfaces de proveedores

Cada proveedor de Automatización de la interfaz de usuario debe implementar una de las interfaces siguientes.

Interface

Descripción

IRawElementProviderSimple

Proporciona funcionalidad para un control simple hospedado en una ventana e incluye compatibilidad con los patrones de control y las propiedades.

IRawElementProviderFragment

Hereda de IRawElementProviderSimple. Agrega funcionalidad para un elemento en un control complejo, que incluye navegación dentro del fragmento, establecimiento del foco y devolución del rectángulo delimitador del elemento.

IRawElementProviderFragmentRoot

Hereda de IRawElementProviderFragment. Agrega funcionalidad para el elemento raíz de un control complejo, que incluye la localización de un elemento secundario en las coordenadas especificadas y el establecimiento del estado del foco para todo el control.

Las interfaces siguientes proporcionan funcionalidad adicional, pero no es obligatorio implementarlas.

Interface

Descripción

IRawElementProviderAdviseEvents

Permite al proveedor realizar el seguimiento de las solicitudes para los eventos.

IRawElementProviderHwndOverride

Permite el cambio de posición de los elementos basados en ventanas dentro del árbol de Automatización de la interfaz de usuario de un fragmento.

Todas las demás interfaces del espacio de nombres System.Windows.Automation.Provider se utilizan para proporcionar compatibilidad con el patrón de control.

Requisitos para los proveedores que no son WPF

Para comunicarse con la Automatización de la interfaz de usuario, el control debe implementar las principales áreas de funcionalidad siguientes:

Funcionalidad

Implementación

Expone el proveedor a la Automatización de la interfaz de usuario

En respuesta a un mensaje de WM_GETOBJECT enviado a la ventana de control, devuelva el objeto que implementa IRawElementProviderSimple (o una interfaz derivada). Para los fragmentos, este debe ser el proveedor correspondiente a la raíz del fragmento.

Proporciona valores de propiedad

Implemente GetPropertyValue para proporcionar o invalidar los valores.

Permite que el cliente interactúe con el control

Implemente interfaces que admiten patrones de control, como IInvokeProvider. Devuelva estos proveedores de modelos en la implementación de GetPatternProvider.

Provoca eventos

Llame a uno de los métodos estáticos de AutomationInteropProvider para provocar un evento para el que un cliente pueda realizar escuchas.

Permite la navegación y la asignación de foco en un fragmento

Implemente IRawElementProviderFragment para cada elemento del fragmento. (No es necesario para los elementos que no forman parte de un fragmento.)

Permite la asignación del foco y la localización de elementos secundarios en un fragmento

ImplementeIRawElementProviderFragmentRoot. (No es necesario para los elementos que no son raíces del fragmento.)

Valores de propiedades en los proveedores que no son WPF

Los proveedores de Automatización de la interfaz de usuario para controles personalizados deben admitir algunas propiedades que tanto el sistema de automatización como las aplicaciones cliente pueden utilizar. Para los elementos que se hospedan en ventanas (HWND), la Automatización de la interfaz de usuario puede recuperar algunas propiedades del proveedor de la ventana predeterminado, pero debe obtener otras del proveedor personalizado.

Los proveedores de controles basados en indicadores de ventana (HWND) no suelen necesitar que se proporcionen las propiedades siguientes (identificadas por valores de campo):

Nota:

La propiedad RuntimeIdProperty de un elemento simple o raíz de fragmento hospedado en una ventana se obtiene de la ventana; sin embargo, los elementos de fragmentos situados por debajo de la raíz (como los elementos de lista de un cuadro de lista) deben proporcionar sus propios identificadores. Para obtener más información, vea GetRuntimeId.

Debe devolverse el campo IsKeyboardFocusableProperty para los proveedores hospedados en un control de formularios Windows Forms. En este caso, es posible que el proveedor predeterminado de la ventana no pueda recuperar el valor correcto.

El proveedor del host suele proporcionar el campo NameProperty. Por ejemplo, si un control personalizado se deriva de Control, el nombre se deriva de la propiedad Text del control.

Para obtener código de ejemplo, vea Return Properties from a UI Automation Provider.

Eventos en los proveedores que no son WPF

Los proveedores de Automatización de la interfaz de usuario deben provocar eventos para notificar a las aplicaciones cliente los cambios que se producen en el estado de la interfaz de usuario. Los métodos siguientes se utilizan para provocar eventos.

Método

Descripción

RaiseAutomationEvent

Provoca varios eventos, incluidos los desencadenados por los patrones de control.

RaiseAutomationPropertyChangedEvent

Provoca un evento cuando cambia una propiedad de Automatización de la interfaz de usuario.

RaiseStructureChangedEvent

Provoca un evento cuando cambia la estructura del árbol de Automatización de la interfaz de usuario; por ejemplo, cuando se quita o agrega un elemento.

El propósito de un evento es notificar al cliente algo que ha sucedido en la interfaz de usuario (UI), independientemente de que esta actividad sea o no desencadenada por el propio sistema de Automatización de la interfaz de usuario. Por ejemplo, el evento identificado por InvokedEvent debe provocarse cada vez que se llame al control, ya sea mediante una acción directa del usuario o mediante una llamada de la aplicación cliente a Invoke.

Para optimizar el rendimiento, un proveedor puede provocar selectivamente los eventos o no provocarlos en absoluto si no hay ninguna aplicación cliente registrada para recibirlos. Los métodos siguientes se utilizan con fines de optimización.

Método

Descripción

ClientsAreListening

Esta propiedad estática especifica si hay alguna aplicación cliente suscrita a los eventos de Automatización de la interfaz de usuario.

IRawElementProviderAdviseEvents

La implementación del proveedor de esta interfaz en una raíz de fragmento permite recibir información cada vez que los clientes registren controladores de eventos y los eliminen en el fragmento.

No es necesario que los proveedores correspondientes a los controles sencillos, como un botón personalizado hospedado en una ventana (HWND), admitan la navegación dentro del árbol de Automatización de la interfaz de usuario. La navegación hasta el elemento y desde él se administra mediante el proveedor predeterminado de la ventana host, que se especifica en la implementación de HostRawElementProvider. Al implementar un proveedor para un control personalizado complejo, sin embargo, debe admitir la navegación entre el nodo raíz del fragmento y sus descendientes, así como entre los nodos relacionados.

Nota:

Los elementos de un fragmento que no sean la raíz deben devolver una referencia null desde la propiedad HostRawElementProvider, porque no se hospedan directamente en una ventana y ningún proveedor predeterminado admite la navegación hasta ellos y desde ellos.

La implementación de Navigate determina la estructura del fragmento. Para cada dirección posible desde cada fragmento, este método devuelve el objeto de proveedor del elemento en esa dirección. Si no hay ningún elemento en esa dirección, el método devuelve una referencia null.

La raíz del fragmento sólo admite la navegación a los elementos secundarios. Por ejemplo, un cuadro de lista devuelve el primer elemento de la lista cuando la dirección es FirstChild y devuelve el último elemento cuando la dirección es LastChild. La raíz del fragmento no admite la navegación a un elemento primario o a elementos del mismo nivel; esto lo administra el proveedor de la ventana host.

Los elementos de un fragmento que no sea la raíz deben admitir la navegación al elemento primario y los elementos secundarios y del mismo nivel que tengan.

Cambio de elemento primario para proveedores que no son WPF

Las ventanas emergentes son realmente ventanas de nivel superior; por ello, aparecen de manera predeterminada en el árbol de Automatización de la interfaz de usuario como elementos secundarios del escritorio. Sin embargo, en muchos casos las ventanas emergentes son lógicamente elementos secundarios de algún otro control. Por ejemplo, la lista desplegable de un cuadro combinado es lógicamente un elemento secundario del cuadro combinado. De igual forma, una ventana emergente del menú es, desde un punto de vista lógico, un elemento secundario del menú. Automatización de la interfaz de usuario proporciona compatibilidad para cambiar los elementos primarios de ventanas emergentes de forma que aparezcan como elementos secundarios del control asociado.

Para cambiar el elemento primario de una ventana emergente:

  1. Cree un proveedor para la ventana emergente. Para ello, se requiere que la clase de la ventana emergente se conozca de antemano.

  2. Implemente, como de costumbre, todas las propiedades y todos los modelos correspondientes a la ventana emergente, como si fuera un control de pleno derecho.

  3. Implemente la propiedad HostRawElementProvider para que devuelva el valor obtenido de HostProviderFromHandle, donde el parámetro es el identificador de ventana de la ventana emergente.

  4. Implemente Navigate para la ventana emergente y su elemento primario, de manera que la navegación se administre correctamente desde elemento primario lógico hasta los elementos secundarios lógicos, así como entre los elementos secundarios del mismo nivel.

Cuando la Automatización de la interfaz de usuario encuentra la ventana emergente, reconoce que se ha invalidado el comportamiento de navegación predeterminado y omite la ventana emergente cuando la encuentra como elemento secundario del escritorio. En su lugar, únicamente se puede tener acceso al nodo a través del fragmento.

No es conveniente cambiar el elemento primario en aquellos casos donde un control puede hospedar una ventana de cualquier clase. Por ejemplo, un rebar pueden hospedar cualquier tipo de HWND en sus bandas. Para administrar estos casos, la Automatización de la interfaz de usuario admite una fórmula alternativa de reubicación de indicadores HWND, que se describe en la sección siguiente.

Cambio de posición de proveedores que no son WPF

Los fragmentos de Automatización de la interfaz de usuario pueden contener dos o más elementos, cada uno de ellos incluido en una ventana (HWND). Dado que cada indicador HWND tiene su propio proveedor predeterminado, que considera que el indicador HWND es un elemento secundario de un indicador HWND contenedor, el árbol de Automatización de la interfaz de usuario mostrará, de forma predeterminada, los indicadores HWND del fragmento como elementos secundarios de la ventana primaria. En la mayoría de los casos, este es el comportamiento deseable. Sin embargo, a veces puede llevar a confusión porque no coincide con la estructura lógica de la interfaz de usuario.

Un buen ejemplo de esto es un control rebar. Un rebar contiene bandas, cada una de las cuales puede contener, a su vez, un control basado en un indicador HWND, como una barra de herramientas, un cuadro de edición o un cuadro combinado. El proveedor de ventana predeterminado del indicador HWND del rebar considera el indicador HWND del control de banda como elemento secundario y el proveedor del control rebar considera las bandas como elementos secundarios. Dado que el proveedor del indicador HWND y el proveedor del rebar funcionan en tándem y combinan sus elementos secundarios, tanto las bandas como los controles basados en indicadores HWND aparecen como elementos secundarios del rebar. Sin embargo, desde el punto de vista lógico, únicamente las bandas deberían aparecer como elementos secundarios del rebar y el proveedor de cada banda debería acoplarse con el proveedor del indicador HWND predeterminado correspondiente al control que contiene.

Para lograr esto, el proveedor de la raíz del fragmento del rebar expone un conjunto de elementos secundarios que representan las bandas. Cada banda tiene un proveedor único que puede exponer propiedades y modelos. En su implementación de HostRawElementProvider, el proveedor de la banda devuelve el proveedor de ventana predeterminado para el indicador HWND del control, que obtiene llamando a HostProviderFromHandle, y pasa el identificador de ventana del control. Por último, el proveedor de la raíz del fragmento del rebar implementa la interfaz IRawElementProviderHwndOverride y, en su implementación de GetOverrideProviderForHwnd, devuelve el proveedor de banda adecuado para el control contenido en el indicador HWND especificado.

Vea también

Tareas

Expose a Server-side UI Automation Provider

Return Properties from a UI Automation Provider

Raise Events from a UI Automation Provider

Enable Navigation in a UI Automation Fragment Provider

Support Control Patterns in a UI Automation Provider

Ejemplo Simple Provider

Ejemplo Fragment Provider

Conceptos

UI Automation Providers Overview