Patrones de control Text y TextRange

Describe instrucciones y convenciones para implementar ITextProvider, ITextProvider2 e ITextRangeProvider, incluida información sobre propiedades y métodos. El patrón de control Text permite a las aplicaciones y controles exponer un modelo de objetos de texto simple, lo que permite a los clientes recuperar contenido textual, atributos de texto y objetos incrustados de controles basados en texto.

Para admitir el patrón de control Text , los controles implementan las interfaces ITextProvider e ITextProvider2 . Los tipos de control que deben admitir el patrón de control Texto incluyen los tipos de control Editar y Documento , y cualquier otro tipo de control que permita al usuario escribir texto o seleccionar texto de solo lectura.

El patrón de control Text se puede usar con otros patrones de control de Microsoft Automatización de la interfaz de usuario para admitir varios tipos de objetos incrustados en el texto, incluidas tablas, hipervínculos y botones de comando.

Las interfaces ITextProvider e ITextProvider2 incluyen una serie de métodos para adquirir intervalos de texto. Un intervalo de texto es un objeto que representa un intervalo contiguo de texto (o varios intervalos separados de texto) en un contenedor de texto. Un método ITextProvider adquiere un intervalo de texto que representa todo el documento, mientras que otros adquieren intervalos de texto que representan parte del documento, como el texto seleccionado, el texto visible o un objeto incrustado en el texto.

Un objeto de intervalo de texto se representa mediante el patrón de control TextRange , que se implementa a través de la interfaz ITextRangeProvider . El patrón de control TextRange proporciona métodos y propiedades que se usan para exponer información sobre el texto del intervalo, mover los puntos de conexión del intervalo, seleccionar o anular la selección de texto, desplazar el intervalo a la vista, etc.

Para obtener más información sobre los patrones de control Text y TextRange, vea Automatización de la interfaz de usuario Compatibilidad con contenido textual.

A partir de Windows 8.1 proveedores puede implementar la interfaz ITextRangeProvider2. Esto permite invocar menús contextuales asociados a un intervalo de texto. Esto admite escenarios como la autocorrección de texto o la selección candidata del Editor de métodos de entrada (IME).

En este tema se incluyen las siguientes secciones.

Directrices y convenciones de implementación

Al implementar el patrón de control Text , tenga en cuenta las siguientes directrices y convenciones:

  • Cualquier control que permita el acceso al texto (por ejemplo, escribir texto o seleccionar texto de solo lectura) debe admitir el patrón de control Texto .
  • El patrón de control Text se puede usar con cualquier elemento de interfaz de usuario que presente texto, incluso una etiqueta estática en un control de botón estándar. Sin embargo, no es necesario en los controles de texto estático que no se pueden seleccionar o no tienen un punto de inserción.
  • Para asegurarse de que el texto es totalmente accesible, los controles que implementan ITextProvider también deben admitir la interfaz IValueProvider . IValueProvider complementa ITextProvider proporcionando una manera programática de cambiar el texto. También ofrece una mayor compatibilidad con las aplicaciones cliente de tecnología de asistencia, incluidas las basadas en tecnologías heredadas, como la accesibilidad activa de Microsoft. Cuando se implementan ambos patrones de control, el evento TextChanged (UIA_Text_TextChangedEventId) y el evento AutomationPropertyChanged (UIA_AutomationPropertyChangedEventId) son equivalentes para la propiedad Value (UIA_ValueValuePropertyId). Se deben admitir ambos eventos.
  • El patrón de control Texto solo admite una secuencia de texto y una ventanilla por control. Si la aplicación ofrece varias vistas del documento en paneles, cada vista (control) debe admitir ITextProvider de forma independiente.
  • El método ITextProvider::GetSelection puede devolver un único intervalo de texto que represente el texto seleccionado actualmente. Si un control admite la selección de varios intervalos de texto no contiguos, el método GetSelection debe devolver una matriz que contenga una interfaz ITextRangeProvider para cada intervalo de texto seleccionado.
  • El patrón de control Texto representa el punto de inserción como un intervalo de texto degenerado (vacío). El método ITextProvider::GetSelection debe devolver un intervalo de texto degenerado cuando exista el punto de inserción y no se seleccione ningún texto. Para obtener más información, vea Interoperabilidad con el símbolo de intercalación del sistema.
  • El método ITextProvider::GetVisibleRanges puede devolver un único intervalo de texto si un intervalo contiguo de texto está visible en la ventanilla o puede devolver una matriz de intervalos de texto separados que representan varias líneas de texto parcialmente visibles.
  • El método ITextProvider::RangeFromChild debe devolver un intervalo degenerado si el elemento secundario no contiene texto. Dado que un objeto incrustado puede incluir texto, es posible que el método RangeFromChild no siempre devuelva un intervalo de texto degenerado. Para obtener más información, vea Cómo Automatización de la interfaz de usuario expone objetos incrustados.
  • El método ITextProvider::RangeFromPoint realiza pruebas de posicionamiento en el área de documento utilizando las coordenadas de pantalla especificadas. El intervalo de texto resultante debe ser coherente con el punto de inserción o la selección que resultaría de hacer clic en la ubicación en las coordenadas de pantalla especificadas. Por ejemplo, si una imagen reside en las coordenadas de pantalla especificadas, el intervalo de texto resultante debe ser el mismo que el intervalo de texto que el método ITextProvider::RangeFromChild adquiriría para la imagen. Del mismo modo, si una aplicación cliente solicita un intervalo de texto para la ubicación en el centro del símbolo de intercalación del sistema (el punto de inserción), el intervalo de texto resultante debe ser el mismo que la ubicación del símbolo de intercalación del sistema.
  • La propiedad ITextProvider::D ocumentRange siempre debe proporcionar un intervalo de texto que incluya todo el texto admitido por la implementación de ITextProvider correspondiente.
  • El evento UIA_Text_TextChangedEventId debe generarse después de que se produzca cualquier cambio de texto, incluso si el cambio no está visible en la ventanilla. Por ejemplo, el proveedor debe generar el evento incluso si el usuario pega exactamente el mismo texto sobre el texto seleccionado.
  • El UIA_Text_TextSelectionChangedEventId debe generarse siempre que la selección de texto cambie o cuando el punto de inserción (símbolo de intercalación) se mueva entre el texto.

Al implementar el patrón de control TextRange , tenga en cuenta las siguientes directrices y convenciones:

  • Todos los métodos del patrón de control TextRange deben realizar operaciones de texto independientemente del estado de visibilidad del texto. La visibilidad de un intervalo de texto siempre se puede determinar consultando el atributo de texto IsHidden (UIA_IsHiddenAttributeId).
  • Si es posible, un proveedor debe asegurarse de que cualquier cambio de texto, como eliminaciones, inserciones y movimientos, se refleje en los objetos de intervalo de texto asociados (instancias de la interfaz ITextRangeProvider ) y genere un evento de UIA_Text_TextChangedEventId . Los clientes pueden usar el evento como sugerencia para confirmar los cambios editoriales realizados en el texto de un control.
  • Todos los objetos de intervalo de texto utilizados por los métodos ITextRangeProvider::Compare, CompareEndpoints y MoveEndpointByRange deben ser elementos del mismo nivel de la misma implementación del patrón de control Text .
  • Aunque no es necesario, el valor pRetVal recuperado por el método ITextRangeProvider::CompareEndpoints puede indicar la distancia, en caracteres (TextUnit_Character), entre los dos extremos. Sin embargo, las aplicaciones cliente no deben depender de la precisión de pRetVal más allá de su valor positivo o negativo.
  • Los métodos ITextRangeProvider::ExpandToEnclosingUnit, Move y MoveEndpointByUnit requieren una cuidadosa consideración de la unidad de texto especificada. Para obtener más información, vea Manipular un textRange por unidad de texto.
  • Para conocer los requisitos de implementación relacionados con los métodos ITextRangeProvider::Select, AddToSelection y RemoveFromSelection , vea Seleccionar texto en un intervalo de texto.
  • Los métodos ITextRangeProvider::FindText y FindAttribute buscan hacia delante o hacia atrás una sola cadena de texto o atributo de texto coincidente. Deben devolver NULL si no se encuentra ninguna coincidencia.
  • El método ITextRangeProvider::GetAttributeValue debe devolver la dirección adquirida desde la función UiaGetReservedMixedAttributeValue o UiaGetReservedNotSupportedValue si el atributo asociado varía en el intervalo o si el atributo no es compatible con el control de texto. La especificación del patrón de control TextRange no permite agregar nuevos identificadores de atributo de texto ni cambiar cómo se definen los atributos existentes.
  • Si es posible, el método ITextRangeProvider::GetBoundingRectangles debe devolver una matriz que contenga un rectángulo delimitador para cada línea de texto totalmente o parcialmente visible en un intervalo de texto. Si esto no es posible, el proveedor puede devolver una matriz que contenga los rectángulos delimitadores de solo líneas totalmente visibles; sin embargo, esto limita la capacidad de una aplicación cliente para describir con precisión cómo se presenta el texto en la pantalla.
  • El método ITextRangeProvider::GetChildren debe devolver todos los elementos secundarios incrustados en un intervalo de texto, pero no es necesario devolver ningún elemento secundario de los elementos secundarios. Por ejemplo, si un intervalo de texto contiene una tabla que tiene una serie de celdas secundarias , el método GetChildren puede devolver solo el elemento table y no los elementos de celda. Por motivos de rendimiento o arquitectura, es posible que un proveedor no pueda exponer todos los objetos incrustados hospedados en un documento en el árbol de automatización. En este caso, el proveedor debe admitir al menos la enumeración de objetos secundarios a través del método GetChildren y, como opción, admitir el patrón de control VirtualizedItem para la compatibilidad con la des virtualización.
  • El método ITextRangeProvider::GetEnclosingElement normalmente devuelve el proveedor de texto que proporciona el intervalo de texto. Sin embargo, si el proveedor de texto admite objetos secundarios como tablas o hipervínculos, el elemento envolvente podría ser un descendiente del proveedor de texto. El elemento devuelto por GetEnclosingElement debe ser el elemento más cercano al intervalo de texto especificado. Por ejemplo, si el intervalo de texto está en una celda de una tabla, GetEnclosingElement debe devolver la celda contenedora en lugar del elemento table.
  • El método ITextRangeProvider::GetText debe devolver el texto sin formato en el intervalo. Para obtener más información, consulte Adquisición de texto de un intervalo de texto.
  • La llamada a ITextRangeProvider::ScrollIntoView debe alinear el texto en la ventanilla del control de texto según lo especificado por el parámetro alignToTop . Aunque no hay ningún requisito en términos de alineación horizontal, el intervalo de texto debe ser visible tanto horizontal como verticalmente. Al evaluar el parámetro alignToTop , un proveedor debe tener en cuenta la orientación del control de texto y la dirección de flujo del texto. Por ejemplo, si alignToTop es TRUE para un control de texto orientado verticalmente que contiene texto que fluye de derecha a izquierda, el proveedor debe alinear el intervalo de texto con el lado derecho de la ventanilla.
  • Al desplazarse por un documento TextUnit_Line, si el intervalo de texto entra en una tabla incrustada, cada línea de texto de una celda debe tratarse como una línea.

Miembros necesarios para ITextProvider

Se requieren las siguientes propiedades y métodos para implementar la interfaz ITextProvider .

Miembros requeridos Tipo de miembro Notas
DocumentRange Propiedad None
SupportedTextSelection Propiedad None
GetSelection Método None
GetVisibleRanges Método None
RangeFromChild Método None
RangeFromPoint Método None
UIA_Text_TextChangedEventId Evento None
UIA_Text_TextSelectionChangedEventId Evento None

 

Se requieren las siguientes propiedades y métodos adicionales para implementar la interfaz ITextProvider2 .

Miembros requeridos Tipo de miembro Notas
GetCaretRange Método None
RangeFromAnnotation Método None

 

Miembros necesarios para ITextRangeProvider

Se requieren las siguientes propiedades y métodos para implementar la interfaz ITextRangeProvider .

Miembros requeridos Tipo de miembro Notas
AddToSelection Método None
Clon Método None
Comparación Método None
CompareEndpoints Método None
ExpandToEnclosingUnit Método None
FindAttribute Método None
FindText Método None
GetAttributeValue Método None
GetBoundingRectangles Método None
GetChildren Método None
GetEnclosingElement Método None
Gettext Método None
Mover Método None
MoveEndpointByUnit Método None
MoveEndpointByRange Método None
Seleccionar Método None
ScrollIntoView Método None

 

Se requieren las siguientes propiedades y métodos adicionales para implementar la interfaz ITextRangeProvider2 .

Miembros requeridos Tipo de miembro Notas
ShowContextMenu Método Consulte la sección "Implementación de ShowContextMenu".

 

El patrón de control TextRange no tiene eventos asociados.

Compatibilidad con intervalos de texto

En esta sección se describe cómo un proveedor debe implementar varios métodos de las interfaces ITextRangeProvider e ITextRangeProvider2 para admitir el patrón de control TextRange .

Manipular un intervalo de texto por unidad de texto

La interfaz ITextRangeProvider proporciona varios métodos para manipular y navegar por intervalos de texto en un control basado en texto. Los métodos ITextRangeProvider::Move, MoveEndpointByUnit y ExpandToEnclosingUnit mueven un intervalo de texto o uno de sus extremos por la unidad de texto especificada, como carácter, palabra, párrafo, etc. Para obtener más información, vea Automatización de la interfaz de usuario Unidades de texto.

A pesar de su nombre, el método ITextRangeProvider::ExpandToEnclosingUnit no expande necesariamente un intervalo de texto. En su lugar, "normaliza" un intervalo de texto moviendo los puntos de conexión para que el intervalo abarque la unidad de texto especificada. El intervalo se expande si es menor que la unidad especificada o se acorta si es mayor que la unidad especificada. Es fundamental que el método ExpandToEnclosingUnit normalice siempre los intervalos de texto de manera coherente; de lo contrario, otros aspectos de la manipulación del intervalo de texto por unidad de texto serían impredecibles. En el diagrama siguiente se muestra cómo ExpandToEnclosingUnit normaliza un intervalo de texto moviendo los puntos de conexión del intervalo.

diagrama que muestra las posiciones del punto de conexión del intervalo de texto antes y después de una llamada a expandtoenclosingunit

Si el intervalo de texto comienza al principio de una unidad de texto y termina al principio de, o antes, el siguiente límite de unidad de texto, el extremo final se mueve al siguiente límite de unidad de texto (vea 1 y 2 en el diagrama anterior).

Si el intervalo de texto comienza al principio de una unidad de texto y termina en, o después, el siguiente límite de unidad, el extremo final permanece o se mueve hacia atrás al siguiente límite de unidad después del punto de conexión inicial (vea 3 y 4 en la ilustración anterior). Si hay más de un límite de unidad de texto entre los extremos inicial y final, el extremo final se mueve hacia atrás al siguiente límite de unidad después del punto de conexión inicial, lo que da como resultado un intervalo de texto que es una unidad de texto de longitud.

Si el intervalo de texto se inicia en medio de la unidad de texto, el punto de conexión inicial se mueve hacia atrás al principio de la unidad de texto y el extremo final se mueve hacia delante o hacia atrás, según sea necesario, al siguiente límite de unidad después del punto de conexión inicial (vea 5 a 8 en el diagrama anterior).

Cuando se llama al método ITextRangeProvider::Move , el proveedor normaliza el intervalo de texto por la unidad de texto especificada, utilizando la misma lógica de normalización que el método ExpandToEnclosingUnit . A continuación, el proveedor mueve el intervalo hacia atrás o hacia delante por el número especificado de unidades de texto. Al mover el intervalo, el proveedor debe omitir los límites de los objetos incrustados en el texto. (Sin embargo, el propio límite de unidad puede verse afectado por la existencia de un objeto incrustado). En el diagrama siguiente se muestra cómo el método Move mueve un intervalo de texto, una unidad por unidad, entre objetos incrustados y límites de unidad de texto.

diagrama que muestra cómo el método de movimiento mueve los puntos de conexión de intervalo entre los límites de unidad de texto y objeto

El método ITextRangeProvider::MoveEndpointByUnit mueve uno de los puntos de conexión hacia delante o hacia atrás por la unidad de texto especificada, como se muestra en la ilustración siguiente.

diagrama que muestra cómo moveendpointbyunit mueve el punto de conexión de un intervalo

El método ITextRangeProvider::MoveEndpointByRange permite a una aplicación cliente establecer un punto de conexión de un intervalo de texto en la misma ubicación que el extremo especificado de un segundo intervalo de texto.

Seleccionar texto en un intervalo de texto

La interfaz ITextRangeProvider incluye varios métodos para controlar la selección de texto en un control basado en texto.

El método ITextRangeProvider::Select debe seleccionar el texto correspondiente a un intervalo de texto y quitar la selección anterior, si existe, del control de texto. Si se llama a Select en un intervalo de texto degenerado, el proveedor debe mover el punto de inserción a la ubicación del intervalo de texto sin seleccionar ningún texto.

Si un control admite la selección de varios intervalos de texto separados, los métodos ITextRangeProvider::AddToSelection y RemoveFromSelection agregan intervalos de texto a la colección de intervalos de texto seleccionados y los quitan. Si el control solo admite un intervalo de texto seleccionado a la vez, pero la operación de selección daría lugar a la selección de varios intervalos de texto separados, el proveedor debe devolver un error de E_INVALIDOPERATION o debe extender o truncar la selección actual. La propiedad ITextProvider::SupportedTextSelection debe indicar si un control admite la selección de uno o varios intervalos de texto, o ninguno en absoluto.

Si un control basado en texto admite inserciones de texto, llamar a ITextRangeProvider::AddToSelection o RemoveFromSelection en un intervalo de texto degenerado en el control debe mover el punto de inserción, pero no debe seleccionar ningún texto.

Adquisición de texto de un intervalo de texto

El método ITextRangeProvider::GetText debe devolver el texto sin formato de un intervalo de texto. El texto sin formato debe incluir todos los caracteres de control que se encuentran en el texto de origen, como retornos de carro y la marca unicode de izquierda a derecha (LRM). El texto sin formato no debe incluir etiquetas de marcado como HTML que puedan estar presentes en el texto de origen. Además, los códigos de escape del texto de origen deben convertirse en los equivalentes de texto sin formato. Por ejemplo, " " debe convertirse en un carácter de espacio simple.

Si un objeto incrustado abarca un intervalo de texto, el texto sin formato debe incluir el texto interno del objeto, pero no el texto alternativo (la propiedad name del objeto incrustado) porque podría ser incoherente con el texto interno descriptivo. Para obtener más información, vea Cómo Automatización de la interfaz de usuario expone objetos incrustados.

Implementación de ShowContextMenu

ITextRangeProvider2::ShowContextMenu siempre debe mostrar el menú contextual en el punto final inicial del intervalo. Esto debería ser equivalente a lo que sucedería si el usuario presionase la tecla de menú contextual o MAYÚS + F10 con el punto de inserción al principio del intervalo.

Si mostrar el menú contextual suele dar lugar a que el punto de inserción se mueva a una ubicación determinada, debe hacerlo también para invocar mediante programación ShowContextMenu para Automatización de la interfaz de usuario compatibilidad.

Interoperabilidad con el símbolo de intercalación del sistema

Admitir correctamente el punto de inserción es fundamental para muchas aplicaciones cliente, incluidas las que no se basan en Automatización de la interfaz de usuario. En el patrón de control Texto , el punto de inserción se representa mediante un intervalo de texto degenerado (vacío) en la posición del símbolo de intercalación del sistema. Cuando se mueve el punto de inserción, un control debe generar el evento TextSelectionChanged (UIA_Text_TextSelectionChangedEventId). Algunas aplicaciones cliente dependen de este evento para supervisar la ubicación del punto de inserción y realizar un seguimiento de la selección de texto.

Cuando un control contiene texto seleccionado, el diseño actual del patrón de control Texto no proporciona una manera de asociar directamente la ubicación del punto de inserción con un intervalo de texto determinado. El proveedor debe realizar un seguimiento de la selección de texto y establecer la ubicación del punto de inserción correctamente. Dado que la selección de texto se realiza normalmente moviendo el punto de inserción mientras mantiene presionada la tecla MAYÚS o CTRL, o ambos, un proveedor puede realizar un seguimiento de la selección de texto comprobando el estado de estas teclas cada vez que cambia la selección.

Dado que el marco de accesibilidad proporciona compatibilidad integrada con el símbolo de intercalación del sistema, pero no para un símbolo de intercalación personalizado, los controles basados en texto deben usar el símbolo de intercalación del sistema siempre que sea posible. Los controles que usan un símbolo de intercalación personalizado pueden garantizar que el símbolo de intercalación sea accesible creando un símbolo de intercalación del sistema que tenga las mismas dimensiones que el símbolo de intercalación personalizado y colocando el símbolo de intercalación del sistema en la misma ubicación del control que el símbolo de intercalación personalizado, es decir, en el punto de inserción. Como alternativa, un control que usa un símbolo de intercalación personalizado puede implementar un proveedor de accesibilidad activo de Microsoft para OBJID_CARET proporcionar información de accesibilidad directamente para el símbolo de intercalación personalizado.

Para obtener más información sobre el símbolo de intercalación del sistema, consulte Carets.

Para probar si el control expone correctamente la ubicación del símbolo de intercalación del sistema, use las herramientas Inspect y Accessible Event Watcher .

Las coordenadas de pantalla del centro del mapa de bits de intercalación del sistema siempre deben coincidir con la ubicación del punto de inserción. De este modo, un cliente puede usar las coordenadas de pantalla de intercalación en una llamada a ITextProvider::RangeFromPoint para recuperar un intervalo de texto que represente con precisión la ubicación del punto de inserción.

Tipos de control y sus patrones de control admitidos

Tipo de control de texto

Patrón de control TextEdit

Patrón de control TextChild

Información general acerca de los patrones de control de UI Automation

compatibilidad de Automatización de la interfaz de usuario con contenido textual

Información general sobre el árbol de la UI Automation