C#调用 Windows 辅助功能 API "AccSetRunningUtilityState" 函数实现音频避闪功能
音频闪避是指当自身应用程序,例如辅助功能程序,正在播放音频的时候,降低其他应用程序的音量。这样可以让用户更清楚地听到自身应用程序的音频,例如文字转语音或者导航提示。Windows API 提供了一个函数,AccSetRunningUtilityState,可以让辅助功能程序设置自己的音频闪避选项。本文将介绍如何使用这个函数实现音频闪避的功能。
AccSetRunningUtilityState 函数
AccSetRunningUtilityState 函数的原型如下:
HRESULT AccSetRunningUtilityState(
[in] HWND hwndApp,
[in] DWORD dwUtilityStateMask,
[in] DWORD dwUtilityState
);
这个函数接受三个参数: - hwndApp:辅助功能程序的主窗口句柄。这个参数不能为 NULL。 - dwUtilityStateMask:一个掩码,表示要设置的系统值。它可以是下面的值的组合: - ANRUS_ON_SCREEN_KEYBOARD_ACTIVE:辅助功能程序提供了一个屏幕键盘。 - ANRUS_TOUCH_MODIFICATION_ACTIVE:辅助功能程序正在消费重定向的触摸输入。 - ANRUS_PRIORITY_AUDIO_ACTIVE:辅助功能程序依赖音频(例如文字转语音)来传达重要信息给用户,并且应该在其他系统声音上保持可听性。 - ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK:辅助功能程序依赖音频(例如文字转语音)来传达重要信息给用户,但不应该相对于其他系统声音发生变化。 - dwUtilityState:dwUtilityStateMask 所指示的系统值的新设置。这个参数可以是零来重置系统值,或者是上面的值的组合。 如果成功,这个函数返回 S_OK,否则返回一个标准的 COM 错误码。 这个函数需要调用进程拥有 UIAccess 或更高的权限。如果调用者没有必要的权限,调用 AccSetRunningUtilityState 会失败,并返回 E_ACCESSDENIED。 在退出之前,辅助功能程序应该重置之前设置的任何系统值。
音频闪避选项
为了实现音频闪避的功能,我们需要使用 ANRUS_PRIORITY_AUDIO_ACTIVE 和 ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK 这两个值。它们分别表示: - ANRUS_PRIORITY_AUDIO_ACTIVE:辅助功能程序正在播放重要的音频,并且希望系统降低其他应用程序的音量。 - ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK:辅助功能程序正在播放重要的音频,但不希望系统降低其他应用程序的音量。 我们可以根据自己的需求,选择其中一个或者两个都使用。如果我们想要让自己的音频始终保持高于其他应用程序的音量,我们可以同时使用这两个值。如果我们想要让自己的音频在开始播放时降低其他应用程序的音量,然后在停止播放时恢复其他应用程序的音量,我们可以在开始播放时使用 ANRUS_PRIORITY_AUDIO_ACTIVE,然后在停止播放时使用 ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK。
示例代码
下面是一个使用 C# 编写的示例代码,演示了如何调用 AccSetRunningUtilityState 函数实现音频闪避的功能。这个代码定义了一个静态类 AudioDucking,提供了两个静态方法: - SetAudioDucking:设置音频闪避选项为 ANRUS_PRIORITY_AUDIO_ACTIVE,表示辅助功能程序处于活动状态,正在播放重要的音频,并且希望系统降低其他应用程序的音量。 - ResetAudioDucking:设置音频闪避选项为 ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK,表示辅助功能程序已经停止播放重要的音频,或者不希望系统降低其他应用程序的音量。 这两个方法都接受一个参数,即辅助功能程序的主窗口句柄。它们都调用了 AccSetRunningUtilityState 函数,并返回一个布尔值,表示是否成功。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace WinForms
{
public static class AudioDucking
{
private const uint ANRUS_PRIORITY_AUDIO_ACTIVE = 0x0000004;
private const uint ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK = 0x0000008;
[DllImport("oleacc.dll", SetLastError = true)]
private static extern int AccSetRunningUtilityState(IntPtr hwndApp, uint dwUtilityStateMask, uint dwUtilityState);
public static bool SetAudioDucking(IntPtr hwnd)
{
int result = AccSetRunningUtilityState(hwnd, ANRUS_PRIORITY_AUDIO_ACTIVE | ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK, ANRUS_PRIORITY_AUDIO_ACTIVE | ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK);
return result == 0;
}
public static bool ResetAudioDucking(IntPtr hwnd)
{
int result = AccSetRunningUtilityState(hwnd, ANRUS_PRIORITY_AUDIO_ACTIVE | ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK, ANRUS_PRIORITY_AUDIO_ACTIVE_NODUCK);
return result == 0;
}
}
}
使用方法
为了使用这个示例代码,我们需要在程序中引用 AudioDucking 类,并在合适的时机调用它的方法。例如,如果我们的辅助功能程序是一个文字转语音的应用程序,我们可以在开始播放语音时调用 SetAudioDucking 方法,然后在停止播放语音时调用 ResetAudioDucking 方法。这样就可以实现音频闪避的功能,让用户更清楚地听到我们的语音输出。
总结
本文介绍了如何使用 Windows API 中的 AccSetRunningUtilityState 函数实现音频闪避的功能。这个函数可以让辅助功能程序设置自己的音频闪避选项,从而影响系统对其他应用程序的音量控制。我们还给出了一个使用 C# 编写的示例代码,演示了如何调用这个函数。希望本文对你有所帮助。