📄 meastool.cpp
字号:
//-----------------------------------------------------------------------------
// 文件名: meastool.cpp
//
// 描 述: 实现一个继承自IDirectMusicTool,用以更新一个UI正方形,使其在调节时闪烁红光,
// 在敲击时闪烁绿光。
//-----------------------------------------------------------------------------
#include <dmusici.h>
#include "MeasTool.h"
#include "resource.h"
CMeasureTool* g_pMusicTool = NULL;
//-----------------------------------------------------------------------------
// 函数名: CMeasureTool::CMeasureTool()
// 描 述:
//-----------------------------------------------------------------------------
CMeasureTool::CMeasureTool(HWND hwndParent)
{
m_cRef = 1; // // 设置为1,可调用Release()释放
m_hwndParent = hwndParent;
g_pMusicTool = this;
}
//-----------------------------------------------------------------------------
// 函数名: CMeasureTool::~CMeasureTool()
// 描 述:
//-----------------------------------------------------------------------------
CMeasureTool::~CMeasureTool()
{
}
//-----------------------------------------------------------------------------
// 函数名: CMeasureTool::QueryInterface()
// 描 述:
//-----------------------------------------------------------------------------
STDMETHODIMP CMeasureTool::QueryInterface(const IID &iid, void **ppv)
{
if (iid == IID_IUnknown || iid == IID_IDirectMusicTool)
{
*ppv = static_cast<IDirectMusicTool*>(this);
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown*>(this)->AddRef();
return S_OK;
}
//-----------------------------------------------------------------------------
// 函数名: CMeasureTool::AddRef()
// 描 述:
//-----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CMeasureTool::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
//-----------------------------------------------------------------------------
// 函数名: CMeasureTool::Release()
// 描 述:
//-----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CMeasureTool::Release()
{
if( 0 == InterlockedDecrement(&m_cRef) )
{
delete this;
return 0;
}
return m_cRef;
}
//-----------------------------------------------------------------------------
// 函数名: CMeasureTool::Init()
// 描 述:
//-----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CMeasureTool::Init( IDirectMusicGraph* pGraph )
{
// 本工具不需要任何初始化
return E_NOTIMPL;
}
//-----------------------------------------------------------------------------
// 函数名: CMeasureTool::GetMsgDeliveryType()
// 描 述:
//-----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CMeasureTool::GetMsgDeliveryType( DWORD* pdwDeliveryType )
{
// 本工具需要消息在消息被处理的时刻。
// 如此以便"敲击指示器"在敲击时闪烁而不是之前
*pdwDeliveryType = DMUS_PMSGF_TOOL_ATTIME;
return S_OK;
}
//-----------------------------------------------------------------------------
// 函数名: CMeasureTool::GetMediaTypeArraySize()
// 描 述:
//-----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CMeasureTool::GetMediaTypeArraySize( DWORD* pdwNumElements )
{
// 这个工具只需要note、patch、sysex和MIDI四种消息,
// 所以*pdwNumElements为4.
*pdwNumElements = 1;
return S_OK;
}
//-----------------------------------------------------------------------------
// 函数名: CMeasureTool::GetMediaTypes()
// 描 述:
//-----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CMeasureTool::GetMediaTypes( DWORD** padwMediaTypes,
DWORD dwNumElements )
{
// 用本工具想要处理的消息的类型来填充padwMediaTypes数组。
// 本例中dwNumElements将为3, 因为该数据是从GetMediaTypeArraySize()返回的。
if( dwNumElements == 1 )
{
// 设置数组的元素为DMUS_PMSGT_NOTE,
// DMUS_PMSGT_MIDI, and DMUS_PMSGT_PATCH
(*padwMediaTypes)[0] = DMUS_PMSGT_NOTIFICATION;
return S_OK;
}
else
{
// 这应该不会发生
return E_FAIL;
}
}
// ------------------------------------------------------------------------------
#define DUMPGUID(g) if (pNotiMsg->guidNotificationType == (g)) OutputDebugString(#g "\n")
//-----------------------------------------------------------------------------
// 函数名: CMeasureTool::ProcessPMsg()
// 描 述:
//-----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE
CMeasureTool::ProcessPMsg
(
IDirectMusicPerformance* pPerf,
DMUS_PMSG* pPMsg
)
{
DMUS_NOTIFICATION_PMSG* pNotiMsg = (DMUS_NOTIFICATION_PMSG*)pPMsg;
// 返回S_FREE释放消息. 如果StampPMsg()失败,没有此消息的目的地,因此释放它
if(( NULL == pPMsg->pGraph ) ||
FAILED(pPMsg->pGraph->StampPMsg(pPMsg)))
{
return DMUS_S_FREE;
}
// 本工具被设置只接受DMUS_PMSGT_NOTIFICATION类型的消息
if (pNotiMsg->guidNotificationType == GUID_NOTIFICATION_MEASUREANDBEAT)
{
if (pNotiMsg->dwField1 == 0)
Blink(eMeasure);
else
Blink(eBeat);
}
//返回DMUS_S_REQUEUE,因此原始消息被重新排列
return DMUS_S_REQUEUE;
}
//-----------------------------------------------------------------------------
// 函数名: CMeasureTool::Flush()
// 描 述:
//-----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CMeasureTool::Flush( IDirectMusicPerformance* pPerf,
DMUS_PMSG* pDMUS_PMSG,
REFERENCE_TIME rt)
{
// 不需要流
return E_NOTIMPL;
}
// ------------------------------------------------------------------------------
// 函数名: CMeasureTool::Blink()
// 描 述:
// ------------------------------------------------------------------------------
void CMeasureTool::Blink(EBeatType eType)
{
HWND hwndBox = GetDlgItem(m_hwndParent, IDC_BLINKY);
if (hwndBox)
{
HDC hdcBox = GetDC(hwndBox);
RECT rcBox;
HBRUSH hbrColored, hbrOld;
COLORREF color = RGB(0, 0, 0);
UINT nTimerId = 0; // 使用'this'作为一个LUID
switch (eType)
{
case eOff:
KillTimer(m_hwndParent, nTimerId);
color = GetSysColor(COLOR_3DFACE);
break;
case eMeasure:
SetTimer(m_hwndParent, nTimerId, 100, Unblink);
color = RGB(255, 0, 0); // 在调节时闪烁红光
break;
case eBeat:
SetTimer(m_hwndParent, nTimerId, 100, Unblink);
color = RGB(0, 255, 0); // 在敲击时闪烁绿光
}
hbrColored = (HBRUSH)CreateSolidBrush(color);
hbrOld = (HBRUSH)SelectObject(hdcBox, hbrColored);
GetClientRect(hwndBox, &rcBox);
Rectangle(hdcBox, rcBox.left, rcBox.top, rcBox.right, rcBox.bottom);
SelectObject(hdcBox, hbrOld);
DeleteObject(hbrColored);
ReleaseDC(hwndBox, hdcBox);
}
}
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
void CALLBACK Unblink
(
HWND hwnd,
UINT uMsg,
UINT_PTR idEvent,
DWORD dwTime
)
{
if( g_pMusicTool )
g_pMusicTool->Blink(eOff);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -