meastool.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:8k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. //-----------------------------------------------------------------------------
  2. // 文件名: meastool.cpp
  3. //
  4. // 描  述: 实现一个继承自IDirectMusicTool,用以更新一个UI正方形,使其在调节时闪烁红光,
  5. //         在敲击时闪烁绿光。
  6. //-----------------------------------------------------------------------------
  7. #include <dmusici.h>
  8. #include "MeasTool.h"
  9. #include "resource.h"
  10. CMeasureTool* g_pMusicTool = NULL;
  11. //-----------------------------------------------------------------------------
  12. // 函数名: CMeasureTool::CMeasureTool()
  13. // 描  述:  
  14. //-----------------------------------------------------------------------------
  15. CMeasureTool::CMeasureTool(HWND hwndParent)
  16. {
  17.     m_cRef = 1;             // // 设置为1,可调用Release()释放
  18.     m_hwndParent = hwndParent;
  19.     g_pMusicTool = this;
  20. }
  21. //-----------------------------------------------------------------------------
  22. // 函数名: CMeasureTool::~CMeasureTool()
  23. // 描  述:  
  24. //-----------------------------------------------------------------------------
  25. CMeasureTool::~CMeasureTool()
  26. {
  27. }
  28. //-----------------------------------------------------------------------------
  29. // 函数名: CMeasureTool::QueryInterface()
  30. // 描  述:  
  31. //-----------------------------------------------------------------------------
  32. STDMETHODIMP CMeasureTool::QueryInterface(const IID &iid, void **ppv)
  33. {
  34.     if (iid == IID_IUnknown || iid == IID_IDirectMusicTool)
  35.     {
  36.         *ppv = static_cast<IDirectMusicTool*>(this);
  37.     } 
  38.     else
  39.     {
  40.         *ppv = NULL;
  41.         return E_NOINTERFACE;
  42.     }
  43.     
  44.     reinterpret_cast<IUnknown*>(this)->AddRef();
  45.     return S_OK;
  46. }
  47. //-----------------------------------------------------------------------------
  48. // 函数名: CMeasureTool::AddRef()
  49. // 描  述:  
  50. //-----------------------------------------------------------------------------
  51. STDMETHODIMP_(ULONG) CMeasureTool::AddRef()
  52. {
  53.     return InterlockedIncrement(&m_cRef);
  54. }
  55. //-----------------------------------------------------------------------------
  56. // 函数名: CMeasureTool::Release()
  57. // 描  述:  
  58. //-----------------------------------------------------------------------------
  59. STDMETHODIMP_(ULONG) CMeasureTool::Release()
  60. {
  61.     if( 0 == InterlockedDecrement(&m_cRef) )
  62.     {
  63.         delete this;
  64.         return 0;
  65.     }
  66.     return m_cRef;
  67. }
  68. //-----------------------------------------------------------------------------
  69. // 函数名: CMeasureTool::Init()
  70. // 描  述:  
  71. //-----------------------------------------------------------------------------
  72. HRESULT STDMETHODCALLTYPE CMeasureTool::Init( IDirectMusicGraph* pGraph )
  73. {
  74.     // 本工具不需要任何初始化
  75.     return E_NOTIMPL;
  76. }
  77. //-----------------------------------------------------------------------------
  78. // 函数名: CMeasureTool::GetMsgDeliveryType()
  79. // 描  述:  
  80. //-----------------------------------------------------------------------------
  81. HRESULT STDMETHODCALLTYPE CMeasureTool::GetMsgDeliveryType( DWORD* pdwDeliveryType )
  82. {
  83.     // 本工具需要消息在消息被处理的时刻。 
  84.     // 如此以便"敲击指示器"在敲击时闪烁而不是之前
  85.     *pdwDeliveryType = DMUS_PMSGF_TOOL_ATTIME;
  86.     return S_OK;
  87. }
  88. //-----------------------------------------------------------------------------
  89. // 函数名: CMeasureTool::GetMediaTypeArraySize()
  90. // 描  述:  
  91. //-----------------------------------------------------------------------------
  92. HRESULT STDMETHODCALLTYPE CMeasureTool::GetMediaTypeArraySize( DWORD* pdwNumElements )
  93. {
  94.     // 这个工具只需要note、patch、sysex和MIDI四种消息, 
  95.     // 所以*pdwNumElements为4.
  96.     
  97.     *pdwNumElements = 1;
  98.     return S_OK;
  99. }
  100. //-----------------------------------------------------------------------------
  101. // 函数名: CMeasureTool::GetMediaTypes()
  102. // 描  述:  
  103. //-----------------------------------------------------------------------------
  104. HRESULT STDMETHODCALLTYPE CMeasureTool::GetMediaTypes( DWORD** padwMediaTypes, 
  105.                                                     DWORD dwNumElements )
  106. {
  107. // 用本工具想要处理的消息的类型来填充padwMediaTypes数组。
  108.     // 本例中dwNumElements将为3, 因为该数据是从GetMediaTypeArraySize()返回的。 
  109.     
  110.     if( dwNumElements == 1 )
  111.     {
  112.         // 设置数组的元素为DMUS_PMSGT_NOTE,
  113.         // DMUS_PMSGT_MIDI, and DMUS_PMSGT_PATCH
  114.         (*padwMediaTypes)[0] = DMUS_PMSGT_NOTIFICATION;
  115.         return S_OK;
  116.     }
  117.     else
  118.     {
  119.         // 这应该不会发生
  120.         return E_FAIL;
  121.     }
  122. }
  123. // ------------------------------------------------------------------------------
  124. #define DUMPGUID(g)     if (pNotiMsg->guidNotificationType == (g))  OutputDebugString(#g "n")
  125. //-----------------------------------------------------------------------------
  126. // 函数名: CMeasureTool::ProcessPMsg()
  127. // 描  述:  
  128. //-----------------------------------------------------------------------------
  129. HRESULT STDMETHODCALLTYPE 
  130. CMeasureTool::ProcessPMsg
  131.     IDirectMusicPerformance* pPerf, 
  132.     DMUS_PMSG*               pPMsg 
  133. )
  134. {
  135.     DMUS_NOTIFICATION_PMSG*  pNotiMsg = (DMUS_NOTIFICATION_PMSG*)pPMsg;
  136.  // 返回S_FREE释放消息. 如果StampPMsg()失败,没有此消息的目的地,因此释放它
  137.     if(( NULL == pPMsg->pGraph ) ||
  138.         FAILED(pPMsg->pGraph->StampPMsg(pPMsg)))
  139.     {
  140.         return DMUS_S_FREE;
  141.     }
  142.     // 本工具被设置只接受DMUS_PMSGT_NOTIFICATION类型的消息
  143.     if (pNotiMsg->guidNotificationType == GUID_NOTIFICATION_MEASUREANDBEAT)
  144.     {
  145.         if (pNotiMsg->dwField1 == 0)
  146.             Blink(eMeasure);
  147.         else
  148.             Blink(eBeat);
  149.     }    
  150.     //返回DMUS_S_REQUEUE,因此原始消息被重新排列 
  151.     return DMUS_S_REQUEUE;
  152. }
  153. //-----------------------------------------------------------------------------
  154. // 函数名: CMeasureTool::Flush()
  155. // 描  述:  
  156. //-----------------------------------------------------------------------------
  157. HRESULT STDMETHODCALLTYPE CMeasureTool::Flush( IDirectMusicPerformance* pPerf, 
  158.                                             DMUS_PMSG* pDMUS_PMSG,
  159.                                             REFERENCE_TIME rt)
  160. {
  161.     // 不需要流
  162.     return E_NOTIMPL;
  163. }
  164. // ------------------------------------------------------------------------------
  165. // 函数名: CMeasureTool::Blink()
  166. // 描  述:  
  167. // ------------------------------------------------------------------------------
  168. void CMeasureTool::Blink(EBeatType eType)
  169. {
  170.     HWND hwndBox = GetDlgItem(m_hwndParent, IDC_BLINKY);
  171.     if (hwndBox)
  172.     {
  173.         HDC         hdcBox = GetDC(hwndBox);
  174.         RECT        rcBox;
  175.         HBRUSH      hbrColored, hbrOld;
  176.         COLORREF    color = RGB(0, 0, 0); 
  177.         UINT        nTimerId = 0;  // 使用'this'作为一个LUID
  178.         
  179.         switch (eType)
  180.         {
  181.             case eOff:
  182.                 KillTimer(m_hwndParent, nTimerId);    
  183.                 color = GetSysColor(COLOR_3DFACE);
  184.                 break;
  185.             case eMeasure:
  186.                 SetTimer(m_hwndParent, nTimerId, 100, Unblink);
  187.                 color = RGB(255, 0, 0); // 在调节时闪烁红光
  188.                 break;
  189.             case eBeat:
  190.                 SetTimer(m_hwndParent, nTimerId, 100, Unblink);
  191.                 color = RGB(0, 255, 0); // 在敲击时闪烁绿光
  192.         }
  193.         
  194.         hbrColored = (HBRUSH)CreateSolidBrush(color);
  195.         hbrOld = (HBRUSH)SelectObject(hdcBox, hbrColored);
  196.         GetClientRect(hwndBox, &rcBox);
  197.         Rectangle(hdcBox, rcBox.left, rcBox.top, rcBox.right, rcBox.bottom);
  198.         SelectObject(hdcBox, hbrOld);
  199.         DeleteObject(hbrColored);
  200.         ReleaseDC(hwndBox, hdcBox);
  201.     }
  202. }
  203. // ------------------------------------------------------------------------------
  204. // ------------------------------------------------------------------------------
  205. void CALLBACK Unblink
  206. (
  207.     HWND        hwnd,
  208.     UINT        uMsg,
  209.     UINT_PTR    idEvent,
  210.     DWORD       dwTime
  211. )
  212. {
  213.     if( g_pMusicTool )
  214.         g_pMusicTool->Blink(eOff);
  215. }
  216.