描画ができたら次は音を再生したいと思うのが自然な流れです サウンドを扱う場合は「winmm.lib」をリンクさせる必要があります #pragma comment(lib,"winmm.lib") ただ鳴らすだけなら PlaySound関数一行で鳴らせますが・・・ PlaySound(WAVEファイル名, NULL, SND_FILENAME | SND_ASYNC); ファイルの読み込みを毎回行うせいで遅い上 Waveファイル(.wav)しか読めません 細かい制御も利きません 細かい制御やmp3やAVIなどのマルチメディアを取り扱うには MCI(Media Control Interface / Multimedia Control Interface)を使います 今回はメディアをオブジェクトとして扱いため、クラス化しています 今回以降はクラスを積極的に使っていく(というか使わざるを得ない)ので 不安な人はC++のクラスを勉強してください すでに講座も作ってあります --------------------------------------------------------------- ヘッダーファイル部です WAV,MP3,MIDI,CD_AUDIO,AVI の読み込みと再生、停止などを扱うことができます //--------------------------------------------// // ファイル名:MCI.h // 概要: 音ファイル再生関係 // // 作成者:Daiki Terai // 作成日:2010/10/23 // 修正履歴: //--------------------------------------------// #ifndef _MCI_H_ #define _MCI_H_ #include <windows.h> #include <tchar.h> #pragma comment(lib, "winmm.lib") // メディアタイプ enum EMEDIA { WAVE, MIDI, MP3, CD_AUDIO, AVI }; // MCIクラス class CMCI { private: MCIDEVICEID m_ID; // ID public: CMCI(); virtual ~CMCI(); // メディアを開く bool Open(const TCHAR* FileName,EMEDIA Media); //-------------------------------------------------------------------// // 再生 // ループ再生するときは通知メッセージ処理するので // ウィンドウハンドルを渡すこと // // 引数: bLoop ループ再生フラグ // hWnd 処理終了通知メッセージを受け取るウィンドウハンドル //-------------------------------------------------------------------// void Play(bool bLoop = false,HWND hWnd = NULL); // 停止 void Stop(); // 巻き戻し void Rewind(); // 一時停止 void Pause(); // 一時停止解除 void Resume(); // 現在位置取得 DWORD GetPos(); // 再生時間取得 DWORD GetLength(); // 閉じる void Close(); }; #endif --------------------------------------------------------------- ヘッダーファイルの実装ファイルです ファイルオープン、(ループ)再生、停止などの基本的な機能の実装をしています // MCI.cpp #define _CRT_SECURE_NO_WARNINGS // 警告抑制用 #define _CRT_NON_CONFORMING_SWPRINTFS // 警告抑制用 #include "MCI.h" CMCI::CMCI():m_ID(0) {} CMCI::~CMCI(){ this->Stop(); this->Close(); } // メディアを開く bool CMCI::Open(const TCHAR* FileName,EMEDIA Media){ MCI_OPEN_PARMS MCIOpen = {}; // 開く用 switch(Media){ case WAVE: { MCIOpen.lpstrDeviceType = _T("WaveAudio"); break; } case MIDI: { MCIOpen.lpstrDeviceType = _T("Sequencer"); break; } case MP3: { MCIOpen.lpstrDeviceType = _T("MPEGVideo"); break; } case CD_AUDIO: { MCIOpen.lpstrDeviceType = _T("CDAudio"); break; } case AVI: { MCIOpen.lpstrDeviceType = _T("avivideo"); break; } } MCIOpen.lpstrElementName = FileName; if(mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD_PTR)&MCIOpen) != 0){ TCHAR Buf[MAX_PATH] = {}; _stprintf(Buf,_T("%sが開けませんでした"),FileName); MessageBox(NULL,Buf,NULL,MB_OK); return false; } m_ID = MCIOpen.wDeviceID; // ミリ秒単位に設定 MCI_SET_PARMS MCISet = {}; MCISet.dwTimeFormat = MCI_FORMAT_MILLISECONDS; mciSendCommand(m_ID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)&MCISet); return true; } //-------------------------------------------------------------------// // 再生 // ループ再生するときは通知メッセージ処理するので // ウィンドウハンドルを渡すこと // // 引数: bLoop ループ再生フラグ // hWnd 処理終了通知メッセージを受け取るウィンドウハンドル //-------------------------------------------------------------------// void CMCI::Play(bool bLoop,HWND hWnd) { if(bLoop){ MCI_PLAY_PARMS MCIPlay = {}; // MCI再生設定 MCIPlay.dwCallback = (DWORD_PTR)hWnd;// MM_NOTIFYメッセージを受け取るウィンドウ mciSendCommand(m_ID,MCI_PLAY, MCI_NOTIFY,(DWORD_PTR)&MCIPlay); } else{ mciSendCommand(m_ID,MCI_PLAY, 0,0); } } // 停止 void CMCI::Stop(){ mciSendCommand(m_ID,MCI_STOP,0,0); } // 巻き戻し void CMCI::Rewind(){ mciSendCommand(m_ID,MCI_SEEK,MCI_SEEK_TO_START,0); } // 一時停止 void CMCI::Pause(){ mciSendCommand(m_ID,MCI_PAUSE,0,0); } // 一時停止解除 void CMCI::Resume(){ mciSendCommand(m_ID,MCI_RESUME,0,0); } // 閉じる void CMCI::Close(){ MCI_GENERIC_PARMS MCIGeneric = {}; // データ mciSendCommand( m_ID, MCI_CLOSE, 0, (DWORD_PTR)&MCIGeneric); } SIZE(30){ COLOR(#ffaa00){ MCIを制御するにはmciSendCommand関数を使います }} メディアを開くには MCI_OPEN_PARMS構造体を使います lpstrDeviceTypeには開くメディアのタイプを文字列で指定します lpstrElementNameにはファイル名を指定します 実際にメディアを開いているのはこの箇所です if(mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD_PTR)&MCIOpen) != 0){ TCHAR Buf[MAX_PATH] = {}; _stprintf(Buf,_T("%sが開けませんでした"),FileName); MessageBox(NULL,Buf,NULL,MB_OK); return false; } オープンに成功したら一意なIDが wDeviceIDに格納されています このIDは再生、停止などの制御に使うので覚えておきます m_ID = MCIOpen.wDeviceID; 時間の単位をミリ秒に設定します 特に設定しなくても再生などはできますが設定すると制御がしやすくなります // ミリ秒単位に設定 MCI_SET_PARMS MCISet = {}; MCISet.dwTimeFormat = MCI_FORMAT_MILLISECONDS; mciSendCommand(m_ID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)&MCISet); 再生箇所は次のようになっています //-------------------------------------------------------------------// // 再生 // ループ再生するときは通知メッセージ処理するので // ウィンドウハンドルを渡すこと // // 引数: bLoop ループ再生フラグ // hWnd 処理終了通知メッセージを受け取るウィンドウハンドル //-------------------------------------------------------------------// void CMCI::Play(bool bLoop,HWND hWnd) { if(bLoop){ MCI_PLAY_PARMS MCIPlay = {}; // MCI再生設定 MCIPlay.dwCallback = (DWORD_PTR)hWnd;// MM_NOTIFYメッセージを受け取るウィンドウ mciSendCommand(m_ID,MCI_PLAY, MCI_NOTIFY,(DWORD_PTR)&MCIPlay); } else{ mciSendCommand(m_ID,MCI_PLAY, 0,0); } } ここでループ再生させるときは、ウィンドウにメディアの再生が終了したときを知らせなければなりません ---------------------------------------------------------------------- メインコードに自作のMCI.hをインクルードさせる必要があります また、CMCIクラス変数もグローバル変数として作成しておきましょう (本当はグローバル変数は使いたくないんですが・・・ ウィンドウをクラス化すればこの問題は解決できます) #include "MCI.h" #include <tchar.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <windowsx.h> #include <commctrl.h> #pragma comment(lib,"comctl32.lib") #pragma comment(lib,"winmm.lib") // MCI CMCI g_Media[2]; -------------------------------------------------------------------- メッセージ処理部分です //------------------------------------------------------// // ウィンドウ作成メッセージ処理 // // 引数: hWnd ウィンドウハンドル // lpCreateStruct ウィンドウ作成情報 //------------------------------------------------------// BOOL OnCreate(HWND hWnd,LPCREATESTRUCT lpCreateStruct){ g_Media[0].Open(_T("あぶないおにいちゃんです.mp3"),MP3); g_Media[1].Open(_T("ゆっくりしていってね.wav"),WAVE); g_Media[0].Play(true,hWnd); g_Media[1].Play(); return TRUE; } //------------------------------------------------------// // ウィンドウ破棄メッセージ処理 // // 引数: hWnd ウィンドウハンドル //------------------------------------------------------// void OnDestroy(HWND hWnd){ PostQuitMessage(0); } //-----------------------------------------------------// // ウィンドウプロシージャ // デフォルトの処理はDefWindowProc関数で行う // // 引数: hWnd ウィンドウハンドル // msg メッセージ // wParam パラメータ // lParam パラメータ // // 戻り値:処理結果 //-----------------------------------------------------// LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg){ HANDLE_MSG(hWnd,WM_CREATE,OnCreate); // MCI処理終了通知メッセージ case MM_MCINOTIFY:{ MCI_PLAY_PARMS mciPlay; // 通知メッセージ失敗 if (wParam != MCI_NOTIFY_SUCCESSFUL) return 0; // 初期位置に戻す mciSendCommand((MCIDEVICEID)lParam, MCI_SEEK, MCI_SEEK_TO_START, 0); mciPlay.dwCallback = (DWORD_PTR)hWnd; // ループ再生 mciSendCommand((MCIDEVICEID)lParam, MCI_PLAY, MCI_NOTIFY, (DWORD_PTR)&mciPlay); return 0; } HANDLE_MSG(hWnd,WM_DESTROY,OnDestroy); } return DefWindowProc(hWnd, msg, wParam, lParam); } 全ソースコードと音ファイルは下からダウンロードしてください &ref(main.zip); ソースファイルと音ファイルは 作成したプロジェクトと同じ場所においてください #vote((^ω^)やったお[0],何これwww意味不すぎwww[0],。(`ω´#)。あぁん?最近、だらしねぇな[0])