[MFC] MFC 用mciSendString加载WAV资源文件

@ - @  

  FIRDST:为什么不用路径加载?

  因为mciSendString函数不支持加载资源文件里的WAV资源,如果按路径加载,那么你的WAV就暴露在exe之外,无法实现音频资源的很好保护。

  SECOND:为什么不用PlaySound(MAKEINTRESOURCE(IDR_WAVE_HIT),AfxGetResourceHandle(),SND_RESOURCE|SND_ASYNC);直接加载资源文件播放呢?

   其实这样是可以的,但是这里有2方面考虑:首先PS函数不能加载mp3格式文件,其次有时候游戏编写过程中同时使用PS函数和mciSS函数可以实现混音效果,如果只用PS函数就只能播放一种音乐出现麻烦!

 

复制代码
 1 bool ExtractResource(LPCTSTR strDstFile, LPCTSTR strResType, LPCTSTR strResName){//中间调用函数
 2     // 创建文件
 3     HANDLE hFile = ::CreateFile(strDstFile, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
 4     if (hFile == INVALID_HANDLE_VALUE)
 5         return false;
 6 
 7     // 查找资源文件中、加载资源到内存、得到资源大小
 8     HRSRC    hRes    = ::FindResource(NULL, strResName, strResType);
 9     HGLOBAL    hMem    = ::LoadResource(NULL, hRes);
10     DWORD    dwSize    = ::SizeofResource(NULL, hRes);
11     
12     // 写入文件
13     DWORD dwWrite = 0;      // 返回写入字节
14     ::WriteFile(hFile, hMem, dwSize, &dwWrite, NULL);
15     ::CloseHandle(hFile);
16 
17     return true;
18 }
19 //--------------------------------------------------------------
20 void init(){//初始化函数
21     // 产生临时文件的文件名
22     TCHAR tmpwav[_MAX_PATH];
23     ::GetTempPath(_MAX_PATH,tmpwav);
24     _tcscat_s(tmpwav, _T("testapp_background.wav"));        // VC2008、VC2010 请用 _tcscat_s 函数
25     // 将wav 资源提取为临时文件
26     //ExtractResource(tmpwav,_T("WAVE"), "background.mp3");
27     // 注:如果wave资源的 ID 为宏 IDR_BACKGROUND,这样做:
28     ExtractResource(tmpwav, _T("WAVE"), MAKEINTRESOURCE(IDR_WAVE_POINT));
29     // 打开音乐
30     TCHAR mcicmd[300];
31     _stprintf_s(mcicmd, _T("open \"%s\" alias mymusic"),tmpwav);        // VC2008、VC2010 请用 _stprintf_s 函数
32     mciSendString(mcicmd, NULL,0, NULL);
33     // 播放音乐
34     mciSendString(_T("play mymusic"), NULL, 0, NULL);
35     // 停止播放并关闭音乐
36     mciSendString(("stop mymusic"), NULL, 0, NULL);
37     mciSendString(("close mymusic"), NULL, 0, NULL);
38     // 删除临时文件
39     DeleteFile(tmpmp3);
40 }
41 //--------------------------------------------------------------
42 //如果是初始化里的情况只能播放一次,想要多次播放,先要把mcicmd[]设为全局变量
43 //再把:下面几条语句注释掉
44 //mciSendString(mcicmd, NULL,0, NULL);
45 //mciSendString(_T("play mymusic"), NULL, 0, NULL);
46 //mciSendString(("stop mymusic"), NULL, 0, NULL);
47 //mciSendString(("close mymusic"), NULL, 0, NULL);
48 //DeleteFile(tmpmp3);
49 //再在该调用的位置使用下面的play函数!!!
50 void play(){//播放函数
51     mciSendString(_T("close mymusic"), NULL, 0, NULL);//先关再开,注意顺序!!!
52     mciSendString(mcicmd, NULL,0, NULL);
53     mciSendString(_T("play mymusic"),NULL,0, NULL);        
54 }//------------------------------------------------------------
复制代码

 

posted @   beautifulzzzz  阅读(2256)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示