Modelli di controllo Text e TextRange

Vengono descritte le linee guida e le convenzioni per l'implementazione di ITextProvider, ITextProvider2 e ITextRangeProvider, incluse informazioni sulle proprietà e sui metodi. Il pattern di controllo Testo consente alle applicazioni e ai controlli di esporre un semplice modello a oggetti di testo, consentendo ai client di recuperare contenuto testuale, attributi di testo e oggetti incorporati da controlli basati su testo.

Per supportare il pattern di controllo Text, i controlli implementano le interfacce ITextProvider e ITextProvider2. I tipi di controllo che devono supportare il pattern di controllo Text includono i tipi di controllo Edit e Document e qualsiasi altro tipo di controllo che consente all'utente di immettere testo o selezionare testo di sola lettura.

Il pattern di controllo Testo può essere usato con altri pattern di controllo di Microsoft Automazione interfaccia utente per supportare diversi tipi di oggetti incorporati nel testo, tra cui tabelle, collegamenti ipertestuali e pulsanti di comando.

Le interfacce ITextProvider e ITextProvider2 includono diversi metodi per l'acquisizione di intervalli di testo. Un intervallo di testo è un oggetto che rappresenta un intervallo contiguo di testo, o più intervalli di testo non contigui, in un contenitore di testo. Un metodo ITextProvider acquisisce un intervallo di testo che rappresenta l'intero documento, mentre altri acquisiscono intervalli di testo che rappresentano una parte del documento, ad esempio il testo selezionato, il testo visibile o un oggetto incorporato nel testo.

Un oggetto intervallo di testo è rappresentato dal pattern di controllo TextRange , implementato tramite l'interfaccia ITextRangeProvider . Il pattern di controllo TextRange fornisce metodi e proprietà utilizzati per esporre informazioni sul testo nell'intervallo, spostare gli endpoint dell'intervallo, selezionare o deselezionare il testo, scorrere l'intervallo in visualizzazione e così via.

Per altre informazioni sui pattern di controllo Text e TextRange, vedere Automazione interfaccia utente Supporto per il contenuto testuale.

A partire da Windows 8.1 provider può implementare l'interfaccia ITextRangeProvider2. Ciò consente di richiamare i menu di scelta rapida associati a un intervallo di testo. Ciò supporta scenari come la correzione automatica del testo o la selezione candidata dell'editor di metodi di input (IME).

In questo argomento sono contenute le sezioni seguenti.

Linee guida e convenzioni di implementazione

Quando si implementa il pattern di controllo Testo , tenere presenti le linee guida e le convenzioni seguenti:

  • Qualsiasi controllo che consente l'accesso al testo (ad esempio, l'immissione di testo o la selezione di testo di sola lettura) deve supportare il pattern di controllo Testo .
  • Il pattern di controllo Testo può essere usato con qualsiasi elemento dell'interfaccia utente che presenta testo, anche un'etichetta statica in un controllo pulsante standard. Non è tuttavia necessario nei controlli di testo statici che non possono essere selezionati o non hanno un punto di inserimento.
  • Per garantire che il testo sia completamente accessibile, i controlli che implementano ITextProvider devono supportare anche l'interfaccia IValueProvider . IValueProvider integra ITextProvider fornendo un modo programmatico per modificare il testo. Offre anche una maggiore compatibilità con le applicazioni client assistive technology, incluse quelle basate su tecnologie legacy come Microsoft Active Accessibility. Quando vengono implementati entrambi i pattern di controllo, l'evento TextChanged (UIA_Text_TextChangedEventId) e l'evento AutomationPropertyChanged (UIA_AutomationPropertyChangedEventId) sono equivalenti per la proprietà Value (UIA_ValueValuePropertyId). Entrambi gli eventi devono essere supportati.
  • Il pattern di controllo Text supporta un solo flusso di testo e un viewport per ogni controllo. Se l'applicazione offre più visualizzazioni del documento nei riquadri, ogni visualizzazione (controllo) deve supportare ITextProvider in modo indipendente.
  • Il metodo ITextProvider::GetSelection può restituire un singolo intervallo di testo che rappresenta il testo attualmente selezionato. Se un controllo supporta la selezione di più intervalli di testo non contigui, il metodo GetSelection deve restituire una matrice contenente un'interfaccia ITextRangeProvider per ogni intervallo di testo selezionato.
  • Il pattern di controllo Text rappresenta il punto di inserimento come intervallo di testo degenerato (vuoto). Il metodo ITextProvider::GetSelection deve restituire un intervallo di testo degenerato quando il punto di inserimento esiste e non è selezionato alcun testo. Per altre informazioni, vedere Interoperabilità con il cursore di sistema.
  • Il metodo ITextProvider::GetVisibleRanges può restituire un singolo intervallo di testo se un intervallo di testo contiguo è visibile nel riquadro di visualizzazione oppure può restituire una matrice di intervalli di testo non contigui che rappresentano più righe parzialmente visibili di testo.
  • Il metodo ITextProvider::RangeFromChild deve restituire un intervallo degenerato se l'elemento figlio non contiene testo. Poiché un oggetto incorporato può includere testo, il metodo RangeFromChild potrebbe non restituire sempre un intervallo di testo degenerato. Per altre informazioni, vedere How Automazione interfaccia utente Exposes Embedded Objects.For more information, see How Automazione interfaccia utente Exposes Embedded Objects.
  • Il metodo ITextProvider::RangeFromPoint esegue hit testing nell'area del documento usando le coordinate dello schermo specificate. L'intervallo di testo risultante deve essere coerente con il punto di inserimento o la selezione risultante facendo clic sulla posizione in corrispondenza delle coordinate dello schermo specificate. Ad esempio, se un'immagine si trova nelle coordinate dello schermo specificate, l'intervallo di testo risultante deve corrispondere all'intervallo di testo acquisito dal metodo ITextProvider::RangeFromChild per l'immagine. Analogamente, se un'applicazione client richiede un intervallo di testo per la posizione al centro del cursore di sistema (il punto di inserimento), l'intervallo di testo risultante deve corrispondere alla posizione del cursore di sistema.
  • La proprietà ITextProvider::D ocumentRange deve sempre fornire un intervallo di testo che includa tutto il testo supportato dall'implementazione ITextProvider corrispondente.
  • L'evento UIA_Text_TextChangedEventId deve essere generato dopo che si verifica una modifica del testo, anche se la modifica non è visibile nel riquadro di visualizzazione. Ad esempio, il provider deve generare l'evento anche se l'utente incolla lo stesso testo esattamente sul testo selezionato.
  • Il UIA_Text_TextSelectionChangedEventId deve essere generato ogni volta che viene modificata la selezione del testo o ogni volta che il punto di inserimento (cursore) si sposta tra il testo.

Quando si implementa il pattern di controllo TextRange , tenere presenti le linee guida e le convenzioni seguenti:

  • Tutti i metodi del pattern di controllo TextRange devono eseguire operazioni di testo indipendentemente dallo stato di visibilità del testo. La visibilità di un intervallo di testo può essere sempre determinata eseguendo una query sull'attributo di testo IsHidden (UIA_IsHiddenAttributeId).
  • Se possibile, un provider deve garantire che eventuali modifiche al testo, ad esempio eliminazioni, inserimenti e spostamenti, vengano riflesse negli oggetti intervallo di testo associati (istanze dell'interfaccia ITextRangeProvider ) e generare un evento UIA_Text_TextChangedEventId . I client possono usare l'evento come suggerimento per confermare le modifiche editoriali apportate al testo di un controllo.
  • Tutti gli oggetti intervallo di testo utilizzati dai metodi ITextRangeProvider::Compare, CompareEndpoints e MoveEndpointByRange devono essere peer della stessa implementazione del pattern di controllo Text .
  • Sebbene non sia obbligatorio, il valore pRetVal recuperato dal metodo ITextRangeProvider::CompareEndpoints può indicare la distanza, in caratteri (TextUnit_Character), tra i due endpoint. Tuttavia, le applicazioni client non devono dipendere dall'accuratezza di pRetVal oltre il valore positivo o negativo.
  • I metodi ITextRangeProvider::ExpandToEnclosingUnit, Move e MoveEndpointByUnit richiedono un'attenta considerazione dell'unità di testo specificata. Per altre informazioni, vedere Modifica di un oggetto TextRange per unità di testo.
  • Per i requisiti di implementazione correlati ai metodi ITextRangeProvider::Select, AddToSelection e RemoveFromSelection , vedere Selezione di testo in un intervallo di testo.
  • I metodi ITextRangeProvider::FindText e FindAttribute eseguono ricerche avanti o indietro per un singolo attributo di testo o stringa di testo corrispondente. Devono restituire NULL se non viene trovata alcuna corrispondenza.
  • Il metodo ITextRangeProvider::GetAttributeValue deve restituire l'indirizzo acquisito dalla funzione UiaGetReservedMixedAttributeValue o UiaGetReservedNotSupportedValue se l'attributo associato varia nell'intervallo o se l'attributo non è supportato dal controllo di testo. La specifica del pattern di controllo TextRange non consente di aggiungere nuovi identificatori di attributo di testo o di modificare la modalità di definizione degli attributi esistenti.
  • Se possibile, il metodo ITextRangeProvider::GetBoundingRectangles deve restituire una matrice contenente un rettangolo di delimitazione per ogni riga di testo completamente o parzialmente visibile in un intervallo di testo. Se ciò non è possibile, il provider può restituire una matrice che contiene i rettangoli di delimitazione solo di linee completamente visibili; Tuttavia, ciò limita la capacità di un'applicazione client di descrivere in modo accurato il modo in cui il testo viene presentato sullo schermo.
  • Il metodo ITextRangeProvider::GetChildren deve restituire tutti gli elementi figlio incorporati in un intervallo di testo, ma non è necessario restituire elementi figlio degli elementi figlio. Ad esempio, se un intervallo di testo contiene una tabella con un numero di celle figlio, il metodo GetChildren può restituire solo l'elemento della tabella e non gli elementi della cella. Per motivi di prestazioni o architetturali, un provider potrebbe non essere in grado di esporre tutti gli oggetti incorporati ospitati in un documento nell'albero di automazione. In questo caso, il provider deve almeno supportare l'enumerazione di oggetti figlio tramite il metodo GetChildren e, come opzione, supporta il modello di controllo VirtualizedItem per il supporto della devirtualizzazione.
  • Il metodo ITextRangeProvider::GetEnclosingElement restituisce in genere il provider di testo che fornisce l'intervallo di testo. Tuttavia, se il provider di testo supporta oggetti figlio, ad esempio tabelle o collegamenti ipertestuali, l'elemento contenitore potrebbe essere un discendente del provider di testo. L'elemento restituito da GetEnclosingElement deve essere l'elemento più vicino all'intervallo di testo specificato. Ad esempio, se l'intervallo di testo si trova in una cella di una tabella, GetEnclosingElement deve restituire la cella contenitore anziché l'elemento table.
  • Il metodo ITextRangeProvider::GetText deve restituire il testo normale nell'intervallo. Per altre informazioni, vedere Acquisizione di testo da un intervallo di testo.
  • La chiamata a ITextRangeProvider::ScrollIntoView deve allineare il testo nel riquadro di visualizzazione del controllo di testo come specificato dal parametro alignToTop . Anche se non esiste alcun requisito in termini di allineamento orizzontale, l'intervallo di testo deve essere visibile sia orizzontalmente che verticalmente. Quando si valuta il parametro alignToTop , un provider deve tenere conto dell'orientamento del controllo di testo e della direzione del flusso del testo. Ad esempio, se alignToTop è TRUE per un controllo di testo orientato verticalmente contenente testo che passa da destra a sinistra, il provider deve allineare l'intervallo di testo al lato destro del riquadro di visualizzazione.
  • Quando si passa attraverso un documento TextUnit_Line, se l'intervallo di testo entra in una tabella incorporata, ogni riga di testo in una cella deve essere considerata come una riga.

Membri obbligatori per ITextProvider

Per implementare l'interfaccia ITextProvider sono necessari i metodi e le proprietà seguenti.

Membri obbligatori Tipo di membro Note
DocumentRange Proprietà Nessuno
SupportedTextSelection Proprietà Nessuno
GetSelection Metodo Nessuno
GetVisibleRanges Metodo Nessuno
RangeFromChild Metodo Nessuno
RangeFromPoint Metodo Nessuno
UIA_Text_TextChangedEventId Evento Nessuno
UIA_Text_TextSelectionChangedEventId Evento Nessuno

 

Per implementare l'interfaccia ITextProvider2 sono necessari i metodi e le proprietà aggiuntivi seguenti.

Membri obbligatori Tipo di membro Note
GetCaretRange Metodo Nessuno
RangeFromAnnotation Metodo Nessuno

 

Membri obbligatori per ITextRangeProvider

Per implementare l'interfaccia ITextRangeProvider sono necessari i metodi e le proprietà seguenti.

Membri obbligatori Tipo di membro Note
AddToSelection Metodo Nessuno
Clone Metodo Nessuno
Confronto Metodo Nessuno
CompareEndpoints Metodo Nessuno
ExpandToEnclosingUnit Metodo Nessuno
FindAttribute Metodo Nessuno
Findtext Metodo Nessuno
GetAttributeValue Metodo Nessuno
GetBoundingRectangles Metodo Nessuno
GetChildren Metodo Nessuno
GetEnclosingElement Metodo Nessuno
Gettext Metodo Nessuno
Sposta Metodo Nessuno
MoveEndpointByUnit Metodo Nessuno
MoveEndpointByRange Metodo Nessuno
Selezionare Metodo Nessuno
ScrollIntoView Metodo Nessuno

 

Per implementare l'interfaccia ITextRangeProvider2 sono necessari i metodi e le proprietà aggiuntivi seguenti.

Membri obbligatori Tipo di membro Note
ShowContextMenu Metodo Vedere la sezione "Implementing ShowContextMenu" (Implementazione di ShowContextMenu)

 

Il pattern di controllo TextRange non ha eventi associati.

Supporto di intervalli di testo

Questa sezione descrive come un provider deve implementare vari metodi delle interfacce ITextRangeProvider e ITextRangeProvider2 per supportare il pattern di controllo TextRange.

Modifica di un intervallo di testo per unità di testo

L'interfaccia ITextRangeProvider fornisce diversi metodi per la modifica e lo spostamento di intervalli di testo in un controllo basato su testo. I metodi ITextRangeProvider::Move, MoveEndpointByUnit e ExpandToEnclosingUnit spostano un intervallo di testo o uno dei relativi endpoint dall'unità di testo specificata, ad esempio carattere, parola, paragrafo e così via. Per altre informazioni, vedere Automazione interfaccia utente unità di testo.

Nonostante il nome, il metodo ITextRangeProvider::ExpandToEnclosingUnit non espande necessariamente un intervallo di testo. Al contrario, "normalizza" un intervallo di testo spostando gli endpoint in modo che l'intervallo includa l'unità di testo specificata. L'intervallo viene espanso se è minore dell'unità specificata o abbreviato se è più lungo dell'unità specificata. È fondamentale che il metodo ExpandToEnclosingUnit normalizzi sempre gli intervalli di testo in modo coerente; in caso contrario, altri aspetti della manipolazione dell'intervallo di testo da parte dell'unità di testo sarebbero imprevedibili. Il diagramma seguente mostra come ExpandToEnclosingUnit normalizza un intervallo di testo spostando gli endpoint dell'intervallo.

Diagramma che mostra le posizioni dell'endpoint dell'intervallo di testo prima e dopo una chiamata a expandtoenclosingunit

Se l'intervallo di testo inizia all'inizio di un'unità di testo e termina all'inizio di o prima, il successivo limite dell'unità di testo, l'endpoint finale viene spostato al limite successivo dell'unità di testo (vedere 1 e 2 nel diagramma precedente).

Se l'intervallo di testo inizia all'inizio di un'unità di testo e termina in corrispondenza o dopo, il limite dell'unità successiva, l'endpoint finale rimane o viene spostato all'indietro al limite dell'unità successiva dopo l'endpoint iniziale (vedere 3 e 4 nella figura precedente). Se sono presenti più limiti di unità di testo tra gli endpoint iniziale e finale, l'endpoint finale viene spostato all'indietro fino al limite dell'unità successiva dopo l'endpoint iniziale, con conseguente intervallo di testo di una singola unità di testo.

Se l'intervallo di testo inizia a metà dell'unità di testo, l'endpoint iniziale viene spostato all'indietro all'inizio dell'unità di testo e l'endpoint finale viene spostato avanti o indietro, se necessario, al limite dell'unità successiva dopo l'endpoint iniziale (vedere da 5 a 8 nel diagramma precedente).

Quando viene chiamato il metodo ITextRangeProvider::Move , il provider normalizza l'intervallo di testo in base all'unità di testo specificata, usando la stessa logica di normalizzazione del metodo ExpandToEnclosingUnit . Il provider sposta quindi l'intervallo indietro o avanti in base al numero specificato di unità di testo. Quando si sposta l'intervallo, il provider deve ignorare i limiti di qualsiasi oggetto incorporato nel testo. Il limite di unità può tuttavia essere influenzato dall'esistenza di un oggetto incorporato. Il diagramma seguente illustra come il metodo Move sposta un intervallo di testo, un'unità per unità, tra oggetti incorporati e limiti di unità di testo.

Diagramma che mostra come il metodo di spostamento sposta gli endpoint dell'intervallo tra i limiti dell'oggetto e dell'unità di testo

Il metodo ITextRangeProvider::MoveEndpointByUnit sposta uno degli endpoint in avanti o indietro in base all'unità di testo specificata, come illustrato nella figura seguente.

diagramma che mostra come moveendpointbyunit sposta l'endpoint di un intervallo

Il metodo ITextRangeProvider::MoveEndpointByRange consente a un'applicazione client di impostare un endpoint di un intervallo di testo sulla stessa posizione dell'endpoint specificato di un secondo intervallo di testo.

Selezione di testo in un intervallo di testo

L'interfaccia ITextRangeProvider include diversi metodi per controllare la selezione del testo in un controllo basato su testo.

Il metodo ITextRangeProvider::Select deve selezionare il testo corrispondente a un intervallo di testo e rimuovere la selezione precedente, se presente, dal controllo di testo. Se Select viene chiamato su un intervallo di testo degenerato, il provider deve spostare il punto di inserimento nella posizione dell'intervallo di testo senza selezionare alcun testo.

Se un controllo supporta la selezione di più intervalli di testo non contigui, i metodi ITextRangeProvider::AddToSelection e RemoveFromSelection aggiungono intervalli di testo e li rimuovono dalla raccolta di intervalli di testo selezionati. Se il controllo supporta un solo intervallo di testo selezionato alla volta, ma l'operazione di selezione determina la selezione di più intervalli di testo non contigui, il provider deve restituire un errore E_INVALIDOPERATION oppure estendere o troncare la selezione corrente. La proprietà ITextProvider::SupportedTextSelection deve indicare se un controllo supporta la selezione di uno o più intervalli di testo o nessuno.

Se un controllo basato su testo supporta inserimenti di testo, chiamare ITextRangeProvider::AddToSelection o RemoveFromSelection in un intervallo di testo degenerato nel controllo deve spostare il punto di inserimento ma non selezionare alcun testo.

Acquisizione di testo da un intervallo di testo

Il metodo ITextRangeProvider::GetText deve restituire il testo normale di un intervallo di testo. Il testo normale deve includere tutti i caratteri di controllo presenti nel testo di origine, ad esempio ritorni a capo e il contrassegno Unicode da sinistra a destra (LRM). Il testo normale non deve includere tag di markup, ad esempio HTML, che possono essere presenti nel testo di origine. Inoltre, tutti i codici di escape nel testo di origine devono essere convertiti negli equivalenti di testo normale. Ad esempio, " " deve essere convertito in un carattere di spazio semplice.

Se un oggetto incorporato si estende su un intervallo di testo, il testo normale deve includere il testo interno dell'oggetto, ma non il testo alternativo (la proprietà name dell'oggetto incorporato) perché potrebbe non essere coerente con il testo interno descrittivo. Per altre informazioni, vedere How Automazione interfaccia utente Exposes Embedded Objects.For more information, see How Automazione interfaccia utente Exposes Embedded Objects.

Implementazione di ShowContextMenu

ITextRangeProvider2::ShowContextMenu deve sempre mostrare il menu di scelta rapida all'estremità iniziale dell'intervallo. Questo dovrebbe essere equivalente a ciò che accadrebbe se l'utente ha premuto il tasto di scelta rapida o MAIUSC + F10 con il punto di inserimento all'inizio dell'intervallo.

Se la visualizzazione del menu di scelta rapida comporta in genere lo spostamento del punto di inserimento in una determinata posizione, deve farlo anche per richiamare ShowContextMenu a livello di codice per Automazione interfaccia utente supporto.

Interoperabilità con il cursore di sistema

Il supporto corretto del punto di inserimento è fondamentale per molte applicazioni client, incluse quelle non basate su Automazione interfaccia utente. Nel pattern di controllo Text il punto di inserimento è rappresentato da un intervallo di testo degenerato (vuoto) nella posizione del cursore di sistema. Quando il punto di inserimento viene spostato, un controllo deve generare l'evento TextSelectionChanged (UIA_Text_TextSelectionChangedEventId). Alcune applicazioni client dipendono da questo evento per monitorare la posizione del punto di inserimento e per tenere traccia della selezione del testo.

Quando un controllo contiene testo selezionato, la struttura corrente del pattern di controllo Testo non consente di associare direttamente la posizione del punto di inserimento a un intervallo di testo specifico. Il provider deve tenere traccia della selezione del testo e impostare la posizione del punto di inserimento in modo appropriato. Poiché la selezione del testo viene in genere eseguita spostando il punto di inserimento tenendo premuto MAIUSC o CTRL oppure entrambi, un provider può tenere traccia della selezione del testo controllando lo stato di questi tasti ogni volta che la selezione cambia.

Poiché il framework di accessibilità fornisce il supporto predefinito per il cursore di sistema, ma non per un cursore personalizzato, i controlli basati su testo devono usare il cursore di sistema quando possibile. I controlli che usano un punto di inserimento personalizzato possono garantire che il cursore sia accessibile creando un cursore di sistema con le stesse dimensioni del punto di inserimento personalizzato e posizionando il cursore di sistema nella stessa posizione nell'interfaccia utente del controllo del cursore personalizzato, ovvero nel punto di inserimento. In alternativa, un controllo che usa un cursore personalizzato può implementare un provider di accessibilità Microsoft Active per OBJID_CARET per fornire informazioni di accessibilità direttamente per il cursore personalizzato.

Per altre informazioni sul cursore di sistema, vedere Carets.

Per verificare se il controllo espone correttamente la posizione del cursore di sistema, usare gli strumenti Inspect e Accessible Event Watcher .

Le coordinate dello schermo del centro della bitmap del cursore di sistema devono sempre corrispondere alla posizione del punto di inserimento. In questo modo, un client può usare le coordinate dello schermo del cursore in una chiamata a ITextProvider::RangeFromPoint per recuperare un intervallo di testo che rappresenta in modo accurato la posizione del punto di inserimento.

Tipi di controllo e modelli di controllo supportati

Tipo di controllo testo

Pattern di controllo TextEdit

Pattern di controllo TextChild

Cenni preliminari sui pattern di controllo per l'automazione interfaccia utente

supporto di Automazione interfaccia utente per il contenuto testuale

Panoramica dell'albero di automazione dell'interfaccia utente