windows 程序设计之「RECORD2.C」范例分析笔记

2024-05-01 03:18

本文主要是介绍windows 程序设计之「RECORD2.C」范例分析笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

/*----------------------------------------

   RECORD2.C -- Waveform Audio Recorder

                (c) Charles Petzold, 1998

------------------------------------------*/

 

#include <windows.h>

#include "..//record1//resource.h" // RECORD1.C 中的资源标识符头文件

 

BOOL CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM) ;

 

TCHAR szAppName [] = TEXT ("Record2") ;

 

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

                    PSTR szCmdLine, int iCmdShow)

{

     if (-1 == DialogBox (hInstance, TEXT ("Record"), NULL, DlgProc))

     {

          MessageBox (NULL, TEXT ("This program requires Windows NT!"),

                      szAppName, MB_ICONERROR) ;

     }

     return 0 ;

}

 

void ShowError (HWND hwnd, DWORD dwError)

{

     TCHAR szErrorStr [1024] ;

    

     mciGetErrorString (dwError, szErrorStr,

                        sizeof (szErrorStr) / sizeof (TCHAR)) ;

     MessageBeep (MB_ICONEXCLAMATION) ;

     MessageBox (hwnd, szErrorStr, szAppName, MB_OK | MB_ICONEXCLAMATION) ;

}

 

BOOL CALLBACK DlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

     static BOOL       bRecording, bPlaying, bPaused ;

     static TCHAR      szFileName[] = TEXT ("record2.wav") ;

     static WORD       wDeviceID ;

     DWORD             dwError ;

     MCI_GENERIC_PARMS mciGeneric ;

     MCI_OPEN_PARMS    mciOpen ;

     MCI_PLAY_PARMS    mciPlay ;

     MCI_RECORD_PARMS  mciRecord ;

     MCI_SAVE_PARMS    mciSave ;

    

     switch (message)

     {

     case WM_COMMAND:

          switch (wParam)

          {

          case IDC_RECORD_BEG:

                    // 删除现有的波形文件

               DeleteFile (szFileName) ;

               // 设置MCI_OPEN_PARMS结构

               // dwCallback 低位字指定一个窗口句柄;用于MCI_NOTIFY旗标

               mciOpen.dwCallback       = 0 ;

               // 调用后用于记录使用的设备标识符

               mciOpen.wDeviceID        = 0 ;

               // 常数标识符名称或设备类型

               mciOpen.lpstrDeviceType  = TEXT ("waveaudio") ;

               // 设备元件(通常是一个路径)

               mciOpen.lpstrElementName = TEXT ("") ;

               // 可选设备别名

               mciOpen.lpstrAlias       = NULL ;

               // MCI_OPEN  初始化一个设备或文件

               dwError = mciSendCommand (0, MCI_OPEN,

                   // MCI_WAIT  指导设备的等待,直到完成所要求的行动才返回控制权

                   // MCI_OPEN_TYPE 表示要使用MCI_OPEN_PARMS结构中的LpstrDiviceType参数

                   // MCI_OPEN_ELEMENT 表示LpstrDeviceType参数中的是设备表述字符串

                   // 还可以使用 MCI_OPEN_TYPE_ID 表示LpstrDeviceType参数中的是设备标识符

                                   MCI_WAIT | MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,

                                   // 指向一个结构,它包含命令的消息参数

                                   (DWORD) (LPMCI_OPEN_PARMS) &mciOpen) ;

               if (dwError != 0)

               {

                    ShowError (hwnd, dwError) ;

                    return TRUE ;

               }

                    // 储存设备ID

               wDeviceID = mciOpen.wDeviceID ;

              

                    // 设置用于录制的命令数据

               // dwCallback 低位字指定一个窗口句柄;用于MCI_NOTIFY旗标

               mciRecord.dwCallback = (DWORD) hwnd ;

               mciRecord.dwFrom     = 0 ;

               mciRecord.dwTo       = 0 ;

               // MCI_RECORD 启动录音功能

// MCI_NOTIFY 旗标导致录音结束后系统向mciRecord.dwCallback元素中指定的窗口句柄发送一条MM_MCINOTIFY通知消息

               mciSendCommand (wDeviceID, MCI_RECORD, MCI_NOTIFY,

                               (DWORD) (LPMCI_RECORD_PARMS) &mciRecord) ;

              

                    // 设置按钮是否有效和当前焦点

               EnableWindow (GetDlgItem (hwnd, IDC_RECORD_BEG), FALSE);

               EnableWindow (GetDlgItem (hwnd, IDC_RECORD_END), TRUE) ;

               EnableWindow (GetDlgItem (hwnd, IDC_PLAY_BEG),   FALSE);

               EnableWindow (GetDlgItem (hwnd, IDC_PLAY_PAUSE), FALSE);

               EnableWindow (GetDlgItem (hwnd, IDC_PLAY_END),   FALSE);

               SetFocus (GetDlgItem (hwnd, IDC_RECORD_END)) ;

              

               bRecording = TRUE ;

               return TRUE ;

               

          case IDC_RECORD_END:

                    // 停止录音

               mciGeneric.dwCallback = 0 ;

               // MCI_STOP 命令消息用于停止先前的录音命令

               mciSendCommand (wDeviceID, MCI_STOP, MCI_WAIT,

                               (DWORD) (LPMCI_GENERIC_PARMS) &mciGeneric) ;

              

                    // 保存声音文件

               mciSave.dwCallback = 0 ;

               mciSave.lpfilename = szFileName ;

               // MCI_SAVE 命令用于对先前录制在临时文件中的声音文件进行保持

               // MCI_SAVE_FILE 指出保存的文件名在mciSave.lpfilename元素中指定

               mciSendCommand (wDeviceID, MCI_SAVE, MCI_WAIT | MCI_SAVE_FILE,

                               (DWORD) (LPMCI_SAVE_PARMS) &mciSave) ;

              

                    // 关闭打开的设备

               // MCI_CLOSE命令消息用于删除所有的临时文件、释放已经建立的内存块并关闭设备

               mciSendCommand (wDeviceID, MCI_CLOSE, MCI_WAIT,

                               (DWORD) (LPMCI_GENERIC_PARMS) &mciGeneric) ;

 

               // 设置按钮是否有效和当前焦点

               EnableWindow (GetDlgItem (hwnd, IDC_RECORD_BEG), TRUE) ;

               EnableWindow (GetDlgItem (hwnd, IDC_RECORD_END), FALSE);

               EnableWindow (GetDlgItem (hwnd, IDC_PLAY_BEG),   TRUE) ;

               EnableWindow (GetDlgItem (hwnd, IDC_PLAY_PAUSE), FALSE);

               EnableWindow (GetDlgItem (hwnd, IDC_PLAY_END),   FALSE);

               SetFocus (GetDlgItem (hwnd, IDC_PLAY_BEG)) ;

               // 录音进行中标记

               bRecording = FALSE ;

               return TRUE ;

              

          case IDC_PLAY_BEG:

                    // 打开波形音频

 

               mciOpen.dwCallback       = 0 ;

               mciOpen.wDeviceID        = 0 ;

               mciOpen.lpstrDeviceType  = NULL ;

               mciOpen.lpstrElementName = szFileName ;

               mciOpen.lpstrAlias       = NULL ;

               

               // MCI_OPEN_ELEMENT 标记表示lpstrElementName字段是一个有效的文件名

               dwError = mciSendCommand (0, MCI_OPEN,

                                         MCI_WAIT | MCI_OPEN_ELEMENT,

                                         (DWORD) (LPMCI_OPEN_PARMS) &mciOpen) ;

              

               if (dwError != 0)

               {

                    ShowError (hwnd, dwError) ;

                    return TRUE ;

               }

                    // Save the device ID

              

               wDeviceID = mciOpen.wDeviceID ;

              

                    // Begin playing

              

               mciPlay.dwCallback = (DWORD) hwnd ;

               mciPlay.dwFrom     = 0 ;

               mciPlay.dwTo       = 0 ;

               // 播放波形音频文件

               // MCI_NOTIFY 旗标导致播放结束后系统向mciPlay.dwCallback元素中指定的窗口句柄发送一条MM_MCINOTIFY通知消息

               mciSendCommand (wDeviceID, MCI_PLAY, MCI_NOTIFY,

                               (DWORD) (LPMCI_PLAY_PARMS) &mciPlay) ;

              

                    // Enable and disable buttons

              

               EnableWindow (GetDlgItem (hwnd, IDC_RECORD_BEG), FALSE);

               EnableWindow (GetDlgItem (hwnd, IDC_RECORD_END), FALSE);

               EnableWindow (GetDlgItem (hwnd, IDC_PLAY_BEG),   FALSE);

               EnableWindow (GetDlgItem (hwnd, IDC_PLAY_PAUSE), TRUE) ;

               EnableWindow (GetDlgItem (hwnd, IDC_PLAY_END),   TRUE) ;

               SetFocus (GetDlgItem (hwnd, IDC_PLAY_END)) ;

              

               bPlaying = TRUE ;

               return TRUE ;

              

          case IDC_PLAY_PAUSE:

              // 如果暂停按钮之前没有被按下则执行暂停操作

               if (!bPaused)

               {

                    mciGeneric.dwCallback = 0 ;

                    // 发出暂停指令

                    mciSendCommand (wDeviceID, MCI_PAUSE, MCI_WAIT,

                                    (DWORD) (LPMCI_GENERIC_PARMS) & mciGeneric);

                    // 设置暂停按钮字样

                    SetDlgItemText (hwnd, IDC_PLAY_PAUSE, TEXT ("Resume")) ;

                    // 标记暂停被按下

                    bPaused = TRUE ;

               }

               // 否者执行继续播放操作

               else

               {

                    mciPlay.dwCallback = (DWORD) hwnd ;

                    mciPlay.dwFrom     = 0 ;

                    mciPlay.dwTo       = 0 ;

                    // MCI_NOTIFY 旗标导致播放结束后系统向mciPlay.dwCallback元素中指定的窗口句柄发送一条MM_MCINOTIFY通知消息

                    mciSendCommand (wDeviceID, MCI_PLAY, MCI_NOTIFY,

                                    (DWORD) (LPMCI_PLAY_PARMS) &mciPlay) ;

                   

                    SetDlgItemText (hwnd, IDC_PLAY_PAUSE, TEXT ("Pause")) ;

                    bPaused = FALSE ;

               }

              

               return TRUE ;

              

          case IDC_PLAY_END:

                    // 停止播放,并关闭设备

              

               mciGeneric.dwCallback = 0 ;

              

               mciSendCommand (wDeviceID, MCI_STOP, MCI_WAIT,

                               (DWORD) (LPMCI_GENERIC_PARMS) &mciGeneric) ;

              

               mciSendCommand (wDeviceID, MCI_CLOSE, MCI_WAIT,

                               (DWORD) (LPMCI_GENERIC_PARMS) &mciGeneric) ;

              

                    // Enable and disable buttons

              

               EnableWindow (GetDlgItem (hwnd, IDC_RECORD_BEG), TRUE) ;

               EnableWindow (GetDlgItem (hwnd, IDC_RECORD_END), FALSE);

               EnableWindow (GetDlgItem (hwnd, IDC_PLAY_BEG),   TRUE) ;

               EnableWindow (GetDlgItem (hwnd, IDC_PLAY_PAUSE), FALSE);

               EnableWindow (GetDlgItem (hwnd, IDC_PLAY_END),   FALSE);

               SetFocus (GetDlgItem (hwnd, IDC_PLAY_BEG)) ;

               // 播放进行中标记

               bPlaying = FALSE ;

 

               bPaused  = FALSE ;

               return TRUE ;

          }

          break ;

              

     case MM_MCINOTIFY:

          switch (wParam)

          {

          case MCI_NOTIFY_SUCCESSFUL:

              // 如果播放或录音正在进行中,则发送停止消息

               if (bPlaying)

                    SendMessage (hwnd, WM_COMMAND, IDC_PLAY_END, 0) ;

              

               if (bRecording)

                    SendMessage (hwnd, WM_COMMAND, IDC_RECORD_END, 0);

              

               return TRUE ;

          }

          break ;

    

     case WM_SYSCOMMAND:

          switch (wParam)

          {

          case SC_CLOSE:

               if (bRecording)

                    SendMessage (hwnd, WM_COMMAND, IDC_RECORD_END, 0L) ;

              

               if (bPlaying)

                    SendMessage (hwnd, WM_COMMAND, IDC_PLAY_END, 0L) ;

              

               EndDialog (hwnd, 0) ;

               return TRUE ;

          }

          break ;

     }

     return FALSE ;

}

 

 

这篇关于windows 程序设计之「RECORD2.C」范例分析笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/950600

相关文章

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

Windows设置nginx启动端口的方法

《Windows设置nginx启动端口的方法》在服务器配置与开发过程中,nginx作为一款高效的HTTP和反向代理服务器,被广泛应用,而在Windows系统中,合理设置nginx的启动端口,是确保其正... 目录一、为什么要设置 nginx 启动端口二、设置步骤三、常见问题及解决一、为什么要设置 nginx

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

在 Windows 上安装 DeepSeek 的完整指南(最新推荐)

《在Windows上安装DeepSeek的完整指南(最新推荐)》在Windows上安装DeepSeek的完整指南,包括下载和安装Ollama、下载DeepSeekRXNUMX模型、运行Deep... 目录在www.chinasem.cn Windows 上安装 DeepSeek 的完整指南步骤 1:下载并安装

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

windows系统下shutdown重启关机命令超详细教程

《windows系统下shutdown重启关机命令超详细教程》shutdown命令是一个强大的工具,允许你通过命令行快速完成关机、重启或注销操作,本文将为你详细解析shutdown命令的使用方法,并提... 目录一、shutdown 命令简介二、shutdown 命令的基本用法三、远程关机与重启四、实际应用

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

Windows自动化Python pyautogui RPA操作实现

《Windows自动化PythonpyautoguiRPA操作实现》本文详细介绍了使用Python的pyautogui库进行Windows自动化操作的实现方法,文中通过示例代码介绍的非常详细,对大... 目录依赖包睡眠:鼠标事件:杀死进程:获取所有窗口的名称:显示窗口:根据图片找元素:输入文字:打开应用:依

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re