Почему мои функции IWMPEvents никогда не вызываются?

У меня проблема с IWMPEvents, который я успешно советовал, но никогда не поднимал. Вот как я создаю кодировку Windows Media Player:

HRESULT MyWMP::setURL(wchar_t* url)
{
return pMediaPlayer->put_URL(url);   // Load and play songs successfully;
}

bool MyWMP::CreatePlayer()
{
HRESULT hr;
const CLSID CLSID_WindowsMediaPlayer = { 0x6BF52A52, 0x394A, 0x11d3,{ 0xB1, 0x53, 0x00, 0xC0, 0x4F, 0x79, 0xFA, 0xA6 } };
hr = ::OleCreate(CLSID_WindowsMediaPlayer, IID_IOleObject, OLERENDER_DRAW, 0, this, this, (void**)&oleObject);
if (SUCCEEDED(hr) && oleObject)
{
if (SUCCEEDED(hr)) hr = oleObject->SetClientSite(this);
if (SUCCEEDED(hr)) hr = OleSetContainedObject(oleObject, TRUE);

if (SUCCEEDED(hr))
{
RECT posRect;
::SetRect(&posRect, -300, -300, 300, 300);
hr = oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, this, -1, this->hwnd, &posRect);
}
hr = oleObject->QueryInterface(&pMediaPlayer);
}
if (FAILED(hr) || !pMediaPlayer)
{
MessageBox(NULL, L"Create Browser failed!", L"Error", MB_ICONERROR);
return false;
}
return true;
}

MyWMP::MyWMP(HWND parentHWND, HINSTANCE hInstance) :
isFullyCreated(false)
{
OleInitialize(NULL);
HRESULT hr = E_FAIL;
IConnectionPointContainer* container = nullptr;
IUnknown* punk = nullptr;

this->parentHWND = parentHWND;
this->hwnd = CreateWindow(L"Static", NULL, WS_CHILD | WS_VISIBLE, 221, 0, 300, 300, parentHWND, NULL, hInstance, 0);

iComRefCount = 0;
::SetRect(&rObject, 0, 0, 300, 300);

if (CreatePlayer())
{
hr = pMediaPlayer->get_settings(&pMediaPlayerSettings);
if (SUCCEEDED(hr) && pMediaPlayerSettings)
{
pMediaPlayerSettings->put_autoStart(VARIANT_TRUE);
pMediaPlayerSettings->put_volume(100);
}
hr = pMediaPlayer->QueryInterface(IID_IConnectionPointContainer, (void**)&container);
if (SUCCEEDED(hr) && container) hr = container->FindConnectionPoint(__uuidof(IWMPEvents), &callback);
if (FAILED(hr) && container)
{
hr = container->FindConnectionPoint(__uuidof(_WMPOCXEvents), &callback);
}
if (SUCCEEDED(hr) && callback)
{
CWMPEventDispatch *cw = new CWMPEventDispatch();
IUnknown *cwUnk = NULL;
if (SUCCEEDED(cw->QueryInterface(IID_IUnknown, (void**)&cwUnk)))
{
if (SUCCEEDED(hr) && container)
{
hr = callback->Advise(cwUnk, &eventCookie);
if (SUCCEEDED(hr) && eventCookie)
{
isFullyCreated = true; // Set breakpoint here and is triggered
// by debugger
// hr = S_OK
}
}
}
if (cwUnk) cwUnk->Release();
}
if (punk) punk->Release();
if (container) container->Release();
}
}

Сильфон это CWMPEventDispatch учебный класс. Я установил точку останова на всех IDispatch функции и ни одна из них не запускается отладчиком. Когда я загружаю новые песни, играю / пауза (на встроенных кнопках управления пользовательского интерфейса), эти функции никогда не вызывается.

// CWMPEventDispatch.h : Declaration of the event dispatcher
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//

#include "stdafx.h"#include "wmpids.h"#include "wmp.h"
class CWMPEventDispatch :
public IWMPEvents,
public _WMPOCXEvents
{
public:

// ----- IUnknown -----
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void**ppvObject) override;
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);

// IDispatch methods
STDMETHOD(GetIDsOfNames)(REFIID /*riid*/,
__in_ecount(cNames) LPOLESTR FAR * /*rgszNames*/,
unsigned int /*cNames*/,
LCID /*lcid*/,
DISPID FAR * /*rgDispId*/)
{
return(E_NOTIMPL);
}

STDMETHOD(GetTypeInfo)(unsigned int /*iTInfo*/,
LCID /*lcid*/,
ITypeInfo FAR *FAR * /*ppTInfo*/)
{
return(E_NOTIMPL);
}

STDMETHOD(GetTypeInfoCount)(unsigned int FAR * /*pctinfo*/)
{
return(E_NOTIMPL);
}

STDMETHOD(Invoke)(DISPID  dispIdMember,
REFIID  /*riid*/,
LCID  /*lcid*/,
WORD  /*wFlags*/,
DISPPARAMS FAR*  pDispParams,
VARIANT FAR*  /*pVarResult*/,
EXCEPINFO FAR*  /*pExcepInfo*/,
unsigned int FAR*  /*puArgErr*/);private:
int iComRefCount;
};

#include "stdafx.h"#include "myWMPEventDispatch.h"
#pragma region ----- IUnknown -----
ULONG STDMETHODCALLTYPE CWMPEventDispatch::AddRef(void) { return ++iComRefCount; }
ULONG STDMETHODCALLTYPE CWMPEventDispatch::Release(void) { return --iComRefCount; }

HRESULT STDMETHODCALLTYPE CWMPEventDispatch::QueryInterface(REFIID riid, void**ppvObject)
{
if (riid == __uuidof(IUnknown))        *ppvObject = static_cast<IDispatch*>(this);
else if (riid == __uuidof(IDispatch))       *ppvObject = static_cast<IDispatch*>(this);
else if (riid == __uuidof(IWMPEvents))  *ppvObject = static_cast<IWMPEvents*>(this);
else if (riid == __uuidof(_WMPOCXEvents)) *ppvObject = static_cast<_WMPOCXEvents*>(this);
else
return E_NOINTERFACE;

AddRef();
return S_OK;
}
#pragma endregion

HRESULT CWMPEventDispatch::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;return(hr);
}

Почему мой IWMPEvents функции никогда не вызываются, и как это исправить?

Я атакую ​​полный исходный код как архив 7z. Вы можете скачать его Вот.

Окружающая среда: Win 10 x64, VS 2017 Community

2

Решение

Этот кусок кода:

if (SUCCEEDED(hr) && container) hr = container->FindConnectionPoint(__uuidof(IWMPEvents), &callback);
if (FAILED(hr) && container)
{
hr = container->FindConnectionPoint(__uuidof(_WMPOCXEvents), &callback);
}

Успешно в первой строке, так что вы будете перехватывать события на IWMPEvents только не продолжишь и зацепишь _WMPOCXEvents,

IWMPEvents — это события с ранним связыванием (производные от IUnknown), поэтому медиаплеер действительно будет вызывать IWMPEvents :: PlayStateChange (…) IWMPEvents :: StatusChange (…) и т. Д., Но не будет вызывать IDispatch :: Invoke с соответствующими идентификаторы DispId.

Если вы хотите события IDispatch, просто удалите первый FindConnectionPoint или вызовите оба.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]