[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 }//------------------------------------------------------------
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?