Windows C语言编程:Beep API实现蜂鸣器原理与实战

发布时间:2026/7/28 10:32:41
Windows C语言编程:Beep API实现蜂鸣器原理与实战
如果你在 Windows 上写过 C 语言程序想给程序加个简单的提示音第一个想到的可能是printf(\a)。这个转义字符确实能在某些终端里发出“嘀”的一声但它太原始、太不可控了而且很多时候根本没声音。那么有没有一种更“Windows”、更可控、更专业的方法来让你的程序“说话”呢答案是肯定的而且它比你想象的要强大和复杂。Windows 提供了一个名为Beep的 API 函数专门用于生成蜂鸣声。你可能觉得这功能太简单甚至有点过时——不就是让电脑“哔”一声吗但恰恰是这个看似简单的功能背后隐藏着 Windows 系统声音架构的演进史以及从硬件控制到软件模拟的完整变迁。更重要的是它至今仍是许多后台服务、批处理脚本和硬件测试工具中实现非侵入式告警或状态提示的可靠手段。本文将带你深入 Windows API 的底层用 C 语言亲手实现一个可控的蜂鸣器。我们不止会写一个Beep(750, 300)的调用更会拆解其背后的原理解释为什么它在现代 Windows 上可能“失声”以及如何确保你的蜂鸣代码在任何环境下都能可靠工作。无论你是想为你的命令行工具添加一个完成提示还是想理解 Windows 系统与硬件交互的底层机制这篇文章都将为你提供从原理到实战的完整路径。1. 这篇文章真正要解决的问题在深入代码之前我们必须先厘清一个核心问题在 202X 年的现代 Windows 系统上为什么我们还需要专门学习一个“发出蜂鸣声”的 API直接播放一个 MP3 提示音不是更酷吗这个问题触及了BeepAPI 存在的根本价值。它的设计目标从来不是取代多媒体音频而是解决以下几个特定场景下的核心痛点极致的轻量与零依赖Beep函数是 Windows Kernel32.dll 的一部分无需任何额外的音频库、编解码器或运行时。对于系统级工具、安装程序或紧急恢复环境确保一个最小的、可靠的听觉反馈至关重要。后台与无头环境在服务器、后台服务或没有用户交互的脚本中程序可能没有图形界面甚至没有默认的音频输出设备。传统的MessageBeep或播放.wav文件依赖于当前会话的音频配置可能失败。而Beep函数在 Windows 7 及以后版本中被重写为向“会话的默认声音设备”传递声音在终端服务如远程桌面场景下声音会被重定向到客户端这为远程管理提供了状态反馈的可能。精确的频率与时长控制与printf(\a)或MessageBeep(MB_ICONASTERISK)播放固定系统声音不同Beep允许你指定精确的频率37-32767 Hz和持续时间毫秒。这使得它可以用于简单的音频测试、硬件诊断如测试扬声器响应甚至创作一些基础的旋律。同步执行与阻塞Beep函数是同步的。调用后它会等待蜂鸣声播放完毕才返回。这对于需要严格时序或确保用户感知到提示后再进行下一步操作的程序来说是一个简单而有效的特性。因此学习BeepAPI不仅仅是学习一个函数调用更是理解 Windows 如何在不同硬件和系统配置下处理最基础的音频信号。这对于开发系统工具、嵌入式上位机软件或需要跨版本兼容的 C 语言开发者来说是一项实用的技能。2. 基础概念与核心原理2.1 什么是 Windows APIWindows APIApplication Programming Interface应用程序编程接口是微软 Windows 操作系统提供给应用程序的一套底层函数集合。你可以把它看作是操作系统与应用程序之间约定好的“通信协议”。通过调用这些 API程序可以请求操作系统完成诸如创建窗口、读写文件、管理进程、播放声音等任务。Beep函数就是这套庞大 API 中负责与系统蜂鸣器或模拟蜂鸣器交互的一个小部分。2.2Beep函数的前世今生根据微软官方文档Beep函数的历史是一部微型的计算机硬件进化史上古时代8254 可编程间隔计时器芯片在早期的 PC 架构中主板上普遍集成了一个名为 8254 的芯片。Beep函数最初就是专门为直接驱动这块硬件芯片而编写的。它通过向特定的 I/O 端口发送指令让主板上的压电蜂鸣器发出“哔哔”声。这个声音是纯粹的硬件生成不受系统音量控制。声卡时代与兼容性断裂随着声卡成为标准配置制造商开始从主板上移除 8254 芯片。在 Windows Vista 和 Windows XP x64 版本中由于缺乏与旧硬件的通信支持从主板蜂鸣器播放声音的功能被放弃。此时很多开发者也转向了更高级的MessageBeep函数它使用默认的声音设备。现代重写Windows 7 及以后在 Windows 7 中Beep函数被彻底重写。它的行为发生了根本改变不再尝试访问可能不存在的硬件而是将蜂鸣声传递到当前会话的默认声音设备。这通常就是你的声卡和扬声器/耳机。在远程桌面终端服务环境下这个声音会被重定向到客户端机器上播放。这是理解现代Beep行为的关键它现在是一个通过声卡播放的、受系统音量控制的软件模拟音调。2.3Beep与相关函数的区别为了避免混淆我们用一个表格来清晰对比函数/方法所属库/头文件原理可控性音量控制现代系统行为BeepWindows.h-Kernel32.dllWin32 API。古早驱动硬件蜂鸣器现代重写后通过声卡播放指定频率/时长的音调。高。可指定频率(Hz)和时长(ms)。Windows 7 受系统音量控制。通过默认音频设备播放纯音。printf(“\a”)C 标准库输出 ASCII 码中的 BEL (Bell, 0x07) 字符。行为由终端/控制台解释。极低。行为不确定可能无声、可能播放系统提示音、可能触发视觉提示。不确定。高度依赖终端模拟器在 Windows 现代终端中常无效。MessageBeepWindows.h-User32.dllWin32 API。播放与系统事件关联的预定义声音方案如感叹号、错误音。低。只能选择几种预定义类型。受系统声音方案和音量控制。播放%SystemRoot%\Media目录下的对应.wav文件。PlaySoundWindows.h-Winmm.dll多媒体 API。可播放指定的.wav文件或系统声音。中。可播放任意.wav文件。受应用程序和系统音量控制。功能强大但需要有效的音频文件或资源。简单来说想要一个可编程的、简单的“哔”声且不依赖外部文件- 用Beep。想要标准的系统提示音如错误弹窗的声音- 用MessageBeep。想要播放自定义的.wav文件- 用PlaySound或其他多媒体库。printf(“\a”)不推荐用于需要可靠听觉反馈的程序。3. 环境准备与前置条件在开始编码前你需要准备好开发环境。由于Beep是 Windows 原生 API因此你的环境必须是Windows 操作系统并安装C 语言编译器和开发环境。3.1 操作系统要求BeepAPI 从古老的 Windows XP 到最新的 Windows 11 都支持。但请注意其行为在 Windows 7 前后的根本性变化。本文的代码和讨论主要基于Windows 7 及更新版本的现代行为。3.2 开发工具选择你可以选择以下任一组合Visual Studio (推荐)微软官方的集成开发环境对 Windows API 支持最完善。社区版免费。安装时确保勾选“使用 C 的桌面开发”工作负载这会包含 C/C 编译器、标准库和 Windows SDK。MinGW-w64 或 MSYS2 GCC轻量级的 GNU 工具链在 Windows 上的移植版。适合喜欢命令行和跨平台开发的用户。你需要确保安装的版本包含了Windows.h头文件和相关的库文件。其他 IDE (如 CLion, Code::Blocks)只要它们配置了上述之一的编译器工具链即可。3.3 验证环境创建一个最简单的 C 程序来测试你的环境是否能编译 Windows 程序。// test_env.c #include stdio.h #include windows.h // 包含 Windows API 头文件 int main() { printf(Hello, Windows API!\n); // 尝试获取一个简单的系统信息验证基础API可用 SYSTEM_INFO sysInfo; GetSystemInfo(sysInfo); printf(Number of processors: %lu\n, sysInfo.dwNumberOfProcessors); return 0; }使用你的编译器进行编译和链接。例如在 Visual Studio 的命令行开发者提示符中cl test_env.c或者使用 MinGW-w64 的 GCCgcc test_env.c -o test_env.exe运行生成的test_env.exe如果成功输出处理器数量说明你的 Windows 开发环境基本就绪。4.BeepAPI 详解与核心流程现在让我们聚焦于Beep函数本身。根据微软官方文档 (utilapiset.h通常通过Windows.h引入)其函数原型如下BOOL Beep( [in] DWORD dwFreq, [in] DWORD dwDuration );这是一个非常简洁的函数只有两个参数和一个返回值。4.1 参数解析[in] DWORD dwFreq含义要生成的蜂鸣声的频率单位是赫兹 (Hz)。有效范围37 到 32,767 (0x25 到 0x7FFF)。这是官方文档明确规定的范围。传入此范围之外的数值可能导致函数调用失败。人耳可听范围大约 20 Hz 到 20,000 Hz。Beep的有效范围基本覆盖了人耳可听的中低频段。常见的提示音频率在 750 Hz 到 2500 Hz 之间。[in] DWORD dwDuration含义蜂鸣声持续的时长单位是毫秒 (ms)。有效范围理论上是一个DWORD(无符号32位整数) 能表示的时间但过长的持续时间如数小时可能不实用。通常用于短提示如 100ms 到 2000ms。4.2 返回值类型BOOL(实际上是int)。成功返回非零值(TRUE)。失败返回0(FALSE)。此时可以调用GetLastError()函数来获取扩展的错误代码帮助诊断问题例如频率参数超出范围。4.3 核心调用流程使用Beep函数的代码流程极其简单包含头文件#include windows.h。调用函数传入你想要的频率和时长。检查返回值可选但推荐判断调用是否成功。5. 完整示例与代码实现理论说再多不如一行代码。让我们从最简单的示例开始逐步构建一个更实用的蜂鸣工具。5.1 基础示例发出一次蜂鸣这是最直接的用法也是文档中的例子。// basic_beep.c #include windows.h // 必须包含此头文件 #include stdio.h // 用于 printf int main() { printf(准备发出蜂鸣声...\n); // 调用 Beep 函数频率 750 Hz持续 300 毫秒 BOOL bResult Beep(750, 300); if (bResult) { printf(蜂鸣成功\n); } else { printf(蜂鸣失败错误代码: %lu\n, GetLastError()); } printf(程序结束。\n); return 0; }编译与运行# 使用 Visual Studio 的 cl 编译器 cl basic_beep.c basic_beep.exe # 或使用 MinGW-w64 的 gcc gcc basic_beep.c -o basic_beep.exe ./basic_beep.exe运行后你应该能听到一个短促的“嘀”声同时控制台会输出相应的成功或失败信息。5.2 进阶示例 1演奏简单旋律利用Beep对频率和时长的精确控制我们可以尝试演奏一段简单的旋律比如《小星星》的前几个音符。// melody_beep.c #include windows.h #include stdio.h // 定义一些音符对应的频率近似值单位Hz #define NOTE_C4 262 // Do #define NOTE_D4 294 // Re #define NOTE_E4 330 // Mi #define NOTE_F4 349 // Fa #define NOTE_G4 392 // Sol #define NOTE_A4 440 // La #define NOTE_B4 494 // Si #define NOTE_C5 523 // Do (高八度) int main() { printf(开始演奏《小星星》片段...\n); // 《小星星》旋律: C4 C4 G4 G4 A4 A4 G4 int melody[] {NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4, NOTE_G4}; int duration 500; // 每个音符持续 500 毫秒 for (int i 0; i sizeof(melody)/sizeof(melody[0]); i) { printf(播放频率: %d Hz\n, melody[i]); if (!Beep(melody[i], duration)) { printf(播放失败于音符 %d错误: %lu\n, i, GetLastError()); break; } // 可选在音符之间添加一个极短的静音间隔使旋律更清晰 Sleep(50); } printf(演奏结束。\n); return 0; }这个例子展示了如何将Beep用于超越简单提示的场景。虽然音质无法与真正的音乐播放器相比但对于程序化生成声音或创建独特的音频反馈来说已经足够。5.3 进阶示例 2带参数的命令行蜂鸣器让我们创建一个更实用的程序它可以从命令行接收频率和时长参数。// cli_beep.c #include windows.h #include stdio.h #include stdlib.h // 用于 atoi int main(int argc, char* argv[]) { DWORD freq 1000; // 默认频率 1000 Hz DWORD duration 500; // 默认时长 500 ms // 解析命令行参数 // 用法: cli_beep.exe [频率] [时长(ms)] if (argc 2) { freq (DWORD)atoi(argv[1]); } if (argc 3) { duration (DWORD)atoi(argv[2]); } // 验证参数范围 (根据API文档) if (freq 37 || freq 32767) { fprintf(stderr, 错误频率参数必须在 37 到 32767 Hz 之间。你输入的是%lu\n, freq); return 1; // 返回非零值表示错误 } printf(即将播放蜂鸣声 - 频率: %lu Hz, 时长: %lu ms\n, freq, duration); if (!Beep(freq, duration)) { DWORD error GetLastError(); fprintf(stderr, 蜂鸣失败系统错误代码: %lu\n, error); // 可以根据 error 代码给出更友好的提示 switch(error) { case 87: // ERROR_INVALID_PARAMETER fprintf(stderr, 可能原因参数无效尽管我们已做检查。\n); break; default: fprintf(stderr, 未知错误。\n); } return 1; } printf(播放成功。\n); return 0; }编译与使用gcc cli_beep.c -o cli_beep.exe # 使用默认参数 cli_beep.exe # 指定频率和时长 cli_beep.exe 440 1000 # 播放 440 Hz (标准音La) 持续1秒 cli_beep.exe 200 2000 # 播放 200 Hz 持续2秒这个程序体现了工程化的思维参数化、输入验证、错误处理。你可以将它集成到批处理脚本中作为某个任务完成后的听觉信号。6. 运行结果与效果验证运行上述代码你期望的结果是听到对应频率和时长的蜂鸣声。但“听到声音”这个结果依赖于多个因素以下是验证步骤和可能的情况6.1 成功运行的标志控制台输出程序应打印出预期的提示信息如“准备发出蜂鸣声...”、“播放成功。”等。听觉反馈你应该能从电脑的扬声器或耳机中听到一个清晰的、单一频率的纯音。音调的高低由频率参数决定声音的长短由时长参数决定。函数返回值Beep函数返回TRUE(非零)并且GetLastError()不会在调用后返回错误通常通过再次调用GetLastError()来确认如果之前成功它可能返回0或一个无关值。6.2 如果听不到声音—— 系统级排查清单这是最常见的问题。请按以下顺序排查排查步骤操作与解释1. 检查系统音量右键点击任务栏右下角的扬声器图标确保音量未静音且音量足够大。Beep在现代 Windows 上通过声卡播放受系统主音量控制。2. 检查默认播放设备右键扬声器图标 - “打开声音设置” - 确保“输出”部分选择了正确的设备如你的扬声器或耳机。3. 检查程序是否运行查看任务管理器确认你的*.exe进程正在运行并很快结束。如果程序闪退可能是参数错误导致。在命令行中运行可看到错误信息。4. 检查频率参数确保频率值在37 到 32767之间。超出此范围Beep会失败。使用我们的cli_beep.c示例它包含了范围检查。5. 以管理员身份运行极少数情况下某些系统策略或驱动程序可能需要提升的权限。尝试右键点击你的可执行文件或命令行窗口选择“以管理员身份运行”。6. 检查音频服务按下Win R输入services.msc找到“Windows Audio”服务确保其状态为“正在运行”。7. 尝试MessageBeep写一个简单的测试程序调用MessageBeep(MB_OK)。如果能听到系统默认提示音说明音频输出正常问题可能出在Beep的特定频率或你的代码上。如果MessageBeep也没声音那很可能是系统音频配置问题。8. 远程桌面/虚拟机如果你在远程桌面连接或虚拟机中运行程序请确认远程桌面或虚拟机的音频重定向功能已开启并且客户端设备音量正常。6.3 验证代码一个综合测试程序创建一个测试程序系统地验证不同频率和Beep的可用性。// test_beep_thorough.c #include windows.h #include stdio.h int main() { printf( Beep API 综合测试 \n\n); // 测试1: 标准提示音频率 printf(测试1: 播放标准提示音 (750Hz, 300ms)...\n); if (Beep(750, 300)) { printf( 通过。\n); } else { printf( 失败错误: %lu\n, GetLastError()); } Sleep(1000); // 等待1秒 // 测试2: 边界频率测试 (低) printf(\n测试2: 播放低频边界音 (37Hz, 500ms)...\n); if (Beep(37, 500)) { printf( 通过 (你可能听不到或声音很沉闷)。\n); } else { printf( 失败错误: %lu\n, GetLastError()); } Sleep(1000); // 测试3: 边界频率测试 (高) printf(\n测试3: 播放高频边界音 (32767Hz, 200ms)...\n); if (Beep(32767, 200)) { printf( 通过 (声音非常尖锐部分成年人可能听不到)。\n); } else { printf( 失败错误: %lu\n, GetLastError()); } Sleep(1000); // 测试4: 无效频率测试 (应失败) printf(\n测试4: 尝试播放无效频率 (10Hz, 应失败)...\n); if (!Beep(10, 100)) { printf( 符合预期调用失败。错误代码: %lu\n, GetLastError()); } else { printf( 意外成功\n); } printf(\n 测试结束 \n); return 0; }运行这个测试程序你可以全面了解BeepAPI 在你的系统上的行为。7. 常见问题与排查思路即使代码正确在实际运行中也可能遇到各种问题。下表汇总了常见问题及其解决方法问题现象可能原因排查方式解决方案完全无声但程序正常退出1. 系统音量静音或过低。2. 默认播放设备设置错误。3. 在远程桌面中音频未重定向。4. 音频服务未运行。1. 检查系统音量滑块和播放设备。2. 在声音设置中测试其他音频。3. 在物理机器上本地运行测试。4. 检查services.msc中的Windows Audio服务。调高音量、切换正确的播放设备、开启远程音频、重启音频服务。程序崩溃或无响应1. 传入的频率或时长参数值异常巨大导致函数内部处理超时或错误虽然不常见。2. 极少数情况下驱动程序冲突。1. 检查代码确保参数在合理范围内。2. 使用调试器运行查看崩溃点。修正参数值。更新声卡/主板驱动。Beep返回FALSEGetLastError()返回 87 (ERROR_INVALID_PARAMETER)频率参数超出 37-32767 范围。这是最常见的原因。打印传入的频率值进行确认。确保调用Beep前频率参数在有效范围内。声音失真或杂音1. 扬声器或耳机硬件问题。2. 频率过高接近或超过扬声器上限。3. 系统音频增强功能如均衡器、音效干扰。1. 用其他音频播放软件测试同一频率的纯音。2. 尝试中频如 1000Hz。3. 暂时禁用所有音效。更换音频设备、使用合理的频率、关闭音效增强。在 Windows XP / Server 2003 等旧系统上行为不一致这些系统可能仍尝试访问硬件蜂鸣器而该硬件可能不存在或被禁用。查阅对应系统的文档。使用MessageBeep作为后备方案。对于需要兼容旧系统的代码考虑功能检测或提供后备方案。杀毒软件或安全软件拦截某些安全软件可能将直接调用底层 API 生成声音的行为视为可疑。查看安全软件日志或暂时禁用测试。将你的程序添加到安全软件的白名单中。8. 最佳实践与工程建议将BeepAPI 集成到实际项目中时遵循以下最佳实践可以让你的代码更健壮、更专业。8.1 封装与错误处理不要在每个需要蜂鸣的地方都直接调用Beep。创建一个封装函数集中处理参数验证、错误日志和可能的回退机制。// sound_utils.h #ifndef SOUND_UTILS_H #define SOUND_UTILS_H #include windows.h // 播放蜂鸣声的封装函数 // 参数: freq - 频率 (Hz), duration - 时长 (ms) // 返回值: 0 成功非0为错误码 int play_beep_safe(DWORD freq, DWORD duration); #endif // SOUND_UTILS_H// sound_utils.c #include “sound_utils.h” #include stdio.h // 在实际项目中应使用更专业的日志库 int play_beep_safe(DWORD freq, DWORD duration) { // 1. 参数验证 if (freq 37 || freq 32767) { // 记录错误日志 fprintf(stderr, “[play_beep_safe] 错误无效频率 %lu。有效范围37-32767 Hz。\n”, freq); return ERROR_INVALID_PARAMETER; // 或自定义错误码 } if (duration 0) { // 持续时间为0没有意义但API可能允许这里我们视为无效或警告 fprintf(stderr, “[play_beep_safe] 警告持续时间为0毫秒。\n”); // 可以选择直接返回成功不做任何事 return 0; } // 2. 调用API if (!Beep(freq, duration)) { DWORD err GetLastError(); fprintf(stderr, “[play_beep_safe] Beep API 调用失败。频率%lu, 时长%lu, 系统错误%lu\n”, freq, duration, err); return err; // 返回系统错误码 } // 3. 成功 // 可以在此处添加调试日志 // fprintf(stderr, “[play_beep_safe] 播放成功。频率%lu, 时长%lu\n”, freq, duration); return 0; }8.2 提供后备方案如果你的程序必须提供听觉反馈而Beep可能失败考虑提供一个后备方案例如调用MessageBeep。int play_notification_sound(int sound_type) { // sound_type: 0Beep, 1MessageBeep if (sound_type 0) { // 尝试我们的自定义蜂鸣 if (play_beep_safe(800, 200) 0) { return 0; // 成功 } // 如果失败降级到 MessageBeep fprintf(stderr, “自定义蜂鸣失败降级使用系统提示音。\n”); } // 使用系统提示音 if (!MessageBeep(MB_ICONINFORMATION)) { // 也可以尝试 MB_OK, MB_ICONWARNING 等 fprintf(stderr, “MessageBeep 也失败了\n”); return GetLastError(); } return 0; }8.3 考虑用户体验与可访问性不要滥用频繁、冗长或高频率的蜂鸣声会严重干扰用户。将其用于重要的、非频繁的提示如长时间操作完成、严重错误发生。可配置化在程序的设置中提供选项允许用户关闭声音提示特别是对于可能运行在安静环境或需要专注的场景下的工具。结合视觉提示重要的状态变化或错误除了声音一定要有清晰的视觉反馈如控制台输出、日志文件、GUI弹窗。不能依赖用户一定能听到声音。8.4 多线程环境下的使用Beep函数是同步且会阻塞当前线程的。如果在 UI 线程如 GUI 程序的主线程中调用一个长时间的Beep会导致界面卡顿。在这种情况下应该在单独的线程中播放声音。#include windows.h #include process.h // 用于 _beginthread void beep_thread(void* params) { // 假设 params 指向一个包含 freq 和 duration 的结构体 // 这里简化为固定值 Beep(1000, 1000); // 播放一个1秒的长音 _endthread(); } void trigger_long_beep_in_background() { // 创建一个新线程来播放声音避免阻塞主线程 _beginthread(beep_thread, 0, NULL); }9. 总结与后续学习方向通过本文我们完成了一次从表面调用到底层原理的 Windows API 探索之旅。Beep这个看似简单的函数串联起了 PC 硬件历史、操作系统演进和现代软件开发中的实用考量。核心收获Beep的本质已变它从一个直接驱动主板蜂鸣器的硬件函数演变为一个通过默认音频设备播放纯音的软件函数。理解这一点是解决“为什么没声音”问题的关键。精准控制它提供了对声音频率和时长的精确编程控制这是printf(“\a”)和MessageBeep所不具备的。轻量与可靠作为 Kernel32.dll 的一部分它无需额外依赖是系统工具和后台程序提供听觉反馈的轻量级选择。工程化思维在实际使用中参数验证、错误处理、日志记录、后备方案和用户体验都是必须考虑的环节。如果你想继续深入探索MessageBeep和PlaySound了解 Windows 更高级的声音通知和多媒体播放 API它们能提供更丰富、更用户友好的音频体验。研究 Windows 音频架构了解 Core Audio (WASAPI)、DirectSound 等现代 Windows 音频栈这对于开发专业的音频应用至关重要。跨平台声音编程如果你的程序需要运行在 Linux 或 macOS 上可以研究 PortAudio 或 SDL 等跨平台音频库它们提供了统一的接口来处理音频输出。深入硬件交互如果你对真正的底层硬件编程感兴趣例如在嵌入式 Windows 或特定工业控制器上可以研究 Windows Driver Kit (WDK) 和如何通过驱动程序与硬件直接通信。Beep就像编程世界里的一个“活化石”它简单到几乎被遗忘但在特定的角落依然闪烁着实用主义的光芒。掌握它不仅是学会一个 API 调用更是理解如何在不同的技术层之间为你的程序找到那个恰到好处的反馈方式。希望下次当你需要为命令行工具添加一个“完成提示音”时能自信地写出那行Beep(800, 200)。