C# : How to detect if screen reader is running?

依然范特西╮ 提交于 2019-11-28 04:23:25

问题


How to detect if screen reader is running (JAWS)?

As I understand in .NET 4 we can use AutomationInteropProvider.ClientsAreListening from System.Windows.Automation.Provider namespace, but what if I have to do it for .NET 2.0?

I tried to inspect ClientsAreListening source code, it calls external RawUiaClientsAreListening method from UIAutomationCore.dll library.

Do you have any ideas how to implement JAWS detection in .NET 2.0?


回答1:


Use the SystemParametersInfo function passing a uiAction of SPI_GETSCREENREADER.

You will need to use P/Invoke for this, for example:

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;
        }
    }
}

This is possibly better than using the ClientsAreListening property as this property appears to return true for any automation client, not just screen readers.

Also see:

  • Using SystemParametersInfo from C# (SPI_GETSCREENREADER SPI_SETSCREENREADER) (Stack Overflow)
  • INFO: How Clients and Servers Should Use SPI_SETSCREENREADER and SPI_GETSCREENREADER (Microsoft KB)

You should also listen for the WM_SETTINGCHANGE message to detect if a screen reader starts / stops running.


Update (in response to BrendanMcK's comments):

Although this is never explicitly documented in as many words, looking at the description of the flag I think the purpose of this flag is relatively clear:

Determines whether a screen reviewer utility is running. A screen reviewer utility directs textual information to an output device, such as a speech synthesizer or Braille display. When this flag is set, an application should provide textual information in situations where it would otherwise present the information graphically.

What this is saying is that applications set this flag whenever an application wishes the UI to behave as if a screen reader is running, regardless of whether or not that application is actually a screen reader or not.

Suitable things to do in response to this flag is to add text in order to "read" otherwise intuitive UI state to the user. If radical changes are needed to make your UI screen reader accessible then the chances are that your UI also isn't that intuitive to sigted users and could probably do with a re-think.



来源:https://stackoverflow.com/questions/8079716/c-sharp-how-to-detect-if-screen-reader-is-running

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!