Search code examples
c++cwinapiaccessibilityscreen-readers

Make windows 10 narrator to speak some text


I'm making a GUI application in C++. Is there a simple way to make the narrator of windows 10 to speak some text ? Given of course that it is currently active.

A trick that sometimes works is to select some text in a text field and then focus it briefly. But

  • It doesn't work all the time
  • The focus is moved out and back. Even if it's for a short time, it's invasive and may disturb whatever the user is currently doing
  • The text field must be present at some place on screen, what is not always desired

If possible, I would like a solution without these three issues.

Other screen readers, in particular Jaws and NVDA, provide API to do this. I'm even the author of a library, UniversalSpeech, which allow to make the currently running screen reader, if any, to speak text, abstracting the need to detect yourself which one is running. Given that the narrator has greatly improved with the last 3 or 4 releases of windows 10, it would probably be interesting to support it, not only in my own program and for my particular usecase, but for everybody in my library.

However, I can't find any documentation or anything telling me if the narrator has an API similar to those of Jaws or NVDA. In fact if there is currently no such API for Narrator, it would probably be interesting to suggest Microsoft to add one.

Note that this question is different from such as this one where the answer suggests to use speech API directly. Using screen readers API and not speech API directly has great benefits:

  • Screen reader users are used to specific voice settings (voice, rate, pitch, language and regional accents, etc.). The default settings set in the control panel may not at all be similar. It implies
    • whether the user must configure speech settings in the control panel, what is global for all applications; not very good
    • and/or managing application-specific speech settings in a business application which isn't at all devoted to speech stuff; it would be rather strange to find speech settings in a financial app for example.
  • Using both screen reader and independent speech engine simultenously means that both can speak at the same time, what is of course extremely annoying. In fact in practice it happens quite often, I have already tested.

So, is there a simple way to make narrator to speak some text ?

My program is in C++, the library is in C, so in theory I have access to the whole winapi, through LoadLibrary/GetProcAddress if needed. Please don't give any C# or VisualStudio-dependent solution.

Thank you.


Solution

  • After quite a while, I answer my own question !

    IN fact, the simplest to make narrator speak something is probably to:

    1. Define some label as being a live region
    2. When something has to be spoken by narrator, change the text in the label and then send an update notification

    Turning a label into a live region and sending a notification whenever the text changes is explained here: https://learn.microsoft.com/en-us/accessibility-tools-docs/items/win32/text_livesetting

    Live setting can be set to 0=off, 1=polite and 2=assertive. The meaning of polite and assertive are the same as in WAI ARIA. Though as present (april 2021), narrator always interrupts speech as soon as the text of the label is replaced, even in polite mode. What changes in assertive mode is that the text even take priority against interruptions due to normal keyboard navigation, i.e. you may not hear where you are when pressing tab, arrow keys, etc. For that reason, I don't recommand it at all.

    Note also that live setting only works on static text controls (win32 STATIC window class). It is totally ignored when applied to text fields and text areas (win32 EDIT window class).

    The label with live setting still works when placed off-screen or even hidden.