5

如何檢測屏幕閱讀器是否正在運行(JAWS)?C#:如何檢測屏幕閱讀器是否正在運行?

正如我在.NET 4中所理解的,我們可以使用System.Windows.Automation.Provider命名空間中的AutomationInteropProvider.ClientsAreListening,但是如果我必須爲.NET 2.0執行此操作,該怎麼辦?

我試着檢查ClientsAreListening源代碼,它調用UIAutomationCore.dll庫中的外部RawUiaClientsAreListening方法。

你有任何想法如何在.NET 2.0中實現JAWS檢測?

+0

好奇 - 如果您確定屏幕閱讀器正在運行,您打算做什麼不同?請注意,某些非屏幕閱讀器應用程序可能會設置SPI_SCREENREADER標誌,因此您可能會得到誤報或否定。理想情況下,您的應用程序應該無需檢查此標誌即可工作。你真的在檢查一般的屏幕閱讀器,還是特別的JAWS? – BrendanMcK

回答

4

使用SystemParametersInfo function通過uiActionSPI_GETSCREENREADER

您將需要使用P/Invoke這一點,例如:

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

這可能是比使用ClientsAreListening屬性更好,因爲這個屬性似乎對任何自動化客戶端返回true,不只是屏幕閱讀器。

另見:

你也應該聽,如果屏幕閱讀器開始檢測WM_SETTINGCHANGE消息/停止運行。


更新(響應BrendanMcK的評論):

雖然這是從來沒有明確地記載了很多的話,看着國旗的描述,我認爲這個標誌的目的也比較明確:

確定屏幕審閱者實用程序是否正在運行。屏幕查看器實用程序將文本信息引導到輸出設備,例如語音合成器或盲文顯示器。設置此標誌時,應用程序應提供文本信息,以便以圖形方式顯示信息。

這是什麼要說的是,應用程序設置該標誌,每當應用程序希望的UI表現得好像一個屏幕閱讀器正在運行,無論該應用是否真的是一個屏幕閱讀器或不

對此標誌做出的適當處理是add text in order to "read" otherwise intuitive UI state to the user。如果激進的需要進行更改以使您的UI屏幕閱讀器可訪問,那麼您的UI對用戶來說並不那麼直觀,並且可能會重新進行思考。

+0

太棒了!效果很好!謝謝! –

+1

請注意,ClientsAreListening只會告訴您有關主動偵聽可訪問性事件的輔助功能客戶端。可能還有其他人仍然使用可訪問性 - 例如。爲語言識別動詞的用戶界面刮 - 但使用其他手段來確定何時刮,並且不聽可訪問性事件。簡而言之,這個API只會讓你知道你需要發送事件;而不是無障礙客戶端是否在運行。 – BrendanMcK

+0

@BrendanMcK相反,「SPI_GETSCREENREADER」只是屏幕閱讀器設置的一個標誌,用於向其他人表明它們正在運行(不管使用何種方法) – Justin

相關問題