📄 canvasframe.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 + -