http://www.cnblogs.com/zhangminaxiang/archive/2013/02/27/2936011.html

缘由:

  在改正俄罗斯方块程序的功能的时候,想给这个程序增加一个背景音乐。本想用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;//当前正在播放文件夹的索引 102 int m_nFileLen;//文件的总长度 103 int m_nCurPos;//当前正播放的位置 104 int m_nSound;//播放的音量大小 105 private: 106 HWND m_hWnd; 107 HANDLE m_hThread; 108 HINSTANCE m_hInstance; 109 UINT m_uDeviceID; 110 DWORD m_dwThreadID; 111 tstring m_tstrWinClassName; 112 tstring m_tstrWinCaptionName; 113 private: 114 void InitThunk() 115 { 116 m_thunk.op_movecx=0xB9;// 0xb9 mov ecx,数值的 机器码 117 m_thunk.val_ecx=(DWORD_PTR)this; 118 m_thunk.op_call=0xE9;//0xe9是Jmp 相对地址的机器码 119 DWORD_PTR off=0; 120 _asm 121 { 122 mov eax,ZMCMusic::ProcWindow 123 mov DWORD PTR[off],eax 124 } 125 m_thunk.val_address=off-((DWORD_PTR)(&m_thunk.val_address)+sizeof(DWORD_PTR)); 126 } 127 pfaCallBack GetStaticEntry() 128 { 129 return (pfaCallBack)&m_thunk; 130 } 131 private: 132 Thunk m_thunk; 133 }; 134 135 #endif

cMusic.cpp

  1 #include "cMusic.h"
  2 //程序说明开始  3 //=========================================================//  4 // 功能:类的构造函数,由于本类需要 创建一个隐藏的窗口,用来接收  5 // 播放完成之后的消息。所以在构造类的时候,很自然也需要构建一个  6 // 隐藏的窗口  7 // 参数:无  8 // 返回 :无  9 // 主要思路:  10 // 初始化一些变量 并且调用createThread函数创建一个线程,并且在线程中  11 // 创建一个窗口  12 // 调用方法:系统自动调用  13 // 作者:张敏  14 // 日期:2012-1-11 邮箱 zhang19min88@163.com  15 // 说明:  16 //=========================================================//  17 ZMCMusic::ZMCMusic()  18 {  19 m_uDeviceID=0;  20 m_tstrFileName=_T("");  21 m_tstrWinCaptionName=_T("MCI");  22 m_tstrWinClassName=_T("CMCI");  23 m_nSound=0;  24 m_nFileLen=0;  25 m_nCurPos=0;  26 m_dwThreadID=0;  27 m_nCurPlayIndex=0;  28 m_hInstance=(HINSTANCE)GetModuleHandle(NULL);  29  InitThunk();  30 }  31 void ZMCMusic::Init()  32 {  33 CreateWindowInThread();//在线程中创建一个窗口  34 }  35 ZMCMusic::~ZMCMusic()  36 {  37  38 }  39 //程序说明开始  40 //=========================================================//  41 // 功能:加载需要播放的文件  42 // 参数:tstrFileName 需要加载的文件名  43 // 返回 :成功执行返回真 否则返回假  44 // 主要思路:  45 // 调用MCISendCommand函数 发送MCI_OPEN命令  46 // 得到一个设备ID  47 // 调用方法:外部接口函数  48 // 作者:张敏  49 // 日期:2013-1-10 邮箱 zhang19min88@163.com  50 // 说明:  51 //=========================================================//  52 BOOL ZMCMusic::LoadMusicFile(tstring const tstrFileNmae)  53 {  54 m_tstrFileName=tstrFileNmae;  55  MCI_OPEN_PARMS mciOPenParms;  56 DWORD dwReturn=0;  57  58 mciOPenParms.lpstrDeviceType=_T("mpegvideo");//使用这种类型,可以播放MP3  59 mciOPenParms.lpstrElementName=m_tstrFileName.c_str();//也就是播放的音频文件的路径名  60 mciOPenParms.dwCallback=(DWORD_PTR)m_hWnd;//该命令成功执行后 想m_hWnd窗口发送一条消息  61  62 dwReturn=mciSendCommand(0,MCI_OPEN,MCI_OPEN_TYPE|MCI_OPEN_ELEMENT,(DWORD)(LPVOID)&mciOPenParms);  63 if(dwReturn!=0)  64  {  65 return FALSE;  66 }//成功打开这个设备  67 m_uDeviceID=mciOPenParms.wDeviceID; //得到一个设备的ID号  68  69 //MCI_STATUS_PARMS mciStatusParms; 70 //ZeroMemory(&mciStatusParms,sizeof(mciStatusParms)); 71 //mciStatusParms.dwItem=MCI_STATUS_LENGTH; 72 //if(mciSendCommand( m_uDeviceID , MCI_STATUS , MCI_STATUS_ITEM , (DWORD)(LPMCI_STATUS_PARMS) &mciStatusParms )==0 ) 73 //{ 74 // m_nFileLen=mciStatusParms.dwReturn; 75 //} 76 return TRUE; 77 } 78 79 //程序说明开始 80 //=========================================================// 81 // 功能:播放加载了的音频文件 82 // 参数: 83 // 返回 :成功执行返回真 否则返回假 84 // 主要思路: 85 // 调用MCISendCommand函数 发送MCI_PLAY命令 86 // 调用方法:外部接口函数 87 // 作者:张敏 88 // 日期:2013-2-26 邮箱 zhang19min88@163.com 89 // 说明: 90 // 在这里并有处理MCI_NOTIFY消息,通过这个消息我们可以知道播放是否结束 91 // 当歌曲播放完成之后 我们会收到一个播放完成的消息 92 //=========================================================// 93 BOOL ZMCMusic::Play() 94 { 95 //LoadMusicFile(m_vcPlayList[ m_nCurPlayIndex]); 96 MCI_PLAY_PARMS mciPlayParms; 97 ZeroMemory(&mciPlayParms,sizeof(mciPlayParms)); 98 mciPlayParms.dwCallback=(DWORD)m_hWnd; 99 return mciSendCommand(m_uDeviceID,MCI_PLAY,MCI_NOTIFY,(DWORD)(LPVOID)&mciPlayParms); 100 } 101 //程序说明开始 102 //=========================================================// 103 // 功能:暂停当前播放的文件 104 // 参数:无 105 // 返回 :成功执行返回真 否则返回假 106 // 主要思路: 107 // 调用MCISendCommand函数 发送MCI_PAUSE命令 108 // 调用方法:外部接口函数 109 // 作者:张敏 110 // 日期:2012-1-10 邮箱 zhang19min88@163.com 111 // 说明: 112 // 在这里并没有处理MCI_NOTIFY消息,通过这个消息我们可以知道播放是否结束 113 //=========================================================// 114 BOOL ZMCMusic::Pause() 115 { 116 MCI_GENERIC_PARMS mciGenericParms; 117 ZeroMemory(&mciGenericParms,sizeof(mciGenericParms)); 118 mciGenericParms.dwCallback=(DWORD_PTR)m_hWnd; 119 return mciSendCommand(m_uDeviceID,MCI_PAUSE,MCI_WAIT,(DWORD)(LPVOID)&mciGenericParms); 120 } 121 //程序说明开始 122 //=========================================================// 123 // 功能:继续播放当前被暂停播放的文件 124 // 参数:无 125 // 返回 :成功执行返回真 否则返回假 126 // 主要思路: 127 // 调用MCISendCommand函数 发送MCI_RESUME命令 128 // 调用方法:外部接口函数 129 // 作者:张敏 130 // 日期:2012-1-10 邮箱 zhang19min88@163.com 131 // 说明: 132 // 133 //=========================================================// 134 BOOL ZMCMusic::Resume() 135 { 136 MCI_GENERIC_PARMS mciGenericParms; 137 ZeroMemory(&mciGenericParms,sizeof(mciGenericParms)); 138 return mciSendCommand(m_uDeviceID,MCI_RESUME,MCI_NOTIFY,(DWORD)(LPVOID)&mciGenericParms); 139 } 140 //程序说明开始 141 //=========================================================// 142 // 功能:停止播放的文件 143 // 参数:无 144 // 返回 :成功执行返回真 否则返回假 145 // 主要思路: 146 // 调用MCISendCommand函数 发送MCI_STOP命令 147 // 调用方法:外部接口函数 148 // 作者:张敏 149 // 日期:2012-1-10 邮箱 zhang19min88@163.com 150 // 说明: 151 // 这个命令和PAUSE是不同的 pause只是暂停播放,但播放的内容依然在内存中,可以继续播放 152 // 而STOP则是该文件退出资源 不能继续播放 153 //对于这个命令的确切理解MSDN上说 它和Pause的区别是看不同的设备来说的 154 //=========================================================// 155 BOOL ZMCMusic::Stop() 156 { 157 return mciSendCommand(m_uDeviceID,MCI_STOP,NULL,NULL); 158 } 159 //程序说明开始 160 //=========================================================// 161 // 功能:关闭播放设备 162 // 参数:无 163 // 返回 :成功执行返回真 否则返回假 164 // 主要思路: 165 // 调用MCISendCommand函数 发送MCI_CLOSE命令 166 // 调用方法:外部接口函数 167 // 作者:张敏 168 // 日期:2013-1-11 邮箱 zhang19min88@163.com 169 // 说明: 170 // 这个命令和PAUSE是不同的 pause只是暂停播放,但播放的内容依然在内存中,可以继续播放 171 // 而STOP则是该文件退出资源 不能继续播放 172 //=========================================================// 173 BOOL ZMCMusic::Close() 174 { 175 return mciSendCommand(m_uDeviceID,MCI_CLOSE,NULL,NULL); 176 } 177 //程序说明开始 178 //=========================================================// 179 // 功能:重新播放 180 // 参数:无 181 // 返回 :成功执行返回真 否则返回假 182 // 主要思路: 183 // 调用CLose()函数 关闭设备 然后调用LoadMusicFile()函数打开设备 最后调用Play()函数进行播放 184 // 调用方法:外部接口函数 185 // 作者:张敏 186 // 日期:2013-2-27 邮箱 zhang19min88@163.com 187 // 说明: 188 //=========================================================// 189 BOOL ZMCMusic::Replay() 190 { 191 Close(); 192 LoadMusicFile(m_tstrFileName); 193 return Play(); 194 } 195 196 197 198 int ZMCMusic::MakeWindow() 199 { 200 MSG stMsg; 201 TCHAR szClassName[]=_T("MCI"); 202 203 WNDCLASSEX stWC; 204 ZeroMemory(&stWC,sizeof(stWC)); 205 stWC.hCursor=LoadCursor(NULL,IDC_ARROW); 206 stWC.cbSize=sizeof(stWC); 207 stWC.style=CS_HREDRAW|CS_VREDRAW; 208 stWC.lpfnWndProc=(WNDPROC)ZMCMusic::GetStaticEntry();//将类成员函数作为窗口过程函数 209 //stWC.lpfnWndProc=DefWindowProc; 210 stWC.lpszClassName=m_tstrWinClassName.c_str(); 211 stWC.cbClsExtra=0; 212 stWC.hInstance=m_hInstance; 213 214 RegisterClassEx(&stWC); 215 216 m_hWnd=CreateWindowEx(WS_EX_CLIENTEDGE,m_tstrWinClassName.c_str(),m_tstrWinCaptionName.c_str(),WS_OVERLAPPEDWINDOW,100,100,600,700,NULL,NULL,m_hInstance,NULL); 217 if(m_hWnd==NULL) 218 { 219 ShowError(); 220 } 221 ShowWindow(m_hWnd,SW_HIDE); 222 UpdateWindow(m_hWnd); 223 while(GetMessage(&stMsg,NULL,0,0)) 224 { 225 TranslateMessage(&stMsg); 226 DispatchMessage(&stMsg); 227 } 228 return 0 ; 229 } 230 231 //程序说明开始 232 //=========================================================// 233 // 功能:窗口过程的处理函数 234 // 参数:hWNd uMsg wParam lParam 正常窗口回调函数 235 // 返回 :无 236 // 主要思路: 237 // 在这个回调函数中我们完成的就是处理MM_MCINOTIFY消息,主要是对MCI播放命令的执行结果进行响应 238 // 最关键的一个结果是通过这个消息的处理我们可以知道什么时候音乐播放完成 239 // 调用方法:系统自动调用 240 // 作者:张敏 241 // 日期:2012-1-11 邮箱 zhang19min88@163.com 242 // 说明: 243 //=========================================================// 244 245 //这个类该怎样利用还不是很清楚 246 LRESULT ZMCMusic::ProcWindow(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) 247 { 248 switch(uMsg) 249 { 250 case WM_CREATE: 251 // MessageBox(NULL,_T("MCI"),_T("MCI"),MB_OK); 252 break; 253 case MM_MCINOTIFY://当播放完成之后 254 //在这里可以进行很多设置 255 //比喻说设定单曲循环 256 //设置自动播放下一首等等 257 //关键是如何用代码进行封装 258 //MessageBox(NULL,_T("MCI"),_T("Play End!"),MB_OK); 259 this->Replay(); 260 break; 261 case MY_WM_PLAY: break; 262 case MY_WM_PAUSE:break; 263 case MY_WM_STOP:break; 264 case MY_WM_RESUME:break; 265 case MY_WM_REPLAY:break; 266 case MY_WM_PLAYNEXT:break; 267 case MY_WM_PLAYLAST:break; 268 case MY_WM_PLAY_LOOP:break; 269 default: 270 return DefWindowProc(hWnd,uMsg,wParam,lParam); 271 } 272 return 0; 273 } 274 275 //程序说明开始 276 //=========================================================// 277 // 功能:线程函数 278 //在这个函数中我们接受一个创建线程时的一个参数this 因为线程可以传递一个参数 279 // 在这个程序的处理过程中 我很好的解决了在内中调用线程的例子 280 // 以前遇到这种问题几次了,都是用一种不是很好的方式解决,今天算是搞清楚了 281 // 在类中创建线程,那么线程函数必须为全局函数,或者是静态函数,因为线程函数只能有一个参数,如果为成员函数,那么就会有一个默认的this 282 // 所以不行 我首先将它定义为友元函数,然后从线程函数中传递参数this这样就可以很好的解决这个问题了 283 // 参数:this指针 284 // 返回 :DWORD 285 // 主要思路: 286 // 调用类的方法创建一个隐藏的窗口 287 // 调用方法:系统自动调用 288 // 作者:张敏 289 // 日期:2012-1-11 邮箱 zhang19min88@163.com 290 // 说明: 291 //=========================================================// 292 DWORD WINAPI ThreadProc(LPVOID lParam) 293 { 294 ZMCMusic *pMusic=NULL; 295 pMusic=(ZMCMusic *)lParam; 296 return pMusic->MakeWindow(); 297 } 298 299 //程序说明开始 300 //=========================================================// 301 // 功能:启动一个新的线程来创建一个窗口 302 // 参数:无 303 // 返回 :int 304 // 主要思路: 305 // 创建一个新的线程 306 // 调用方法:系统自动调用 307 // 作者:张敏 308 // 日期:2012-1-11 邮箱 zhang19min88@163.com 309 // 说明: 310 //=========================================================// 311 int ZMCMusic::CreateWindowInThread() 312 { 313 m_hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc,(LPVOID)this,0,&m_dwThreadID); 314 WaitForSingleObject(m_hThread,500); 315 return 0; 316 } 317 318 //程序说明开始 319 //=========================================================// 320 // 功能:输出最近一次的错误信息 321 // 返回 :成功执行返回真 否则返回假 322 // 主要思路: 323 // 调用InternetReadFile函数 324 // 调用方法: 325 // 作者:张敏 326 // 日期:2012-1-7 邮箱 zhang19min88@163.com 327 // 说明: 328 //=========================================================// 329 void ZMCMusic::ShowError() 330 { 331 #define ERROR_BUF 256 332 TCHAR szBuf[ERROR_BUF]; 333 LPVOID lpMsgBuf; 334 DWORD dw=GetLastError(); 335 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,dw,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR)&lpMsgBuf,0,NULL); 336 wsprintf(szBuf,_T("执行失败!错误码为:%d. 错误原因为:%s\n"),dw,lpMsgBuf); 337 MessageBox(NULL,szBuf,_T("错误"),MB_OK); 338 } 339 //程序说明开始 340 //=========================================================// 341 // 功能:得到文件当前播放的位置 342 // 返回 :无 343 // 主要思路: 344 // 发送MCI_STATUS命令获得 345 // 主要是得到状态 346 // 调用方法: 347 // 作者:张敏 348 // 日期:2012-1-7 邮箱 zhang19min88@163.com 349 // 说明: 350 //=========================================================// 351 void ZMCMusic::GetCurPos() 352 { 353 MCI_STATUS_PARMS mciStatusParms; 354 mciStatusParms.dwItem=MCI_STATUS_POSITION; 355 if(mciSendCommand( m_uDeviceID , MCI_STATUS , MCI_STATUS_ITEM , (DWORD)(LPMCI_STATUS_PARMS) &mciStatusParms )==0 ) 356 { 357 m_nCurPos=mciStatusParms.dwReturn; 358 } 359 } 360 //程序说明开始 361 //=========================================================// 362 // 功能:得到文件的长度 363 // 返回 :无 364 // 主要思路: 365 // 发送MCI_STATUS命令获得 366 // 主要是得到状态 367 // 调用方法: 368 // 作者:张敏 369 // 日期:2012-2-27 邮箱 zhang19min88@163.com 370 // 说明: 371 //=========================================================// 372 void ZMCMusic::GetFileLenth() 373 { 374 MCI_STATUS_PARMS mciStatusParms; 375 mciStatusParms.dwItem=MCI_STATUS_LENGTH;//获得文件的长度 376 if(mciSendCommand( m_uDeviceID , MCI_STATUS , MCI_STATUS_ITEM , (DWORD)(LPMCI_STATUS_PARMS) &mciStatusParms )==0 ) 377 { 378 m_nFileLen=mciStatusParms.dwReturn; 379 } 380 } 381 //程序说明开始 382 //=========================================================// 383 // 功能:将文件夹中的*.MP3文件和*.wav文件读取出来按照顺序添加到播放列表 384 // 返回 :无 385 // 主要思路: 386 // 在文件夹中查找*.mp3和*.wav的文件,然后放在容器中 387 // 调用方法: 388 // 作者:张敏 389 // 日期:2012-1-7 邮箱 zhang19min88@163.com 390 // 说明: 391 //=========================================================// 392 void ZMCMusic::AddPlayList(tstring tstrDir) 393 { 394 395 }

main.cpp

 1 #include "cMusic.h"
 2
 3 void ShowMenu()  4 {  5 tcout<<"Press 0 to EXIT"<<endl;  6 tcout<<"Press 1 to PLAY"<<endl;  7 tcout<<"Press 2 to PAUSE"<<endl;  8 tcout<<"Press 3 to RESUSE"<<endl;  9 tcout<<"Press 4 to STOP"<<endl; 10 tcout<<"Press 5 to FULLSCAN"<<endl; 11 tcout<<"Press 6 to CLOSE"<<endl; 12 tcout<<"Press 7 to REPALY"<<endl; 13 tcout<<"Press 8 to SHOWPOS"<<endl; 14 tcout<<"Press 9 to STOP"<<endl; 15 16 } 17 int main() 18 { 19  tstring strFileName; 20 strFileName=_T("D:\\musicTest\\ifLove.mp3"); 21 // strFileName=_T("D:\\musicTest\\msg.mp3"); 22 23  ZMCMusic music; 24  music.Init(); 25 //music.AddPlayList(strFileName); 26  music.LoadMusicFile(strFileName); 27 28 int nKey=0; 29 bool bExit=false; 30 while(!bExit) 31  { 32  ShowMenu(); 33 tcout<<_T("You Command:"); 34 tcin>>nKey; 35 switch(nKey) 36  { 37 case 0:bExit=true;break; 38 case 1:music.Play();break; 39 case 2:music.Pause();break; 40 case 3:music.Resume();break; 41 //case 4:music.Stop();break; 42 case 6:music.Close();break; 43 case 7:music.Replay();break; 44 //case 8:SendMessage(g_hWnd,WM_CLOSE,NULL,NULL);break; 45 default:break; 46  } 47 Sleep(500); 48  } 49 return 0; 50 }

运行结果:

注意:

这个类还有一些功能没有实现。

其中不是很理解PAUSE  STOP CLOSE 这三个命令的区别。还待以后研究……

自己封装的CMusic类 【转】相关推荐

  1. Java封装OkHttp3工具类

    点击关注公众号,Java干货及时送达  作者:如漩涡 https://blog.csdn.net/m0_37701381 Java封装OkHttp3工具类,适用于Java后端开发者 说实在话,用过挺多 ...

  2. writeValueAsString封装成工具类

    封装成工具类 [java] view plaincopyprint? <span style="font-family:Microsoft YaHei;">public ...

  3. MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)...

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  4. spring入门(11)-spring与hibernate整合完成增删改查的操作(封装HibernateTemplate模版类对象)

    今天是spring的最后一节课,这节课老师讲了spring与hibernate整合完成增删改查的操作,这是很重要的一节课,这也是第一次真正的实现spring结合Hibernate和数据库连接上,下面是 ...

  5. php面向对象分页,PHP基于面向对象封装的分页类示例

    本文实例讲述了php基于面向对象封装的分页类.分享给大家供大家参考,具体如下: class page { protected $num;//每页显示条数 protected $total;//总记录数 ...

  6. 1.使用C++封装一个链表类LinkList

     使用C++封装一个链表类LinkList.写出相应一个测试用例 链表需要提供 添加 修改删除 除重 合并 排序创建 销毁等接口. 不能调用库函数或者使用STL等类库 题目延伸********** ...

  7. 基于mysqli封装的数据库类

    本文实例讲述了php封装的mysqli类.分享给大家供大家参考,具体如下: 类:     <?php header('content-type:text/html;charset=utf-8') ...

  8. 基于AFNetworking的封装的工具类

    基于AFNetworking的封装的工具类MXERequestService // // MXERequestService.h // testAFNetWorking // // Created b ...

  9. php smarty框架案例,php封装的smarty类案例

    这篇文章主要介绍了php封装的smarty类,针对Smarty的基本操作技巧进行了封装整理,具有一定参考借鉴价值,需要的朋友可以参考下 具体如下: /** * Project: Smarty: the ...

最新文章

  1. jstl 处理Date 时间
  2. html盒子嵌套居中,css在盒子中垂直居中和固定居中
  3. 新时代培育新动能:2021年“专精特新”发展蓝皮书
  4. Rust: 逆序输出str
  5. 《反欺骗的艺术》读后感
  6. 单片机中断实验 EX0
  7. 2020大学计算机知到答案,2020知到APP大学计算机(北华大学)章节测试答案
  8. 《未来简史》--读后感
  9. Spring Security系列(一)——登录认证基本配置
  10. Unity做360度的全景照片
  11. 网页怎么算切屏_电脑怎么切屏
  12. angular4 监听input框输入值的改变 (实用、赞)
  13. 计算机专业学生如何找到一份优质实习?如何进大厂呢?
  14. [4G5G专题-43]:物理层-4G/5G参考信号大全(DM-RS, PT-RS, CSI-RS, SRS)
  15. 企业服务从业者必读:从格局到发展,一场破与立的论断
  16. 使用QianWei网站源码配合cpolar,发布本地音乐分享网站
  17. libjpeg用法linux压缩,使用libjpeg对图像进行压缩
  18. Java使用geotools将Geometry(地图要素)导出为shp文件
  19. 硬盘视频文件损坏如何快速恢复
  20. QT 借助 图表 实现音频频谱的绘制

热门文章

  1. 文献解读 | 科学家发现代谢调控促进肿瘤转移新机制
  2. 《交互式程序设计 第2版》一1.2.4 交互语言
  3. 值得学习的开源web项目
  4. 《数值分析》-- 埃尔米特插值与分段插值
  5. composer global require fxp/composer-asset-plugin:1.0.0的Not enough arguments解决
  6. flink各版本变化和新增特性
  7. Python repr函数——学习笔记
  8. ros python 控制手柄数据发布频率
  9. 完美解决Macbook安装win 10调节亮度的问题
  10. 伊利诺伊大学厄本那 香槟分校计算机科学,伊利诺伊大学厄本那-香槟分校计算机科学面试经验汇总...