5

Come rilevare se lo screen reader è in esecuzione (JAWS)?C#: come rilevare se lo screen reader è in esecuzione?

Come ho capito in .NET 4 possiamo usare AutomationInteropProvider.ClientsAreListening dallo spazio dei nomi System.Windows.Automation.Provider, ma cosa succede se devo farlo per .NET 2.0?

Ho provato a ispezionare il codice sorgente ClientsAreListening, chiama il metodo esterno RawUiaClientsAreListening dalla libreria UIAutomationCore.dll.

Avete qualche idea su come implementare il rilevamento JAWS in .NET 2.0?

+0

Curioso, cosa intendi fare diversamente se determini che uno screen reader è in esecuzione? Tieni presente che alcune app non compatibili con screen reader possono impostare il flag SPI_SCREENREADER, in modo da ottenere falsi positivi o negativi. Idealmente la tua app dovrebbe funzionare senza dover controllare questo flag. Stai davvero controllando gli screen reader in generale, o JAWS in particolare? – BrendanMcK

risposta

4

Utilizzare SystemParametersInfo function passando un uiAction di SPI_GETSCREENREADER.

Sarà necessario utilizzare P/Invoke per questo, ad esempio:

internal class UnsafeNativeMethods 
{ 
    public const uint SPI_GETSCREENREADER = 0x0046; 

    [DllImport("user32.dll", SetLastError = true)] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref bool pvParam, uint fWinIni); 
} 

public static class ScreenReader 
{ 
    public static bool IsRunning 
    { 
     get 
     { 
      bool returnValue = false; 
      if (!UnsafeNativeMethods.SystemParametersInfo(UnsafeNativeMethods.SPI_GETSCREENREADER, 0, ref returnValue, 0)) 
      { 
       throw new Win32Exception(Marshal.GetLastWin32Error(), "error calling SystemParametersInfo"); 
      } 
      return returnValue; 
     } 
    } 
} 

Questa è forse meglio che usare la proprietà ClientsAreListening come questa proprietà sembra di tornare vero per qualsiasi client di automazione, non solo screen reader.

Vedi anche:

Si dovrebbe anche ascoltare il messaggio WM_SETTINGCHANGE per rilevare se uno screen reader inizia/interrompe l'esecuzione.


aggiornamento (in risposta ai commenti di BrendanMcK):

Anche se questo non viene mai esplicitamente documentata in altrettante parole, guardando la descrizione della bandiera penso che lo scopo di questo flag è relativamente chiara :

Determina se è in esecuzione un'utilità di revisione dello schermo. Un'utilità di revisione dello schermo indirizza le informazioni testuali a un dispositivo di output, ad esempio un sintetizzatore vocale o un display braille. Quando questo flag è impostato, un'applicazione dovrebbe fornire informazioni testuali in situazioni in cui altrimenti presenterebbe le informazioni graficamente.

Ciò sta dicendo è che le applicazioni impostare questo flag ogni volta che un'applicazione vuole l'interfaccia utente a comportarsi come se un lettore di schermo è in esecuzione, indipendentemente dal fatto o meno che l'applicazione è in realtà uno screen reader o no .

Le cose appropriate da fare in risposta a questo flag sono add text in order to "read" otherwise intuitive UI state to the user. Se sono necessarie modifiche radicali per rendere accessibile lo screen reader per l'interfaccia utente, è probabile che anche l'interfaccia utente non sia intuitiva per gli utenti e potrebbe probabilmente fare con un ripensamento.

+0

Ottimo! Funziona! Grazie! –

+1

Si noti che ClientsAreListening indica solo i client di accessibilità che ascoltano attivamente gli eventi di accessibilità. Ci potrebbero essere altri che usano ancora l'accessibilità - es. per analizzare l'interfaccia utente per i verbi per il riconoscimento vocale, ma utilizzare qualche altro metodo per determinare quando scansionare e non ascoltare gli eventi di accessibilità. In breve, questa API ti consente solo di sapere che è necessario inviare eventi; non se è in esecuzione un client di accessibilità. – BrendanMcK

+0

@BrendanMcK Viceversa il 'SPI_GETSCREENREADER' è semplicemente un flag che viene impostato dagli screen reader per indicare agli altri che sono in esecuzione (indipendentemente dal metodo utilizzato) – Justin