-1

I am embedding Windows Media Player in a C program. I found the WMP Host example in C++ in the WMP SDK. It contains an even dispatcher. But when I receive an event, how do I know who sent the event and how do I access that class object's variables? For example, I want to set a class member (variable) or call a method.

The CWMPHost object creates the window containing the WMP object and creates the event object. The minimal code is:

LRESULT CWMPHost::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    AtlAxWinInit();
    CComPtr<IAxWinHostWindow>           spHost;
    CComPtr<IConnectionPointContainer>  spConnectionContainer;
    CComWMPEventDispatch                *pEventListener = NULL;
    CComPtr<IWMPEvents>                 spEventListener;
    HRESULT                             hr;
    RECT                                rcClient;

    m_dwAdviseCookie = 0;

    // create window
    GetClientRect(&rcClient);
    m_wndView.Create(m_hWnd, rcClient, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, 0);

    // load OCX in window
    hr = m_wndView.QueryHost(&spHost);
    hr = spHost->CreateControl(CComBSTR(_T("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView, 0);
    hr = m_wndView.QueryControl(&m_spWMPPlayer);

    // start listening to events
    hr = CComWMPEventDispatch::CreateInstance(&pEventListener);
    spEventListener = pEventListener;

    hr = m_spWMPPlayer->QueryInterface(&spConnectionContainer);

    // See if OCX supports the IWMPEvents interface
    hr = spConnectionContainer->FindConnectionPoint(__uuidof(IWMPEvents), &m_spConnectionPoint);
    if (FAILED(hr))
    {
        // If not, try the _WMPOCXEvents interface, which will use IDispatch
        hr = spConnectionContainer->FindConnectionPoint(__uuidof(_WMPOCXEvents), &m_spConnectionPoint);
    }
    hr = m_spConnectionPoint->Advise(spEventListener, &m_dwAdviseCookie);

    return 0;
}

The full sample code can be found at https://github.com/pauldotknopf/WindowsSDK7-Samples/tree/master/multimedia/WMP/cpp/WMPHost

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
  • Hmmm...I see a down vote and a close suggestion, but could anybody please help me or tell me what to do? – Paul Ogilvie Aug 02 '16 at 14:59
  • You can safely assume that it was WMP that generated the event. Nobody else will. – Hans Passant Aug 02 '16 at 15:04
  • @Hans-Passant, I intend to have more than one player active, so I must know which one. – Paul Ogilvie Aug 02 '16 at 15:08
  • The class you use to implement IWMPEvents needs an extra variable that stores a reference to one of the spWMPPlayers. In general this is not a very sensible thing to do. WMP is a very heavy object and having more than one play back media at the same time isn't typically very useful. – Hans Passant Aug 02 '16 at 15:27
  • @Hans-Pasant, but looking at how the event dispatcher is created in the above code, there is no way to pass it that reference. That's the whole problem. (Please note: I am not a C++ programmer; I am a C programmer, so maybe I lack some required knowledge of C++) – Paul Ogilvie Aug 02 '16 at 15:32
  • The code has to be modified, it doesn't get more simple than that. That this is an obstacle when you don't know C++ is a given, the abstraction level is quite high. You can't use ATL and smart pointer classes in a C program so none of this code is useful to you. Writing COM client code in C is outlawed by the Geneva Convention on Programmer's Rights, local exemptions may apply. – Hans Passant Aug 02 '16 at 15:40
  • @Hans-Passant, indeed, so I call wrappers from C that then call C++. It works fine, except for things like this. So what would be the way to pass a reference to the parent to the event dispatcher object? – Paul Ogilvie Aug 02 '16 at 15:45

1 Answers1

0

EDIT: My improved solution that meets my needs:

First I untangled the include dependencies and applied include guards against circular includes. The CWMPHost class definition doesn't need to know about the CWMPEventDispatch class; however its implementation does, so the CWMPEventDispatch.h class definition is included in the CWMPHost.cpp file but not in the CWMPHost.h file.

This allows to define a member of CWMPEventDispatch to be a pointer to the owning CWMPHost object:

    CWMPHost *pCWMPHost;

It is set in the CWMPHost::Create method:

    hr = CComWMPEventDispatch::CreateInstance(&pEventListener);
    pEventListener->pCWMPHost= this;

Now the event dispatcher can access the methods and members of the CWMPHost object that created the dispatcher.

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41