2025-11-27 16:46:48 +09:00

1077 lines
26 KiB
C++

// ==========================================================================
// Class Implementation :
// COXSoundEffectManager & COXSoundEffectOrganizer
// ==========================================================================
// Version: 9.3
// This software along with its related components, documentation and files ("The Libraries")
// is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
// to obtain this file, or directly from our office. For a copy of the license governing
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
// //////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "OXSoundEffectManager.h"
#ifndef OXSE_NO_SAVESTATE
#include "OXRegistryValFile.h"
#endif // OXSE_NO_SAVESTATE
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNAMIC(COXSoundEffectManager, COXHookWnd);
// Constructor
COXSoundEffectManager::COXSoundEffectManager(COXSoundEffectOrganizer* pOrganizer/*=NULL*/)
{
m_pOrganizer=pOrganizer;
Reset();
}
// Destructor
COXSoundEffectManager::~COXSoundEffectManager()
{
if(IsHooked())
UnregisterAllEffects();
// delete all the structures we allocated
LPSOUNDEFFECT pSoundEffect;
UINT nMsgID;
POSITION pos=m_allSoundPlayEvents.GetStartPosition();
while(pos!=NULL)
{
m_allSoundPlayEvents.GetNextAssoc(pos,nMsgID,pSoundEffect);
ASSERT(nMsgID!=SNDEVENT_NONE);
ASSERT(pSoundEffect!=NULL);
delete pSoundEffect;
}
m_allSoundPlayEvents.RemoveAll();
m_allSoundStopEvents.RemoveAll();
}
// Attach ListCtrl handler.
BOOL COXSoundEffectManager::Attach(CWnd* pWnd)
{
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
Reset();
HookWindow(pWnd);
// call this function in oder to get HWM_MOUSEENTER and HWM_MOUSELEAVE messages
InstallSpy();
return TRUE;
}
// Detach the handler. Called by default when hooked window is about
// to be destroyed.
void COXSoundEffectManager::Detach()
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
Reset();
UnhookWindow();
}
////////////////////////////////////////////////////////////////////////////
// Message handler handles sound events and sound-related messages
//
LRESULT COXSoundEffectManager::WindowProc(UINT msg, WPARAM wp, LPARAM lp)
{
#if defined (_WINDLL)
#if defined (_AFXDLL)
AFX_MANAGE_STATE(AfxGetAppModuleState());
#else
AFX_MANAGE_STATE(AfxGetStaticModuleState());
#endif
#endif
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
BOOL bHandled=FALSE;
// playing of the sound has been finished
if(msg==WM_OX_SOUNDPLAYBACKCOMPLETE)
{
ASSERT(!bHandled);
// start playing next event if there is any in the queue
if(m_nNextEvent!=SNDEVENT_NONE)
{
m_nCurrentEvent=m_nNextEvent;
m_nNextEvent=SNDEVENT_NONE;
StartPlaying();
}
else
Reset();
bHandled=TRUE;
}
// playing sound in the loop
if(msg==WM_OX_SOUNDPLAYLOOPING && m_nCurrentEvent!=SNDEVENT_NONE)
{
TRACE(_T("WM_OX_SOUNDPLAYLOOPING\n"));
ASSERT(!bHandled);
LPSOUNDEFFECT pSoundEffect=GetSoundEffect(m_nCurrentEvent);
ASSERT(pSoundEffect);
ASSERT(pSoundEffect->bLoop);
if(pSoundEffect->nLoopCount!=-1)
{
m_nLoopCount++;
ASSERT(pSoundEffect->nLoopCount==0 ||
pSoundEffect->nLoopCount>=m_nLoopCount);
// stop playing sound if the specified number of repeated playings
// has elapsed
if(pSoundEffect->nLoopCount<=m_nLoopCount)
StopPlaying();
}
bHandled=TRUE;
}
UINT nOrder;
// check if the current message is one of the stop event
if(m_allSoundStopEvents.Lookup(msg,nOrder))
{
ASSERT(!bHandled);
StopPlaying();
bHandled=TRUE;
}
LPSOUNDEFFECT pSoundEffect;
// check if the current message is one of the playing event
if(m_allSoundPlayEvents.Lookup(msg,pSoundEffect))
{
ASSERT(!bHandled);
ASSERT(pSoundEffect);
BOOL bAmIPlaying=IsPlaying();
BOOL bOtherPlaying=FALSE;
if(!bAmIPlaying && m_pOrganizer!=NULL)
bOtherPlaying=m_pOrganizer->IsPlaying();
BOOL bPlaying=bAmIPlaying|bOtherPlaying;
if(!bPlaying || pSoundEffect->bForceToStart)
{
if(bAmIPlaying)
{
StopPlaying();
m_nNextEvent=msg;
}
else
{
if(bOtherPlaying && m_pOrganizer!=NULL)
m_pOrganizer->StopPlaying();
m_nCurrentEvent=msg;
StartPlaying();
}
}
bHandled=TRUE;
}
// I don't handle it: pass along
return COXHookWnd::WindowProc(msg, wp, lp);
}
void COXSoundEffectManager::UnregisterAllPlayEvents()
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
StopPlaying();
// delete all start playing events
LPSOUNDEFFECT pSoundEffect;
UINT nMsgID;
POSITION pos=m_allSoundPlayEvents.GetStartPosition();
while(pos!=NULL)
{
m_allSoundPlayEvents.GetNextAssoc(pos,nMsgID,pSoundEffect);
ASSERT(nMsgID!=SNDEVENT_NONE);
ASSERT(pSoundEffect!=NULL);
delete pSoundEffect;
}
m_allSoundPlayEvents.RemoveAll();
}
void COXSoundEffectManager::UnregisterAllStopEvents()
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
// delete all stop playing events
m_allSoundStopEvents.RemoveAll();
}
void COXSoundEffectManager::UnregisterAllEffects()
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
UnregisterAllPlayEvents();
UnregisterAllStopEvents();
}
BOOL COXSoundEffectManager::RegisterPlayEvent(UINT nMsgIDtoStartPlaying,
LPCTSTR pszFileName,
BOOL bLoop/*=FALSE*/,
int nLoopCount/*=-1*/,
BOOL bForceToStart/*=TRUE*/)
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
ASSERT(pszFileName!=NULL);
ASSERT(nMsgIDtoStartPlaying!=SNDEVENT_NONE);
// create sound object
COXSound* pSound=CreateSound();
if(pSound==NULL)
{
TRACE(_T("COXSoundEffectManager::RegisterPlayEvent: failed to create COXSound object\n"));
return FALSE;
}
// try to open the specified file
if(!pSound->Open(pszFileName))
{
delete pSound;
TRACE(_T("COXSoundEffectManager::RegisterPlayEvent: failed to open specified sound file\n"));
return FALSE;
}
// register it
return RegisterSoundEffect(nMsgIDtoStartPlaying,pSound,
bLoop,nLoopCount,bForceToStart);
}
BOOL COXSoundEffectManager::RegisterPlayEvent(UINT nMsgIDtoStartPlaying,
UINT nSoundResource,
HINSTANCE hResInstance/*=AfxGetResourceHandle()*/,
BOOL bLoop/*=FALSE*/,
int nLoopCount/*=-1*/,
BOOL bForceToStart/*=TRUE*/)
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
ASSERT(nMsgIDtoStartPlaying!=SNDEVENT_NONE);
COXSound* pSound=CreateSound();
if(pSound==NULL)
{
TRACE(_T("COXSoundEffectManager::RegisterPlayEvent: failed to create COXSound object\n"));
return FALSE;
}
if(!pSound->Open(nSoundResource,hResInstance))
{
delete pSound;
TRACE(_T("COXSoundEffectManager::RegisterPlayEvent: failed to open specified sound file\n"));
return FALSE;
}
return RegisterSoundEffect(nMsgIDtoStartPlaying,pSound,
bLoop,nLoopCount,bForceToStart);
}
BOOL COXSoundEffectManager::RegisterPlayEvent(UINT nMsgIDtoStartPlaying,
CFile* pOpenedFile,
BOOL bLoop/*=FALSE*/,
int nLoopCount/*=-1*/,
BOOL bForceToStart/*=TRUE*/)
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
ASSERT(nMsgIDtoStartPlaying!=SNDEVENT_NONE);
ASSERT(pOpenedFile!=NULL);
COXSound* pSound=CreateSound();
if(pSound==NULL)
{
TRACE(_T("COXSoundEffectManager::RegisterPlayEvent: failed to create COXSound object\n"));
return FALSE;
}
if(!pSound->Open(pOpenedFile))
{
delete pSound;
TRACE(_T("COXSoundEffectManager::RegisterPlayEvent: failed to open specified sound file\n"));
return FALSE;
}
return RegisterSoundEffect(nMsgIDtoStartPlaying,pSound,
bLoop,nLoopCount,bForceToStart);
}
BOOL COXSoundEffectManager::UnregisterPlayEvent(UINT nMsgIDtoStartPlaying)
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
ASSERT(nMsgIDtoStartPlaying!=SNDEVENT_NONE);
if(nMsgIDtoStartPlaying==m_nCurrentEvent)
{
ASSERT(IsPlaying());
VERIFY(StopPlaying());
}
LPSOUNDEFFECT pSoundEffect;
if(m_allSoundPlayEvents.Lookup(nMsgIDtoStartPlaying,pSoundEffect))
{
ASSERT(pSoundEffect);
delete pSoundEffect;
VERIFY(m_allSoundPlayEvents.RemoveKey(nMsgIDtoStartPlaying));
return TRUE;
}
else
{
TRACE(_T("COXSoundEffectManager::UnregisterPlayEvent: event %d wasn't registered\n"),nMsgIDtoStartPlaying);
return FALSE;
}
}
BOOL COXSoundEffectManager::IsRegisteredPlayEvent(UINT nMsgIDtoStartPlaying)
{
LPSOUNDEFFECT pSoundEffect;
return (m_allSoundPlayEvents.Lookup(nMsgIDtoStartPlaying,pSoundEffect));
}
UINT COXSoundEffectManager::GetNextPlayEvent(POSITION& rNextPosition)
{
ASSERT(rNextPosition!=NULL);
LPSOUNDEFFECT pSoundEffect;
UINT nMsgID;
m_allSoundPlayEvents.GetNextAssoc(rNextPosition,nMsgID,pSoundEffect);
ASSERT(nMsgID!=SNDEVENT_NONE);
ASSERT(pSoundEffect!=NULL);
return nMsgID;
}
BOOL COXSoundEffectManager::RegisterStopEvent(UINT nMsgIDtoStopPlaying)
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
ASSERT(nMsgIDtoStopPlaying!=SNDEVENT_NONE);
LPSOUNDEFFECT pSoundEffect;
if(m_allSoundPlayEvents.Lookup(nMsgIDtoStopPlaying,pSoundEffect))
{
TRACE(_T("COXSoundEffectManager::RegisterStopEvent: event already registered as Start Event\n"));
return FALSE;
}
UnregisterStopEvent(nMsgIDtoStopPlaying);
m_allSoundStopEvents.SetAt(nMsgIDtoStopPlaying,PtrToUint(m_allSoundPlayEvents.GetCount()));
return TRUE;
}
BOOL COXSoundEffectManager::UnregisterStopEvent(UINT nMsgIDtoStopPlaying)
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
ASSERT(nMsgIDtoStopPlaying!=SNDEVENT_NONE);
UINT nOrder;
if(m_allSoundStopEvents.Lookup(nMsgIDtoStopPlaying,nOrder))
{
VERIFY(m_allSoundStopEvents.RemoveKey(nMsgIDtoStopPlaying));
return TRUE;
}
else
{
TRACE(_T("COXSoundEffectManager::UnregisterStopEvent: event %d wasn't registered\n"),nMsgIDtoStopPlaying);
return FALSE;
}
}
BOOL COXSoundEffectManager::IsRegisteredStopEvent(UINT nMsgIDtoStopPlaying)
{
UINT nOrder;
return (m_allSoundStopEvents.Lookup(nMsgIDtoStopPlaying,nOrder));
}
UINT COXSoundEffectManager::GetNextStopEvent(POSITION& rNextPosition)
{
ASSERT(rNextPosition!=NULL);
UINT nOrder;
UINT nMsgID;
m_allSoundStopEvents.GetNextAssoc(rNextPosition,nMsgID,nOrder);
ASSERT(nMsgID!=SNDEVENT_NONE);
return nMsgID;
}
BOOL COXSoundEffectManager::IsPlaying()
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
if(m_nCurrentEvent==SNDEVENT_NONE)
return FALSE;
else
{
LPSOUNDEFFECT pSoundEffect=GetSoundEffect(m_nCurrentEvent);
ASSERT(pSoundEffect);
return pSoundEffect->pSound->IsPlaying();
}
}
BOOL COXSoundEffectManager::StopPlaying()
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
if(!IsPlaying())
{
TRACE(_T("COXSoundEffectManager::StopPlaying: there is nothing to stop\n"));
return TRUE;
}
else
{
LPSOUNDEFFECT pSoundEffect=GetSoundEffect(m_nCurrentEvent);
ASSERT(pSoundEffect);
ASSERT(pSoundEffect->pSound->IsPlaying());
pSoundEffect->pSound->Stop();
Reset();
return TRUE;
}
}
COXSound* COXSoundEffectManager::CreateSound()
{
COXSound* pSound=NULL;
try
{
pSound=new COXSound;
}
catch (CMemoryException* pException)
{
UNREFERENCED_PARAMETER(pException);
TRACE(_T("COXSoundEffectManager::CreateSound: failed to allocate memory for COXSound object\n"));
}
return pSound;
}
BOOL COXSoundEffectManager::RegisterSoundEffect(UINT nMsgIDtoStartPlaying,
COXSound* pSound,
BOOL bLoop/*=FALSE*/,
int nLoopCount/*=-1*/,
BOOL bForceToStart/*=TRUE*/)
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
ASSERT(nMsgIDtoStartPlaying!=SNDEVENT_NONE);
ASSERT(pSound);
UINT nOrder;
if(m_allSoundStopEvents.Lookup(nMsgIDtoStartPlaying,nOrder))
{
delete pSound;
TRACE(_T("COXSoundEffectManager::RegisterSoundObject: event already registered as Stop Event\n"));
return FALSE;
}
UnregisterPlayEvent(nMsgIDtoStartPlaying);
LPSOUNDEFFECT pSoundEffect=new SOUNDEFFECT;
pSoundEffect->pSound=pSound;
pSoundEffect->bLoop=bLoop;
pSoundEffect->nLoopCount=nLoopCount;
pSoundEffect->bForceToStart=bForceToStart;
m_allSoundPlayEvents.SetAt(nMsgIDtoStartPlaying,pSoundEffect);
return TRUE;
}
BOOL COXSoundEffectManager::StartPlaying()
{
ASSERT(m_hWndHooked!=NULL);
ASSERT(::IsWindow(m_hWndHooked));
if(m_nCurrentEvent==SNDEVENT_NONE)
{
TRACE(_T("COXSoundEffectManager::StartPlaying: there is no an active event to start playing\n"));
return FALSE;
}
LPSOUNDEFFECT pSoundEffect=GetSoundEffect(m_nCurrentEvent);
ASSERT(pSoundEffect);
pSoundEffect->pSound->SetCallbackWnd(GetHookedWnd());
if(!pSoundEffect->pSound->Play(pSoundEffect->bLoop))
{
TRACE(_T("COXSoundEffectManager::StartPlaying: failed to start playing current sound effect\n"));
m_nCurrentEvent=SNDEVENT_NONE;
return FALSE;
}
else
return TRUE;
}
LPSOUNDEFFECT COXSoundEffectManager::GetSoundEffect(UINT nMsgIDtoStartPlaying)
{
LPSOUNDEFFECT pSoundEffect;
if(m_allSoundPlayEvents.Lookup(nMsgIDtoStartPlaying,pSoundEffect))
{
ASSERT(pSoundEffect);
ASSERT(pSoundEffect->pSound);
return pSoundEffect;
}
else
return NULL;
}
void COXSoundEffectManager::Reset()
{
m_nCurrentEvent=SNDEVENT_NONE;
m_nLoopCount=0;
m_nNextEvent=SNDEVENT_NONE;
}
//////////////////////////////////////
#ifndef OXSE_NO_SAVESTATE
//////////////////////////////////////
BOOL COXSoundEffectManager::SaveState(LPCTSTR lpszProfileName)
{
#ifndef _MAC
CWinApp* pApp=AfxGetApp();
// make sure you called CWinApp::SetRegistryKey() functions before
if(pApp->m_pszRegistryKey==NULL || pApp->m_pszProfileName==NULL)
{
TRACE(_T("COXSoundEffectManager::SaveState: SetRegistryKey() haven't been called\n"));
return FALSE;
}
// we use default registry key assigned to your application by MFC
HKEY hSecKey=pApp->GetSectionKey(_T(""));
if (hSecKey==NULL)
{
TRACE(_T("COXSoundEffectManager::SaveState: unable to get section key\n"));
return FALSE;
}
BOOL bResult=TRUE;
try
{
COXRegistryValFile reg(hSecKey, lpszProfileName, _T("SoundEffects"));
CArchive ar(&reg, CArchive::store);
Serialize(ar);
ar.Close();
}
catch(CException* e)
{
UNREFERENCED_PARAMETER(e);
bResult=FALSE;
}
::RegCloseKey(hSecKey);
return bResult;
#else
return FALSE;
#endif
}
BOOL COXSoundEffectManager::LoadState(LPCTSTR lpszProfileName)
{
#ifndef _MAC
CWinApp* pApp=AfxGetApp();
// make sure you called CWinApp::SetRegistryKey() functions before
if(pApp->m_pszRegistryKey==NULL || pApp->m_pszProfileName==NULL)
{
TRACE(_T("COXSoundEffectManager::LoadState: SetRegistryKey() haven't been called\n"));
return FALSE;
}
// we use default registry key assigned to your application by MFC
HKEY hSecKey=pApp->GetSectionKey(_T(""));
if (hSecKey==NULL)
{
TRACE(_T("COXSoundEffectManager::SaveState: unable to get section key\n"));
return FALSE;
}
BOOL bResult=TRUE;
try
{
COXRegistryValFile reg(hSecKey, lpszProfileName, _T("SoundEffects"));
if(reg.GetLength()>0)
{
CArchive ar(&reg, CArchive::load);
Serialize(ar);
ar.Close();
}
}
catch(CException* e)
{
UNREFERENCED_PARAMETER(e);
bResult=FALSE;
}
::RegCloseKey(hSecKey);
return bResult;
#else
return FALSE;
#endif
}
//////////////////////////////////////
#endif // OXSE_NO_SAVESTATE
//////////////////////////////////////
void COXSoundEffectManager::Serialize(CArchive& ar)
{
ASSERT(IsHooked());
// Only CObject-derived objects and six data-type
// primitives are serializable. However, you
// can cast any data type to a serializable data type,
// and then you can serialize your data. The serializable
// data types are
// BYTE: 8 bits unsigned
// WORD: 16 bits unsigned
// LONG: 32 bits unsigned
// DWORD: 32 bits unsigned
// float 32 bits
// double 64 bits, IEEE standard
if (ar.IsStoring())
{
DWORD nPlayEventCount= PtrToLong(m_allSoundPlayEvents.GetCount());
ar << nPlayEventCount;
LPSOUNDEFFECT pSoundEffect;
UINT nMsgID;
POSITION pos=m_allSoundPlayEvents.GetStartPosition();
while(pos!=NULL)
{
m_allSoundPlayEvents.GetNextAssoc(pos,nMsgID,pSoundEffect);
ASSERT(nMsgID!=SNDEVENT_NONE);
ASSERT(pSoundEffect);
ASSERT(pSoundEffect->pSound);
ar << (DWORD)nMsgID;
pSoundEffect->Serialize(ar);
ASSERT(pSoundEffect->pSound);
pSoundEffect->pSound->GetSoundSourceInfo()->Serialize(ar);
}
DWORD nStopEventCount= PtrToInt(m_allSoundStopEvents.GetCount());
ar << nStopEventCount;
UINT nOrder;
pos=m_allSoundStopEvents.GetStartPosition();
while(pos!=NULL)
{
m_allSoundStopEvents.GetNextAssoc(pos,nMsgID,nOrder);
ASSERT(nMsgID!=SNDEVENT_NONE);
ar << (DWORD)nMsgID;
}
}
else
{
UnregisterAllEffects();
DWORD nPlayEventCount;
ar >> nPlayEventCount;
DWORD nMsgID;
DWORD nIndex=0;
for(nIndex=0; nIndex<nPlayEventCount; nIndex++)
{
ar >> nMsgID;
ASSERT(nMsgID!=SNDEVENT_NONE);
SOUNDEFFECT soundEffect;
soundEffect.Serialize(ar);
SOUNDSOURCEINFO ssInfo;
ssInfo.Serialize(ar);
if(ssInfo.source!=SNDSRC_CFILE && ssInfo.source!=SNDSRC_UNKNOWN)
{
switch(ssInfo.source)
{
case SNDSRC_FILE:
RegisterPlayEvent((UINT)nMsgID,ssInfo.sFileName,
soundEffect.bLoop,soundEffect.nLoopCount,
soundEffect.bForceToStart);
break;
case SNDSRC_INTRESOURCE:
RegisterPlayEvent((UINT)nMsgID,ssInfo.nResourceID,
ssInfo.hInstance,soundEffect.bLoop,
soundEffect.nLoopCount,soundEffect.bForceToStart);
break;
default:
ASSERT(FALSE);
}
}
}
DWORD nStopEventCount;
ar >> nStopEventCount;
for(nIndex=0; nIndex<nStopEventCount; nIndex++)
{
ar >> nMsgID;
ASSERT(nMsgID!=SNDEVENT_NONE);
RegisterStopEvent((UINT)nMsgID);
}
}
}
///////////////////////////////////////////////////////////////
// Constructor
COXSoundEffectOrganizer::COXSoundEffectOrganizer()
{
}
// Destructor
COXSoundEffectOrganizer::~COXSoundEffectOrganizer()
{
// delete all COXSoundEffectManager objects we allocated
COXSoundEffectManager* pManager;
CWnd* pWnd;
POSITION pos=m_allSoundEffectManagers.GetStartPosition();
while(pos!=NULL)
{
m_allSoundEffectManagers.GetNextAssoc(pos,pWnd,pManager);
ASSERT(pWnd!=NULL);
ASSERT(pManager!=NULL);
delete pManager;
}
m_allSoundEffectManagers.RemoveAll();
}
void COXSoundEffectOrganizer::UnregisterAllPlayEvents(CWnd* pWnd/*=NULL*/)
{
COXSoundEffectManager* pManager;
if(pWnd==NULL)
{
POSITION pos=m_allSoundEffectManagers.GetStartPosition();
while(pos!=NULL)
{
m_allSoundEffectManagers.GetNextAssoc(pos,pWnd,pManager);
ASSERT(pWnd!=NULL);
ASSERT(pManager!=NULL);
pManager->UnregisterAllPlayEvents();
}
}
else
{
pManager=GetManager(pWnd);
ASSERT(pManager!=NULL);
pManager->UnregisterAllPlayEvents();
}
}
void COXSoundEffectOrganizer::UnregisterAllStopEvents(CWnd* pWnd/*=NULL*/)
{
COXSoundEffectManager* pManager;
if(pWnd==NULL)
{
POSITION pos=m_allSoundEffectManagers.GetStartPosition();
while(pos!=NULL)
{
m_allSoundEffectManagers.GetNextAssoc(pos,pWnd,pManager);
ASSERT(pWnd!=NULL);
ASSERT(pManager!=NULL);
pManager->UnregisterAllStopEvents();
}
}
else
{
pManager=GetManager(pWnd);
ASSERT(pManager!=NULL);
pManager->UnregisterAllStopEvents();
}
}
void COXSoundEffectOrganizer::UnregisterAllEffects(CWnd* pWnd/*=NULL*/)
{
UnregisterAllPlayEvents(pWnd);
UnregisterAllStopEvents(pWnd);
}
BOOL COXSoundEffectOrganizer::RegisterPlayEvent(CWnd* pWnd, UINT nMsgIDtoStartPlaying,
LPCTSTR pszFileName,
BOOL bLoop/*=FALSE*/,
int nLoopCount/*=-1*/,
BOOL bForceToStart/*=TRUE*/)
{
ASSERT(pWnd);
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
ASSERT(pszFileName!=NULL);
COXSoundEffectManager* pManager=GetManager(pWnd);
if(pManager==NULL)
pManager=CreateManager(pWnd);
ASSERT(pManager!=NULL);
return pManager->RegisterPlayEvent(nMsgIDtoStartPlaying,pszFileName,
bLoop,nLoopCount,bForceToStart);
}
BOOL COXSoundEffectOrganizer::RegisterPlayEvent(CWnd* pWnd, UINT nMsgIDtoStartPlaying,
UINT nSoundResource,
HINSTANCE hResInstance/*=AfxGetResourceHandle()*/,
BOOL bLoop/*=FALSE*/,
int nLoopCount/*=-1*/,
BOOL bForceToStart/*=TRUE*/)
{
ASSERT(pWnd);
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
COXSoundEffectManager* pManager=GetManager(pWnd);
if(pManager==NULL)
pManager=CreateManager(pWnd);
ASSERT(pManager!=NULL);
return pManager->RegisterPlayEvent(nMsgIDtoStartPlaying,nSoundResource,
hResInstance,bLoop,nLoopCount,bForceToStart);
}
BOOL COXSoundEffectOrganizer::RegisterPlayEvent(CWnd* pWnd, UINT nMsgIDtoStartPlaying,
CFile* pOpenedFile,
BOOL bLoop/*=FALSE*/,
int nLoopCount/*=-1*/,
BOOL bForceToStart/*=TRUE*/)
{
ASSERT(pWnd);
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
COXSoundEffectManager* pManager=GetManager(pWnd);
if(pManager==NULL)
pManager=CreateManager(pWnd);
ASSERT(pManager!=NULL);
return pManager->RegisterPlayEvent(nMsgIDtoStartPlaying,pOpenedFile,
bLoop,nLoopCount,bForceToStart);
}
BOOL COXSoundEffectOrganizer::UnregisterPlayEvent(CWnd* pWnd,
UINT nMsgIDtoStartPlaying)
{
ASSERT(pWnd);
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
COXSoundEffectManager* pManager=GetManager(pWnd);
ASSERT(pManager!=NULL);
return pManager->UnregisterPlayEvent(nMsgIDtoStartPlaying);
}
COXSoundEffectManager* COXSoundEffectOrganizer::GetManager(CWnd* pWnd)
{
ASSERT(pWnd);
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
COXSoundEffectManager* pManager=NULL;
if(!m_allSoundEffectManagers.Lookup(pWnd,pManager))
return NULL;
else
return pManager;
}
CWnd* COXSoundEffectOrganizer::GetNextRegisteredWindow(POSITION& rNextPosition)
{
ASSERT(rNextPosition!=NULL);
COXSoundEffectManager* pManager;
CWnd* pWnd;
m_allSoundEffectManagers.GetNextAssoc(rNextPosition,pWnd,pManager);
ASSERT(pWnd!=NULL);
ASSERT(pManager!=NULL);
return pWnd;
}
BOOL COXSoundEffectOrganizer::RegisterStopEvent(CWnd* pWnd, UINT nMsgIDtoStopPlaying)
{
ASSERT(pWnd);
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
COXSoundEffectManager* pManager=GetManager(pWnd);
if(pManager==NULL)
pManager=CreateManager(pWnd);
ASSERT(pManager!=NULL);
return pManager->RegisterStopEvent(nMsgIDtoStopPlaying);
}
BOOL COXSoundEffectOrganizer::UnregisterStopEvent(CWnd* pWnd,
UINT nMsgIDtoStopPlaying)
{
ASSERT(pWnd);
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
COXSoundEffectManager* pManager=GetManager(pWnd);
ASSERT(pManager!=NULL);
return pManager->UnregisterStopEvent(nMsgIDtoStopPlaying);
}
BOOL COXSoundEffectOrganizer::IsPlaying(CWnd* pWnd/*=NULL*/)
{
COXSoundEffectManager* pManager;
if(pWnd!=NULL)
{
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
pManager=GetManager(pWnd);
ASSERT(pManager);
return pManager->IsPlaying();
}
else
{
BOOL bResult=FALSE;
POSITION pos=m_allSoundEffectManagers.GetStartPosition();
while(pos!=NULL)
{
m_allSoundEffectManagers.GetNextAssoc(pos,pWnd,pManager);
ASSERT(pWnd!=NULL);
ASSERT(pManager!=NULL);
if(pManager->IsPlaying())
{
bResult=TRUE;
break;
}
}
return bResult;
}
}
BOOL COXSoundEffectOrganizer::StopPlaying(CWnd* pWnd/*=NULL*/)
{
if(!IsPlaying(pWnd))
{
TRACE(_T("COXSoundEffectOrganizer::StopPlaying: there is nothing to stop\n"));
return TRUE;
}
else
{
COXSoundEffectManager* pManager;
if(pWnd!=NULL)
{
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
pManager=GetManager(pWnd);
ASSERT(pManager);
ASSERT(pManager->IsPlaying());
return pManager->StopPlaying();
}
else
{
BOOL bResult=TRUE;
POSITION pos=m_allSoundEffectManagers.GetStartPosition();
while(pos!=NULL)
{
m_allSoundEffectManagers.GetNextAssoc(pos,pWnd,pManager);
ASSERT(pWnd!=NULL);
ASSERT(pManager!=NULL);
bResult&=pManager->StopPlaying();
}
return bResult;
}
}
}
#ifndef OXSE_NO_SAVESTATE
// Save to and load from registry all registered start and stop playing events
// for specified window. These functions require using COXRegistryValFile class.
// If you are not going to use them then you can include in your stdafx.h
// file next code:
//
// #define OXSE_NO_SAVESTATE
//
// In this case you don't need to include into your project references
// to source code for COXRegistryValFile class.
//
BOOL COXSoundEffectOrganizer::SaveState(CWnd* pWnd, LPCTSTR lpszProfileName)
{
ASSERT(pWnd);
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
COXSoundEffectManager* pManager=GetManager(pWnd);
ASSERT(pManager!=NULL);
return pManager->SaveState(lpszProfileName);
}
BOOL COXSoundEffectOrganizer::LoadState(CWnd* pWnd, LPCTSTR lpszProfileName)
{
ASSERT(pWnd);
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
COXSoundEffectManager* pManager=GetManager(pWnd);
if(pManager==NULL)
pManager=CreateManager(pWnd);
ASSERT(pManager!=NULL);
return pManager->LoadState(lpszProfileName);
}
#endif // OXCP_NO_SAVESTATE
COXSoundEffectManager* COXSoundEffectOrganizer::CreateManager(CWnd* pWnd)
{
ASSERT(pWnd);
ASSERT(::IsWindow(pWnd->GetSafeHwnd()));
COXSoundEffectManager* pManager=NULL;
try
{
pManager=new COXSoundEffectManager(this);
}
catch (CMemoryException* pException)
{
UNREFERENCED_PARAMETER(pException);
TRACE(_T("COXSoundEffectOrganizer::CreateManager: failed to allocate memory for COXSoundEffectManager object\n"));
return NULL;
}
ASSERT(pManager!=NULL);
if(!pManager->Attach(pWnd))
{
TRACE(_T("COXSoundEffectOrganizer::CreateManager: failed to attach specified window\n"));
delete pManager;
return NULL;
}
m_allSoundEffectManagers.SetAt(pWnd,pManager);
return pManager;
}