Обработка событий в C++

[Функция, связанная с этой страницей, Медиаплеер Windows sdk, является устаревшей функцией. Он был заменен MediaPlayer. MediaPlayer оптимизирован для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует по возможности использовать MediaPlayer вместо пакета SDK для Медиаплеер Windows. Корпорация Майкрософт предлагает переписать существующий код, использующий устаревшие API, чтобы по возможности использовать новые API.]

Получить события от Медиаплеер Windows можно двумя способами.

  • С помощью IDispatch с помощью интерфейса _WMPOCXEvents . Это интерфейс, используемый в большинстве сценариев внедрения.
  • Через интерфейс IWMPEvents . Этот интерфейс доступен при подключении кода к проигрывателю в полном режиме, например при удаленном взаимодействии элемента управления Медиаплеер Windows или в подключаемом модуле пользовательского интерфейса.

В каждом сценарии вы начинаете прослушивать события с помощью 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 . Это означает, что вы можете обрабатывать только определенные события и игнорировать другие. В следующем примере кода показан обработчик _WMPOCXEvents с помощью Invoke, который обрабатывает только события 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 Mobile

Элемент управления Медиаплеер Windows 10 Mobile поддерживает получение определенных событий только через _WMPOCXEvents и IWMPEvents. Дополнительные сведения см. в документации по IWMPEvents.

Примеры

Пакет установки Медиаплеер Windows устанавливает пример, демонстрирующий обработку событий. Дополнительные сведения см. в примере WMPHost.

Примеры

Использование элемента управления Медиаплеер Windows в программе C++