// ========================================================================== // 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(®, 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(®, 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> 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> 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; }