在 C++ 中处理事件
[与此页面关联的功能(Windows 媒体播放器 SDK)是旧版功能。 它已被 MediaPlayer 取代。 MediaPlayer 已针对Windows 10和Windows 11进行了优化。 如果可能,Microsoft 强烈建议新代码使用 MediaPlayer 而不是 Windows 媒体播放器 SDK。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
可以通过两种方式从Windows 媒体播放器接收事件。
- 通过使用 _WMPOCXEvents 接口通过 IDispatch。 这是用于大多数嵌入方案的接口。
- 通过 IWMPEvents 接口。 当代码连接到全模式 Player 时,例如远程处理Windows 媒体播放器控件或 UI 插件时,此接口可用。
在每个方案中,你都使用 COM 连接点开始侦听事件。
以下示例代码使用三个成员变量:
CComPtr<IWMPPlayer> m_spWMPPlayer;
CComPtr<IConnectionPoint> m_spConnectionPoint;
DWORD m_dwAdviseCookie;
若要检索连接点,请先为连接点容器使用 QueryInterface 。
HRESULT hr = S_OK;
// Smart pointer to IConnectionPointContainer
CComPtr<IConnectionPointContainer> spConnectionContainer;
hr = m_spWMPPlayer->QueryInterface(&spConnectionContainer);
接下来,请求要使用的事件接口的连接点。 以下示例代码首先尝试使用 IWMPEvents。 如果该接口不可用,则使用 _WMPOCXEvents。
// Test whether the control supports the IWMPEvents interface.
if(SUCCEEDED(hr))
{
hr = spConnectionContainer->FindConnectionPoint(__uuidof(IWMPEvents), &m_spConnectionPoint);
if (FAILED(hr))
{
// If not, try the _WMPOCXEvents interface, which uses IDispatch.
hr = spConnectionContainer->FindConnectionPoint(__uuidof(_WMPOCXEvents), &m_spConnectionPoint);
}
}
最后,调用 IConnectionPoint::Advise 以请求事件。
if(SUCCEEDED(hr))
{
hr = m_spConnectionPoint->Advise(this, &m_dwAdviseCookie);
}
在前面的示例中,第一个参数假定调用类同时实现 IWMPEvents 和 _WMPOCXEvents。 第二个参数是用于停止侦听事件(例如程序退出时)的返回值,使用类似于下面的代码:
// Stop listening to events
if (m_spConnectionPoint)
{
if (0 != m_dwAdviseCookie)
m_spConnectionPoint->Unadvise(m_dwAdviseCookie);
m_spConnectionPoint.Release();
}
为 IWMPEvents 和 _WMPOCXEvents 实现事件处理程序有所不同。 对于 IWMPEvents,必须实现一个函数来处理接口定义的每个事件,即使你不打算使用该事件。
// IWMPEvents methods
void STDMETHODCALLTYPE OpenStateChange( long NewState ){ return; }
void STDMETHODCALLTYPE PlayStateChange( long NewState ){ return; }
void STDMETHODCALLTYPE AudioLanguageChange( long LangID ){ return; }
// And so on...
若要实现 _WMPOCXEvents 处理程序,必须使用 IDispatch::Invoke,它是针对 IDispatch 接口上发生的所有事件的单个事件处理程序实现。 这意味着可以选择仅处理某些事件,而忽略其他事件。 以下示例代码演示了一个使用 Invoke的 _WMPOCXEvents 处理程序,该处理程序仅处理 OpenStateChange 和 PlayStateChange 事件:
HRESULT CMyClass::Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS FAR* pDispParams,
VARIANT FAR* pVarResult,
EXCEPINFO FAR* pExcepInfo,
unsigned int FAR* puArgErr )
{
if (!pDispParams)
return E_POINTER;
if (pDispParams->cNamedArgs != 0)
return DISP_E_NONAMEDARGS;
HRESULT hr = DISP_E_MEMBERNOTFOUND;
switch (dispIdMember)
{
case DISPID_WMPCOREEVENT_OPENSTATECHANGE:
OpenStateChange(pDispParams->rgvarg[0].lVal /* NewState */ );
break;
case DISPID_WMPCOREEVENT_PLAYSTATECHANGE:
PlayStateChange(pDispParams->rgvarg[0].lVal /* NewState */);
break;
// Other cases can handle additional events by using DISPIDs.
}
return( hr );
}
在前面的示例代码中,每个情况都只是通过 调用相应事件的 IWMPEvents 处理程序。 如果代码仅处理 _WMPOCXEvents,则只需调用自定义函数或在 case 语句后内联处理事件。
从 Windows 媒体播放器 10 移动版接收事件
Windows 媒体播放器 10 Mobile 控件仅支持通过 _WMPOCXEvents 和 IWMPEvents 接收某些事件。 有关详细信息,请参阅 IWMPEvents 的文档。
示例
Windows 媒体播放器安装包安装一个演示事件处理的示例。 有关详细信息,请参阅 WMPHost 示例。
相关主题
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈