⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 canvasframe.cpp

📁 《Visual C++游戏设计入门》配套代码
💻 CPP
字号:
// canvasFrame.cpp : implementation file
//

#include "stdafx.h"
#include "canvasr.h"
#include "canvasFrame.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// canvasFrame

IMPLEMENT_DYNCREATE(canvasFrame, CFrameWnd)
LPDIRECTSOUND pDS;          //声明 DirectSound 对象指针
LPDIRECTSOUNDBUFFER pPBuf;  //声明主缓冲区指标
LPDIRECTSOUNDBUFFER pSBuf[6];  //声明次缓冲区
WAVEFORMATEX pwfmt;         //声明声音结构
WAVEFORMATEX swfmt;         //声明声音结构
DSBUFFERDESC dsdesc;          //声明描述结构
MMCKINFO      ckRiff;       //RIFF 区块的信息  
MMCKINFO      ckInfo;       //子区块的信息
MMRESULT	  mmresult;     //传回结果
HMMIO hmmio;                //开启的多媒体文件
DWORD size;                 //实际数据大小
HRESULT result;             //声明HRESULT型态变量
LPVOID pAudio;
DWORD bytesAudio;
int now;
int volume=-1000;
int pan=0;
canvasFrame::canvasFrame()
{
	RECT rect;
	Create(NULL,"绘图窗口",WS_OVERLAPPEDWINDOW,CRect(0,0,400,380));
	CClientDC dc(this);
	int width = dc.GetDeviceCaps(HORZRES);
	int height = dc.GetDeviceCaps(VERTRES);
	GetWindowRect( &rect );
	width = ( width - ( rect.right - rect.left ))/2 ;
	height = (height - (rect.bottom - rect.top ))/2 ;
	MoveWindow( width , height , (rect.right - rect.left ) , (rect.bottom - rect.top ) ,true);
}

canvasFrame::~canvasFrame()
{
	delete play;
	delete stop;
	delete loop;
	delete listbox;
	delete volumn;
	delete channel;
	for(int i=0;i<7;i++)
		delete title[i];
	pPBuf->Release();
	for(i=0;i<6;i++)
		pSBuf[i]->Release();
	pDS->Release();
}


BEGIN_MESSAGE_MAP(canvasFrame, CFrameWnd)
	//{{AFX_MSG_MAP(canvasFrame)
	ON_WM_CREATE()
	ON_BN_CLICKED(3,OnPlayDown)
	ON_BN_CLICKED(4,OnLoopDown)
	ON_BN_CLICKED(2,OnStopDown)
	ON_WM_VSCROLL()
	ON_WM_CHAR()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// canvasFrame message handlers
void canvasFrame::OnStopDown()
{
	pSBuf[now]->Stop();
}
void canvasFrame::OnPlayDown()
{
	pSBuf[now]->Stop();
	DWORD num ;
	int index;
	index = listbox->GetCurSel();  	   //选得选项索引值
	num = listbox->GetItemData(index); //取得选项数据值
	pSBuf[num]->SetCurrentPosition(0); //设定播放起点
	pSBuf[num]->SetVolume(volume);     //设定音量
	pSBuf[num]->SetPan(pan);           //设定声道
	pSBuf[num]->Play(0,0,0);           //播放
	now = num;                         //重设播放曲号
}
void canvasFrame::OnLoopDown()
{
	pSBuf[now]->Stop();
	DWORD num ;
	int index;
	index = listbox->GetCurSel();	   //选得选项索引值
	num = listbox->GetItemData(index); //取得选项数据值
	pSBuf[num]->SetCurrentPosition(0); //设定播放起点
	pSBuf[num]->SetVolume(volume);     //设定音量
	pSBuf[num]->SetPan(pan);           //设定声道
	pSBuf[num]->Play(0,0,1);           //循环播放
	now = num;                         //重设播放曲号
}

int canvasFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
    result = DirectSoundCreate( NULL, &pDS, NULL ); //建立 DirectSound 对象
	if(result != DS_OK)
		MessageBox("建立 DirectSound 对象失败!");
    result = pDS->SetCooperativeLevel( m_hWnd, DSSCL_PRIORITY );
	if(result != DS_OK)
		MessageBox("设定协调层级失败!");
    memset( &dsdesc,0, sizeof(dsdesc) );          //清空结构内容
    dsdesc.dwSize        = sizeof(dsdesc);        //配置描述结构大小
    dsdesc.dwFlags       = DSBCAPS_PRIMARYBUFFER;
    dsdesc.dwBufferBytes = 0;
    dsdesc.lpwfxFormat   = NULL;
    result = pDS->CreateSoundBuffer( &dsdesc, &pPBuf, NULL );
	if(result != DS_OK)
		MessageBox("建立主缓冲区失败!");
    memset( &pwfmt,0, sizeof(pwfmt) );
    pwfmt.wFormatTag      = WAVE_FORMAT_PCM;
    pwfmt.nChannels       = 2;               //播放声道
    pwfmt.nSamplesPerSec  = 44100;           //播放频率
    pwfmt.wBitsPerSample  = 16;              //位
    pwfmt.nBlockAlign     = pwfmt.wBitsPerSample / 8 * pwfmt.nChannels;
    pwfmt.nAvgBytesPerSec = pwfmt.nSamplesPerSec * pwfmt.nBlockAlign;
    result = pPBuf->SetFormat(&pwfmt);       //设定播放格式
	if(result != DS_OK)
		MessageBox("设定播放格式失败!");
	title[0] = new CStatic;
	title[0]->Create("请选择要播放的音乐",WS_VISIBLE,CRect(10,10,240,40),this,100);
	title[1] = new CStatic;
	title[1]->Create("音量",WS_VISIBLE,CRect(250,10,290,40),this,101);
	title[2] = new CStatic;
	title[2]->Create("声道",WS_VISIBLE,CRect(290,10,330,40),this,102);
	title[3] = new CStatic;
	title[3]->Create("小",WS_VISIBLE|SS_CENTER,CRect(250,50,290,70),this,103);
	title[4] = new CStatic;
	title[4]->Create("左",WS_VISIBLE|SS_CENTER,CRect(290,50,330,70),this,104);
	title[5] = new CStatic;
	title[5]->Create("大",WS_VISIBLE|SS_CENTER,CRect(250,240,290,260),this,105);
	title[6] = new CStatic;
	title[6]->Create("右",WS_VISIBLE|SS_CENTER,CRect(290,240,330,260),this,106);
	listbox = new CListBox;
	listbox->CreateEx(WS_EX_CLIENTEDGE,"ListBox",NULL,LBS_STANDARD|WS_VISIBLE|WS_CHILD,CRect(10,50,240,270),this,1); //建立 CListBox 对象
	CString item[6] = {"宝贝奇想曲","魔力狂飙五十音","新无敌炸弹超人","巴冷公主","陆战英豪","雀战时空"};  //选项名称数组
	DWORD num[6] = {0,1,2,3,4,5};  //选项的数据值
	int index;
	char filename[10];
	for(int i=0;i<=5;i++)
	{
		index = listbox->AddString(item[i]);   //加入各个选项
		listbox->SetItemData(index,num[i]);    //设定各个选项的数据值
		sprintf(filename,"s%d.wav",i);         //取得文件名称
		pSBuf[i] = createbuffer(filename);     //加载背景音乐
	}
	listbox->SelectString(0,"巴冷公主");       //设定预设选项
	stop = new CButton;
	stop->Create("停止",BS_PUSHBUTTON|WS_VISIBLE,CRect(10,280,80,310),this,2); //建立停止钮
	play = new CButton;
	play->Create("播放",BS_PUSHBUTTON|WS_VISIBLE,CRect(90,280,160,310),this,3); //建立播放钮
	loop = new CButton;
	loop->Create("循环",BS_PUSHBUTTON|WS_VISIBLE,CRect(170,280,240,310),this,4); //建立循环钮
	volumn = new CSliderCtrl; //控制音量滑轴
	volumn->Create(WS_VISIBLE|TBS_VERT,CRect(250,70,290,240),this,5);
	volumn->SetRange(-2000,0,true);			//设定音量滑轴的范围
	volumn->SetPos(-1000);					 //设定滑钮位置
	channel = new CSliderCtrl; //控制声道滑轴
	channel->Create(WS_VISIBLE|TBS_VERT,CRect(290,70,330,240),this,6);
	channel->SetRange(-10000,10000,true);	 //设定声道滑轴的范围
	channel->SetPos(0);						 //设定滑钮位置
	return 0;
}

LPDIRECTSOUNDBUFFER canvasFrame::createbuffer(char* filename)
{	
	LPDIRECTSOUNDBUFFER buf;
	hmmio = mmioOpen(filename, NULL, MMIO_ALLOCBUF|MMIO_READ );
	//开启文件
	if(hmmio == NULL)                           //判断是否为空
		MessageBox("文件不存在!");
	ckRiff.fccType = mmioFOURCC('W', 'A', 'V', 'E');
	//设定文件类型
	mmresult = mmioDescend(hmmio,&ckRiff,NULL,MMIO_FINDRIFF);
	//搜寻型态
	if(mmresult != MMSYSERR_NOERROR)
		MessageBox("文件格式错误!");
	ckInfo.ckid = mmioFOURCC('f','m','t',' ');  //设定区块类型
	mmresult = mmioDescend(hmmio,&ckInfo,&ckRiff,MMIO_FINDCHUNK);
	//搜寻区块
	if(mmresult != MMSYSERR_NOERROR)
		MessageBox("文件格式错误!");
	if(mmioRead(hmmio,(HPSTR)&swfmt,sizeof(swfmt)) == -1) //读取文件格式
		MessageBox("读取格式失败!");
	mmresult = mmioAscend(hmmio,&ckInfo,0);     //跳出子区块
	ckInfo.ckid = mmioFOURCC('d','a','t','a');  //设定区块类型
	mmresult = mmioDescend(hmmio,&ckInfo,&ckRiff,MMIO_FINDCHUNK);
	//搜寻区块
	if(mmresult != MMSYSERR_NOERROR)
		MessageBox("文件格式错误!");
	size = ckInfo.cksize;                       //取得实际数据大小
	memset( &dsdesc,0,sizeof(dsdesc));        //清空结构内容
    dsdesc.dwSize  = sizeof(dsdesc);          //配置结构大小
    dsdesc.dwFlags = 	 DSBCAPS_STATIC |DSBCAPS_CTRLPAN |DSBCAPS_CTRLVOLUME| DSBCAPS_GLOBALFOCUS;
    dsdesc.dwBufferBytes = size;            //设定缓冲区大小
    dsdesc.lpwfxFormat   = &swfmt;          //设定缓冲区格式
    result = pDS->CreateSoundBuffer( &dsdesc, &buf, NULL );
	if(result != DS_OK)
		MessageBox("建立次缓冲区失败!");

	result = buf->Lock(0,size,&pAudio,&bytesAudio,NULL,NULL,NULL);
	//锁定缓冲区
	if(result != DS_OK)
		MessageBox("锁定缓冲区失败!");
	mmresult = mmioRead(hmmio,(HPSTR)pAudio,bytesAudio);
	//读取音文件数据
	if(mmresult == -1)
		MessageBox("读取音文件数据失败!");
	result = buf->Unlock(pAudio,bytesAudio,NULL,NULL);
	//解除锁定缓冲区
	if(result != DS_OK)
		MessageBox("解除锁定缓冲区失败!");
	mmioClose(hmmio,0);
	return buf;
}

void canvasFrame::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	switch(pScrollBar->GetDlgCtrlID())   //取得滑轴控件的识别码
	{
	case 5:                              //卷动音量控制滑轴
		if(nPos != 0)
		{
			volume = nPos;               //设定音量值
			pSBuf[now]->SetVolume(nPos); //设定音量
		}
		break;
	case 6:							     //卷动声道控制滑轴
		if(nPos != 0)
		{
			pan = nPos;                  //设定声道值
			pSBuf[now]->SetPan(nPos);    //设定声道
		}
		break;
	}
	CFrameWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}

void canvasFrame::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	if(nChar == VK_ESCAPE)
		PostMessage(WM_CLOSE);
	CFrameWnd::OnChar(nChar, nRepCnt, nFlags);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -