📄 mcipldlg.cpp
字号:
// MCIPLdlg.cpp : implementation file
//
#include "stdafx.h"
#include "MCIPLAY.h"
#include "MCIPLdlg.h"
#include "mmsystem.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMCIPLAYDlg dialog
CMCIPLAYDlg::CMCIPLAYDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMCIPLAYDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMCIPLAYDlg)
m_commandStringText = _T("");
m_errorText = _T("");
m_returnString = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMCIPLAYDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMCIPLAYDlg)
DDX_Text(pDX, IDC_COMMANDSTRINGTEXT, m_commandStringText);
DDX_Text(pDX, IDC_ERRORTEXT, m_errorText);
DDX_Text(pDX, IDC_RETURNSTRING, m_returnString);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMCIPLAYDlg, CDialog)
//{{AFX_MSG_MAP(CMCIPLAYDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_MESSAGEBEEP, OnMessagebeep)
ON_BN_CLICKED(IDC_SNDPLAYSOUND, OnSndplaysound)
ON_BN_CLICKED(IDC_MCISENDSTRING, OnMcisendstring)
ON_BN_CLICKED(IDC_MCISENDCOMMAND, OnMcisendcommand)
ON_BN_CLICKED(IDC_WAVEOUTWRITE, OnWaveoutwrite)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMCIPLAYDlg message handlers
BOOL CMCIPLAYDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CenterWindow();
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CMCIPLAYDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMCIPLAYDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CMCIPLAYDlg::OnMessagebeep()
{
if (!MessageBeep(MB_ICONEXCLAMATION))
MessageBox("MessageBeep() Error");
}
void CMCIPLAYDlg::OnSndplaysound()
{
char n[80];
//Update member variables with dialog box contents.
UpdateData(TRUE);
//Call the MCI function.
int success = sndPlaySound(m_commandStringText, SND_ASYNC);
if (success)
wsprintf(n, "Successful - function returned %d.", success);
else
wsprintf(n, "Not successful - function returned %d.", success);
//Update the dialog box controls with current contents of
//the member variables.
m_errorText = n;
UpdateData(FALSE);
}
void CMCIPLAYDlg::OnMcisendstring()
{
#define BUF_LEN 256
char reply[BUF_LEN];
char errorString[BUF_LEN];
//Update member variables with dialog box contents.
UpdateData(TRUE);
//Call the MCI functions.
int mciError = mciSendString(m_commandStringText, reply, BUF_LEN, NULL);
int dummy = mciGetErrorString(mciError, errorString, BUF_LEN);
//Update the dialog box controls with current contents of
//the member variables.
m_returnString = reply;
m_errorText = errorString;
UpdateData(FALSE);
}
void CMCIPLAYDlg::OnMcisendcommand()
{
//Plays a WAVE file using mciSendCommand().
MCI_WAVE_OPEN_PARMS mciOpenParms;
MCI_PLAY_PARMS mciPlayParms;
DWORD mciError, mciFlags;
int wDeviceID;
#define BUF_LEN 256
char mciErrorString[BUF_LEN];
//Initialize data structures.
mciOpenParms.dwCallback = 0L;
mciOpenParms.wDeviceID = 0;
mciOpenParms.lpstrDeviceType = "waveaudio";
mciOpenParms.lpstrElementName = "tada.wav";
mciOpenParms.lpstrAlias = NULL;
mciOpenParms.dwBufferSeconds = 0L;
mciFlags = MCI_OPEN_TYPE | MCI_OPEN_ELEMENT;
//Send the "open" command.
mciError = mciSendCommand(0, MCI_OPEN, mciFlags, (DWORD)&mciOpenParms);
//If open was successful, retrieve the device id
//and send the "play" command.
if (!mciError)
{
wDeviceID = mciOpenParms.wDeviceID;
mciError = mciSendCommand(wDeviceID, MCI_PLAY, MCI_WAIT, (DWORD)&mciPlayParms);
//If play was successful, send the "close" command.
if (!mciError)
mciError = mciSendCommand(wDeviceID, MCI_CLOSE, 0, 0L);
}
//Get the error message and update dialog box.
int dummy = mciGetErrorString(mciError, mciErrorString, BUF_LEN);
m_returnString = "";
m_errorText = mciErrorString;
UpdateData(FALSE);
}
void CMCIPLAYDlg::OnWaveoutwrite()
{
//Open and read the WAVE file and get the handle
//of the memory where it is stored.
HANDLE handle = m_OpenWaveFile("tada.wav");
//If the WAVE file was opened successfully, play it.
if (handle)
if (!m_WaveOut())
AfxMessageBox("WAVE file could not be played", MB_OK | MB_ICONSTOP, NULL);
//Free memory.
if (::GlobalFree(handle))
AfxMessageBox("Error freeing allocated memory", MB_OK | MB_ICONSTOP, NULL);
}
HANDLE CMCIPLAYDlg::m_OpenWaveFile(CString FileNameAndPath)
{
//Opens and reads the specified WAVE file. Returns the handle to
//the allocated memory where the WAVE data is stored,
//or NULL on failure.
MMCKINFO MMCkInfoParent;
MMCKINFO MMCkInfoChild;
//Open the WAVE file.
HMMIO hmmio = mmioOpen(FileNameAndPath.GetBuffer(80), NULL, MMIO_READ);
//Was open successful?
if (!hmmio)
{
AfxMessageBox("File could not be opened", MB_OK | MB_ICONSTOP, NULL);
return (NULL);
}
//Find WAVE parent chunk.
MMCkInfoParent.fccType = mmioFOURCC('W','A','V','E');
int errorCode = mmioDescend(hmmio, &MMCkInfoParent, NULL, MMIO_FINDRIFF);
if (errorCode)
{
AfxMessageBox("Error descending in file", MB_OK | MB_ICONSTOP, NULL);
mmioClose(hmmio, 0);
return (NULL);
}
//Find format chunk.
MMCkInfoChild.ckid = mmioFOURCC('f','m','t',' ');
errorCode = mmioDescend(hmmio, &MMCkInfoChild, &MMCkInfoParent, MMIO_FINDCHUNK);
if (errorCode)
{
AfxMessageBox("Error descending in file", MB_OK | MB_ICONSTOP, NULL);
mmioClose(hmmio, 0);
return (NULL);
}
//Read PCM wave format record.
DWORD bytesRead = mmioRead(hmmio, (LPSTR)&PCMWaveFmtRecord, MMCkInfoChild.cksize);
if (bytesRead <= 0)
{
AfxMessageBox("Error reading PCM wave format record", MB_OK | MB_ICONSTOP, NULL);
mmioClose(hmmio, 0);
return (NULL);
}
//See if data is compatible with WAVE hardware.
errorCode = waveOutOpen(NULL, WAVE_MAPPER,
(tWAVEFORMATEX*)&PCMWaveFmtRecord,
0L, 0L, WAVE_FORMAT_QUERY);
if (errorCode)
{
AfxMessageBox("Incompatible WAVE file format", MB_OK | MB_ICONSTOP, NULL);
mmioClose(hmmio, 0);
return (NULL);
}
//Ascend back one level in RIFF file in preparation
//for reading data.
errorCode = mmioAscend(hmmio, &MMCkInfoChild, 0);
if (errorCode)
{
AfxMessageBox("Error ascending in file", MB_OK | MB_ICONSTOP, NULL);
mmioClose(hmmio, 0);
return (NULL);
}
//Read data chunk.
MMCkInfoChild.ckid = mmioFOURCC('d','a','t','a');
errorCode = mmioDescend(hmmio, &MMCkInfoChild,
&MMCkInfoParent, MMIO_FINDCHUNK);
if (errorCode)
{
AfxMessageBox("Error reading data chunk", MB_OK | MB_ICONSTOP, NULL);
mmioClose(hmmio, 0);
return (NULL);
}
//Allocate memory to hold the WAVE data.
long lDataSize = MMCkInfoChild.cksize;
HANDLE waveDataBlock = ::GlobalAlloc(GMEM_MOVEABLE, lDataSize);
if (waveDataBlock == NULL)
{
AfxMessageBox("Could not allocate memory", MB_OK | MB_ICONSTOP, NULL);
mmioClose(hmmio, 0);
return (NULL);
}
//If we reach here we can read the data. First, lock the
//memory buffer and get a pointer to it, then read data into it.
char* pWave = (char*)::GlobalLock(waveDataBlock);
if (mmioRead(hmmio, (LPSTR)pWave, lDataSize) != lDataSize)
{
//Data read failed.
AfxMessageBox("Error reading WAVE data", MB_OK | MB_ICONSTOP, NULL);
mmioClose(hmmio, 0);
::GlobalFree(waveDataBlock);
return (NULL);
}
//Fill in the WAVE header.
WaveHeader.lpData = pWave;
WaveHeader.dwBufferLength = lDataSize;
WaveHeader.dwFlags = 0L;
WaveHeader.dwLoops = 0L;
//Close the WAVE file.
mmioClose(hmmio, 0);
//Return the memory block handle.
return waveDataBlock;
}
BOOL CMCIPLAYDlg::m_WaveOut()
{
//Plays the WAVE file identified by the WaveHeader
//and PCMWaveFormatRecord structures.
//Handle for the WAVE device.
HWAVEOUT hWaveOut;
//Open the WAVE device.
MMRESULT ReturnCode = waveOutOpen(&hWaveOut, WAVE_MAPPER,
(tWAVEFORMATEX*)&PCMWaveFmtRecord,
0L, 0L, 0L);
if (ReturnCode)
{
char m[8];
//wsprintf(m, "%d", ReturnCode);
AfxMessageBox("Could not open WAVE device", MB_OK | MB_ICONSTOP, NULL);
AfxMessageBox(m, MB_OK | MB_ICONSTOP, NULL);
return (FALSE);
}
//Prepare the header.
ReturnCode = waveOutPrepareHeader(hWaveOut, &WaveHeader, sizeof(WaveHeader));
if (ReturnCode)
{
AfxMessageBox("Could not prepare header", MB_OK | MB_ICONSTOP, NULL);
waveOutClose(hWaveOut);
return (FALSE);
}
//Write data to WAVE device.
ReturnCode = waveOutWrite(hWaveOut, &WaveHeader, sizeof(WaveHeader));
if (ReturnCode)
{
AfxMessageBox("Error writing to WAVE device", MB_OK | MB_ICONSTOP, NULL);
waveOutClose(hWaveOut);
return (FALSE);
}
//Loop until playback is finished.
do {}
while (!(WaveHeader.dwFlags & WHDR_DONE));
//Unprepare the wave output header.
ReturnCode = waveOutUnprepareHeader(hWaveOut, &WaveHeader, sizeof(WaveHeader));
if (ReturnCode)
{
AfxMessageBox("Unable to unprepare wave header", MB_OK | MB_ICONSTOP, NULL);
waveOutClose(hWaveOut);
return (FALSE);
}
WaveHeader.dwFlags = 0L;
//Close the WAVE device.
ReturnCode = waveOutClose(hWaveOut);
if (ReturnCode)
{
AfxMessageBox("Unable to close wave device", MB_OK | MB_ICONSTOP, NULL);
waveOutClose(hWaveOut);
return (FALSE);
}
return (TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -