缘由:
在改正俄罗斯方块程序的功能的时候,想给这个程序增加一个背景音乐。本想用PlayWave来做的,但想到这个功能十分常用,那还不如封装一个自己的CMusic
类,以备不时之需。本来以为很容易的,可是在真正操作的时候,却出现了一个问题,就是无法准确的知道什么时候音乐播放完成。问题的难道就在于,怎样将类的成员函数作为窗口的回调函数。
原本用thunk来解决这个问题的,但是在解决的时候出现了一个问题,调试了好几天都没有解决。直到最近才解决。(也就是前一篇文章的由来)
代码:(前面定义的宏主要是解决Unicode问题)
cMusic.h
1 #ifndef CMUSIC_H
2 #define CMUSIC_H
3
4 #ifdef _UNICODE
5 #define tstring wstring
6 #define tcout wcout
7 #define tcin wcin
8 #else
9 #define tstring string
10 #define tcout cout
11 #define tcin cin
12
13 #endif
14
15 #pragma warning(disable:4311)
16
17 #include "TCHAR.h"
18 #include<iostream>
19 #include<windows.h>
20 #include<string>
21 #include<vector>
22 #include<MMSystem.h>
23 #pragma comment(lib,"Winmm.lib")
24 using namespace std;
25
26 typedef LRESULT (*pfaCallBack)(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
27 #pragma pack(push,1)
28 struct Thunk
29 {
30 BYTE op_movecx;
31 DWORD_PTR val_ecx;
32 BYTE op_call;
33 DWORD_PTR val_address;
34 };
35 #pragma pack(pop)
36
37 #define MY_WM_PLAY WM_USER+1
38 #define MY_WM_PAUSE WM_USER+2
39 #define MY_WM_STOP WM_USER+3
40 #define MY_WM_CLOSE WM_USER+4
41 #define MY_WM_PLAYNEXT WM_USER+5
42 #define MY_WM_PLAYLAST WM_USER+6
43 #define MY_WM_REPLAY WM_USER+7
44 #define MY_WM_PLAY_LOOP WM_USER+8
45 #define MY_WM_RESUME WM_USER+9
46 #define MY_WM_TEST0 WM_USER+10
47
48 //类说明开始
49 //=========================================================//
50 // 功能:播放音乐以及进行相关的控制
51 // 设计思路:
52 // 这个类的实现应该会比较简单,主要是利用MCI开头的函数来进行控制
53 // 最主要实现一下功能:
54 // 播放一个音频文件
55 // 暂停播放
56 // 恢复播放
57 // 得到音频文件的信息
58 // 文件名
59 // 长度
60 // 当前播放的位置
61 // 显示播放列表//一个文件夹中的所有MP3或者是wav文件
62 // 播放上一首
63 // 播放下一首
64 //
65 // 作者:张敏
66 // 日期:2013-1-10 邮箱 zhang19min88@163.com
67 // 注意:实现这个类我的最大的感想就是不要想在一个类中封装所有的函数
68 // 在真正要用的时候再进行继承
69 //也许这样不会焦头乱额
70 //=========================================================//
71 class ZMCMusic
72 {
73 public:
74 friend DWORD WINAPI ThreadProc(LPVOID);
75 public:
76 ZMCMusic();//构造函数
77 ~ZMCMusic();//析构函数
78 public:
79 void Init();
80 void AddPlayList(tstring tstrDir);
81 BOOL Play();
82 BOOL Pause();
83 BOOL Resume();
84 BOOL Stop();
85 BOOL Close();
86 BOOL Replay();
87 BOOL PlayNext();//播放下一曲
88 BOOL playLast();//播放上一曲
89 BOOL GetFileInfo();
90 BOOL LoadMusicFile(tstring const tstrFileNmae);
91 static void ShowError();
92 private:
93 void GetCurPos();
94 void GetFileLenth();
95 int MakeWindow();//产生一个窗口
96 int CreateWindowInThread();//在线程中创建窗口
97 LRESULT ProcWindow(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);//窗口过程的处理函数
98 private:
99 tstring m_tstrFileName;
100 vector<tstring> m_vcPlayList;//保存播放列表
101 int m_nCurPlayIndex;