使用传递 a的SystemParametersInfo
函数。uiAction
SPI_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 表现得好像屏幕阅读器正在运行,应用程序就会设置此标志,而不管该应用程序是否实际上是屏幕阅读器。
响应这个标志的合适的事情是添加文本以便向用户“读取”其他直观的 UI 状态。如果需要彻底更改以使您的 UI 屏幕阅读器可访问,那么您的 UI 对签名用户来说也不是那么直观,可能需要重新考虑。