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

相关文章

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

找不到Anaconda prompt终端的原因分析及解决方案

《找不到Anacondaprompt终端的原因分析及解决方案》因为anaconda还没有初始化,在安装anaconda的过程中,有一行是否要添加anaconda到菜单目录中,由于没有勾选,导致没有菜... 目录问题原因问http://www.chinasem.cn题解决安装了 Anaconda 却找不到 An

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

C++ 各种map特点对比分析

《C++各种map特点对比分析》文章比较了C++中不同类型的map(如std::map,std::unordered_map,std::multimap,std::unordered_multima... 目录特点比较C++ 示例代码 ​​​​​​代码解释特点比较1. std::map底层实现:基于红黑

Windows Server服务器上配置FileZilla后,FTP连接不上?

《WindowsServer服务器上配置FileZilla后,FTP连接不上?》WindowsServer服务器上配置FileZilla后,FTP连接错误和操作超时的问题,应该如何解决?首先,通过... 目录在Windohttp://www.chinasem.cnws防火墙开启的情况下,遇到的错误如下:无法与

Python解析器安装指南分享(Mac/Windows/Linux)

《Python解析器安装指南分享(Mac/Windows/Linux)》:本文主要介绍Python解析器安装指南(Mac/Windows/Linux),具有很好的参考价值,希望对大家有所帮助,如有... 目NMNkN录1js. 安装包下载1.1 python 下载官网2.核心安装方式3. MACOS 系统安

Spring、Spring Boot、Spring Cloud 的区别与联系分析

《Spring、SpringBoot、SpringCloud的区别与联系分析》Spring、SpringBoot和SpringCloud是Java开发中常用的框架,分别针对企业级应用开发、快速开... 目录1. Spring 框架2. Spring Boot3. Spring Cloud总结1. Sprin

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想