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

相关文章

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

python中Hash使用场景分析

《python中Hash使用场景分析》Python的hash()函数用于获取对象哈希值,常用于字典和集合,不可变类型可哈希,可变类型不可,常见算法包括除法、乘法、平方取中和随机数哈希,各有优缺点,需根... 目录python中的 Hash除法哈希算法乘法哈希算法平方取中法随机数哈希算法小结在Python中,

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

关于MyISAM和InnoDB对比分析

《关于MyISAM和InnoDB对比分析》:本文主要介绍关于MyISAM和InnoDB对比分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录开篇:从交通规则看存储引擎选择理解存储引擎的基本概念技术原理对比1. 事务支持:ACID的守护者2. 锁机制:并发控制的艺

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

在Windows上使用qemu安装ubuntu24.04服务器的详细指南

《在Windows上使用qemu安装ubuntu24.04服务器的详细指南》本文介绍了在Windows上使用QEMU安装Ubuntu24.04的全流程:安装QEMU、准备ISO镜像、创建虚拟磁盘、配置... 目录1. 安装QEMU环境2. 准备Ubuntu 24.04镜像3. 启动QEMU安装Ubuntu4

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis