上一章中,主要是介绍了WINDOWS消息机制和模板对话框的创建,其实学到现在感觉windows程序设计就是各种逻辑+API函数。所以MSDN很重要。由于整个代码太大了,所以下面系列文章中,我只讲思路以及一些控件的用法。源代码以后会上传。请大家多多支持...
   下面先上个 最后的效果图..

     这节主要总结下最核心的播放功能,如何实现的。只提供关键思路。
核心思路:
1.按“添加”按钮,将添加歌曲进入Listbox。具有数字标号+歌曲名字
            这里包括文件添加的操作,listBox的插入操作,字符串函数的操作
2.双击Listbox中某个歌曲将可以播放,并且可以有时间进度条和总时间
           这里包括 listbox响应双击事件,mcisendCommand和关联结构体操作

1.添加文件的操作

    在开始播放前,肯定要手动添加哪些要加入到播放列表中,就是上面按钮"添加"触发的操作。这里涉及文件的打开以及多个文件同时选中的情况。关键代码如下:
void  DoSelectFile(HWND hwnd) //选择文件
{OPENFILENAME ofn;  //定义一个文件结构体TCHAR szOpenFileNames[80*MAX_PATH]; //打开的文件名字TCHAR szPath[MAX_PATH]; //歌曲文件的路径 其实操作一个Mp3文件就是通过路径来操作的TCHAR szFileName[80*MAX_PATH];ZeroMemory(szOpenFileNames,sizeof(szOpenFileNames)/sizeof(TCHAR));ZeroMemory(&ofn,sizeof(ofn));ZeroMemory(szFileName,sizeof(szFileName));ZeroMemory(szPath,sizeof(szPath));  //清空 各类结构//配置ofn各字段ofn.Flags=OFN_EXPLORER|OFN_ALLOWMULTISELECT;//指定浏览功能,和允许多选功能ofn.hwndOwner=hwnd; //父句柄为当前对话框ofn.lStructSize=sizeof(ofn);//整个ofn结构体的大小   (这里以前犯了个错误&ofn)ofn.lpstrFile=szOpenFileNames;//打开的文件的全路径ofn.nMaxFile=sizeof(szOpenFileNames);//文件大小的最大值ofn.lpstrFile[0]='\0';//指定第一个为NULL字符ofn.lpstrFilter=TEXT("*.mp3\0*.mp3\0*.wav\0*.wav\0All files\0*.*\0");//文件过滤器if(GetOpenFileName(&ofn)) //成功返回非零 不成功为0{  TCHAR withnum_song[255];//带数字列表的 插入到listbox的歌曲名ZeroMemory(withnum_song,sizeof(withnum_song)/sizeof(TCHAR));lstrcpyn(szPath,szOpenFileNames,ofn.nFileOffset);//获取该多个文件所在的目录 单个文件不需要加‘\’,多个文件少个\if(szPath[lstrlen(szPath)-1]!='\\')    {lstrcat(szPath,TEXT("\\")); //这里又要犯错误了,lstrcat是连接两个字符串,\在字符串中必须是"\\"}//  MessageBox(hwnd,szPath,TEXT("szPath2"),MB_OK);TCHAR *p=szOpenFileNames+ofn.nFileOffset;//get the first file namewhile(*p){  lstrcpy(fileinfo[isong].songname,p); //  保存歌曲名     歌曲复制到 全局文件信息库lstrcpy(szFileName,szPath);lstrcat(szFileName,p);lstrcpy(fileinfo[isong].szfiledir,szFileName); //保存歌曲完整路径TCHAR puresn[255]; //纯的songname=snZeroMemory(puresn,sizeof(puresn)/sizeof(TCHAR));TCHAR *pos=strrchr(p,'.');//从后往前查找'.' .mp3的.lstrcpyn(puresn,p,pos-p+1);ZeroMemory(withnum_song,sizeof(withnum_song)/sizeof(TCHAR));wsprintf(withnum_song,TEXT("%02d  %s"),isong+1,puresn);ListBox_InsertString(hlistbox,-1,withnum_song);p=p+lstrlen(p)+1; //移动到下一个文件名ZeroMemory(szFileName,sizeof(szFileName));isong++; //歌曲自加1}}
}
     上面就是文件的操作了,包括歌曲的添加和 往ListBox中插入歌曲名字。其实全部都是文件路径的操作,我们要得到歌曲的路径,存于全局变量中 我这里是存到一个全局结构体中,用来存放歌曲名字和路径 。
typedef struct   //defined a information struct for song
{TCHAR songname[50];     //注意这个值过小 可能导致 输入的信息有误,要保证有绝对空间  查了半天的错TCHAR szfiledir[100];
}FileInfo;
FileInfo fileinfo[255];   //文件信息 只能存255首歌曲
     歌曲的名字,我们希望有标号,并且希望歌曲名字不带.mp3的字样,这里就是截取的方法,利用字符串函数的操作,来获取我们想要的文件名字。当我们同时选取了多个文件时,实际上在内存中存在的形式就是该文件的目录+各个文件名字,每个文件名字以一个'\0'隔开。在调用完(GetOpenFileName(&ofn)这个函数成功后,会将你选择的文件名全部存于该 ofn.lpstrFile=szOpenFileNames.也就是存于szOpenFileNames的数组中。
所以剩下要做两件事: 1.获取每首歌曲完整路径    2.拼写出每个歌曲的名字
将获取的名字 格式化 加上数字,就插入到Listbox中即可。具体的参见工程中的代码。

2.播放音乐

      在上面我们大概了解了这么添加文件和修改文件名,剩下的就是要播放了,其实要播放一首歌曲很简单,只需要条用mciSendCommand().函数即可,比如下面代码就可以播放一首歌曲
  mciSendCommand(DeviceId,MCI_PLAY,MCI_FROM|MCI_NOTIFY,(DWORD)(LPVOID)&mciplay);
参数1:是要播放的设备号 参数2:是要播放的命令,参数3:是从哪里播放和播放完发送给主窗口一个通知
参数4:是结构体。每个mcisendcommand 都要关联一个结构体,这要关联播放mciplay
MCIDEVICEID DeviceId=0;      //打开的设备ID号
MCI_OPEN_PARMS mciopen;  //打开结构体
MCI_PLAY_PARMS mciplay;  //播放结构体
MCI_SET_PARMS  mciset;   //设置时间格式
MCI_SEEK_PARMS mciseek; // 设置跳转到
MCI_STATUS_PARMS mcistatus; //播放状态 获得歌曲总长度
具体的意思 和怎么使用查找 MSDN手册。
      思路:就是先配置 mciopen。指定打开的路径(就是音乐文件的路径)成功打开后,得到一个设备号,然后用该设备号来操作,比如播放,暂停,关闭..附加的功能 比如获取 歌曲状态,得到歌曲的总时间。
下面代码演示了怎么打开设备和获取歌曲总时间长度
BOOL DoPlay(HWND hwnd,INT index)
{   mciopen.lpstrElementName=fileinfo[index].szfiledir;    //给打开设备指定路径mciSendCommand(DeviceId,MCI_STOP,0,0); mciSendCommand(DeviceId,MCI_CLOSE,0,0);   //先关闭全部变量的设备if(0==mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_ELEMENT,(DWORD)(LPVOID)&mciopen))  //成功返回为0{  //  MessageBox(hwnd,TEXT("MCIOPEN打开设备成功"),TEXT(""),MB_OK);DeviceId=mciopen.wDeviceID;//成功打开后将ID号保留下来。mciset.dwTimeFormat=MCI_FORMAT_MILLISECONDS; //config mciset time formatmciSendCommand(DeviceId,MCI_SET,MCI_WAIT|MCI_FORMAT_MILLISECONDS,(DWORD)(LPMCI_SET_PARMS)&mciset);//设置歌曲的长度以Ms度量 mcistatus.dwItem=MCI_STATUS_LENGTH; mciSendCommand(DeviceId,MCI_STATUS,MCI_WAIT|MCI_STATUS_ITEM,(DWORD)(LPMCI_STATUS_PARMS)&mcistatus);DWORD dwsonglen=mcistatus.dwReturn/1000; //返回歌曲的总长度 ms级别的 dwsonglen单位是秒SendDlgItemMessage(hwnd,IDC_SLIDER_SONG,TBM_SETRANGE,TRUE,MAKELPARAM(0,dwsonglen));//设置Silder的两端范围mciplay.dwFrom=0;//从0开始播放mciplay.dwCallback=(DWORD)hwnd;//播放完毕后,通该窗口处理函数mciSendCommand(DeviceId,MCI_PLAY,MCI_FROM|MCI_NOTIFY,(DWORD)(LPVOID)&mciplay);//开始播放ListBox_SetCurSel(hlistbox,iIndex);  //设置当前选中宏return TRUE;}else MessageBox(hwnd,TEXT("打开歌曲错误"),TEXT("errror!"),MB_OK);return FALSE;
}
 下个模块继续...                                          

自己动手写类似酷狗播放器(2)_音乐播放模块实现相关推荐

  1. 自己动手写类似酷狗播放器(5)_文件的保存和读取

    对于播放器,我们希望在打开的时候,播放列表存有上一次的歌曲,不必每次去添加,就是通过文件的操作实现的. 这里要实现两个: 1.在播放器打开的时候,能自动加载上一次的歌曲信息进入Listbox,并且更新 ...

  2. 自己动手写类似酷狗播放器(4)_系统托盘的显示

    任何一个应用程序,在开启后都会在任务栏的又下角显示一个图标,用来表示这个应用程序已经开启,比如QQ.那是如何做到 的呢?其实也是很简单,就是填充NOTIFYICONDATA结构体,这时候就需要对该结构 ...

  3. android音乐播放器git,Android音乐播放器

    Android音乐播放器 介绍 Android音乐播放器开发 进度 算是全部完成了,后续只会改进了. 如何使用 按这篇博客修改一下gradle相关文件,匹配自己的开发环境 日志 2020.12.15 ...

  4. android学习笔记---43_音乐播放器,音频采集,音乐播放,使用SoundPool播放音效

    43_音乐播放器 ------------------------------------------ 1.注意在string.xml中不可以使用java的关键字,因为用关键字的话,会和java内部冲 ...

  5. android 音乐播放器论文,Android音乐播放器论文-Android文档类资源

    基于android系统的音乐播放器论文.里边有详细的介绍,没有代码.只是单独的一个论文. XXX科技大学本科生毕业设计(论文) 摘要 当今社会的生活节奏越来越快,随着硬件移动设备的越来越先进,人们 对 ...

  6. Linux下的豆瓣FM音乐播放器和虾米音乐播放器

    RT.给大家介绍两个我亲测可以使用的非常流行的网页音乐播放器的本地版. A.doubanFM音乐播放器: 对于喜欢在豆瓣FM下听音乐的同学,对于打开一个网页听音乐,肯定会觉得很麻烦.这里我给大家推荐的 ...

  7. android 暂停音乐播放器,Android仿音乐播放器带进度的播放暂停按钮

    因为项目需要,要做一个下载暂停开始的按钮,要求按钮上显示进度.网上找了找没有合适的,不太满意,于是自己动手写了一个. 效果如下: 主要步骤: 1.最外侧的圆环. 2.圆环内侧代表进度的圆弧. 3.暂停 ...

  8. android音乐播放器sd,Android音乐播放器(2)从SD卡中读取音乐

    首先提一下我的UI设计,对于主页面,用到了侧滑效果,这样在一个页面上可以有更多按钮而不显得拥挤,其实也就是我的另一篇博客中(http://blog.csdn.net/ye_yun_lin/articl ...

  9. android唤醒音乐播放器,android调用音乐播放器,三种方

    小弟想请问一下.怎样在自己写的程序中调用系统的音乐播放器呢. 我在google上搜索了.主要是有两种方法,可是都不是我想要的. 第一种是.使用mp3音乐文件的uri.和intent,进行调用.可是这样 ...

最新文章

  1. Java Jaxb JavaBean与XML互转
  2. android开发环境建立以及开发工具的使用--怎样使用eclipse来开发android源码
  3. python操作gif
  4. 深度学习(二十五)基于Mutil-Scale CNN的图片语义分割、法向量估计-ICCV 2015
  5. numpy 归一化_NumPy 数据归一化、可视化
  6. 学习过osgi 发布bundle
  7. 使用Linux的alternatives命令替换选择软件的版本
  8. 最常用的看板工具,敏捷开发工具
  9. 行业研究的结构化分析方法:【PEST分析】实战案例
  10. 如何领购和作废电子发票流程
  11. 值得看三次的高干文_6本好看的高干文推荐,每本都值得看三次!
  12. 计科实训 餐馆点菜系统
  13. 自然语言处理-应用场景-文本分类:基于LSTM模型的情感分析【IMDB电影评论数据集】--(重点技术:自定义分词、文本序列化、输入数据批次化、词向量迁移使用)
  14. 【全网最全面】SourceTree使用教程详解(连接远程仓库,克隆,拉取,提交,推送,新建/切换/合并分支,冲突解决,提交PR)...
  15. 正在从你的计算机中删除office,手动删除Office 2013或Office 365即点即用安装的步骤...
  16. 含抽水蓄能电站系统的调峰经济调度研究matlab程序(粒子群算法)
  17. 《筱静观察》第三季第12期丨区块链赋能数字政府
  18. Python计算歌手得分数案例
  19. 【锐捷路由】静态路由配置
  20. AATCC 美国纺织化学师与印染师协会标准

热门文章

  1. 第九篇 Java多线程
  2. 从无名之辈到技术大神,他们是怎么做到的?
  3. pandas 何如追加Excel数据
  4. C语言圣诞树 源代码
  5. 百度地图多条线段绘制的方法
  6. 不一样的LCA——luoguP1852跳跳棋
  7. Android开发百科全书②
  8. 企企通联合创始人兼总架构师杨华:剖析SRM顾问长期主义项目实践
  9. 平台之战:京东,拿什么来跟天猫拼?
  10. Day002 费九牛二虎之力搭环境,倾洪荒之力写HelloWorld