Click here to Skip to main content
15,881,687 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
GeneralRe: ATL compiler error Pin
David Crow12-Mar-10 5:14
David Crow12-Mar-10 5:14 
GeneralRe: ATL compiler error Pin
Roger Stoltz12-Mar-10 5:43
Roger Stoltz12-Mar-10 5:43 
QuestionRe: ATL compiler error Pin
David Crow12-Mar-10 5:55
David Crow12-Mar-10 5:55 
AnswerRe: ATL compiler error Pin
Roger Stoltz12-Mar-10 8:34
Roger Stoltz12-Mar-10 8:34 
GeneralRe: ATL compiler error Pin
David Crow12-Mar-10 9:50
David Crow12-Mar-10 9:50 
GeneralRe: ATL compiler error Pin
Roger Stoltz16-Mar-10 0:34
Roger Stoltz16-Mar-10 0:34 
GeneralRe: ATL compiler error Pin
David Crow16-Mar-10 2:58
David Crow16-Mar-10 2:58 
GeneralRe: ATL compiler error Pin
Roger Stoltz16-Mar-10 4:44
Roger Stoltz16-Mar-10 4:44 
DavidCrow wrote:
Roger Stoltz wrote:

The error returned to the server is most likely E_NOINTERFACE.


Which is 0x8004002. The error that I am getting is 0x80040202.


Well, you're not the server which means that what I'm talking about is the error message your client is sending the Media Player when the Media Player server asks for your implementation of the IWMPEvents source interface.


David, now I'm just guessing, but I get the impression that you've misinterpreted some part of what I've been trying to explain and I cannot really figure out what part...
Most likely I haven't been very clear on the subject so let me try again.

It looks like you've opted for my suggestion based on a nested class to use as an event sink, otherwise I don't understand your pEventHandler variable as it should be this in the call to Advise(). Whatever pEventHandler points to doesn't seem to expose the IWMPEvents interface judging from the error you got.
If you are using the nested class version you should remove the IWMPEvents entry from the COM_MAP in the outer class and put it into the presumably non-existing COM_MAP of the inner/nested class. You can think of the COM_MAP as being traversed when QueryInterface() is called on your object.

I don't understand why you're exposing the IMyEventHandler and IDispatch interfaces from your class. Perhaps you did it intentionally or it could be a misunderstanding. Who is going to use those interfaces? If you're not trying to develop a COM server yourself that exposes e.g. IMyEventHandler, then I guess it shouldn't be there in the first place.

However, now that you've provided an important part of your class declaration I can try and patch together a declaration based on the nested class scenario for you. I hope things will clear up afterwards.
It should look something like this:
class ATL_NO_VTABLE CMyEventHandler : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMyEventHandler, &CLSID_MyEventHandler>,
    public IDispatchImpl,
{
public:
    CMyEventHandler() {}

DECLARE_REGISTRY_RESOURCEID(IDR_MYEVENTHANDLER)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CMyEventHandler)
	COM_INTERFACE_ENTRY(IMyEventHandler)
	COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

protected:
	class ATL_NO_VTABLE CMyEventSink : 
		public CComObjectRootEx<CComSingleThreadModel>,
		public IWMPEvents
	{
		public:
			CMyEventSink( CMyEventHandler* pParent = NULL ) { m_pParent = pParent; }

			BEGIN_COM_MAP( CMyEventSink )
				COM_INTERFACE_ENTRY(IWMPEvents)
			END_COM_MAP()

		public:
			/* Here goes declarations of the functions in the IWMPEvents interface */
			STDMETHOD(PlayStateChanged)( long NewState ) { m_pParent->PlayStateChanged( NewState ); } // E.g.

		protected:
			CMyEventHandler* m_pParent;
	}; 

	friend class CMyEventSink;
	CMyEventSink* m_pMyEventSink;
	CComPtr<IConnectionPoint> m_spConnectionPoint;
	DWORD m_dwWMPEventsCookie;

	void PlayStateChanged( long NewState ); // Called from the event sink
...
};

The nested class CMyEventSink is the only part that is interesting as far as COM events are concerned. Here I just put it inside the outer CMyEventHandler, which seems to be a COM server itself, for clarification reasons and because I guess that you've already started going in this direction. This way you can see that CMyEventHandler exposes the two interfaces IMyEventHandler and IDispatch. The nested class, CMyEventSink, serves no other purpose than acting as an event sink for the IWMPEvents interface.
Given the declaration above, you can hook up for receiving IWMPEvents from the CMyEventHandler class like we've discussed earlier:
CComPtr<IWMPPlayer> spWMPPlayer;
CComPtr<IConnectionPoint> spConnectionPoint;
DWORD dwAdviseCookie;
HRESULT hr;

/* Create the CMyEventSink object, error checking omitted for brevity
** Provide this-pointer to let CMyEventSink call CMyEventHandler functions */
m_pMyEventSink =  new CComObject<CMyEventSink>( this ); 

/* Get the connection point */
CComQIPtr<IConnectionPointContainer, &__uuidof(IConnectionPointContainer)> spConnectionContainer( spWMPPlayer );
if( spConnectionContainer )
{
	hr = spConnectionContainer->FindConnectionPoint( __uuidof(IWMPEvents), &m_spConnectionPoint ) 
	if( m_pMyEventSink && SUCCEEDED( hr ) )
	{
		hr = m_spConnectionPoint->Advise( (IUnknown*)m_pMyEventSink, &m_dwWMPEventsCookie );
	}
}

When you're done receiving events from the Media Player, unregister as listener with the following:
m_spConnectionPoint->Unadvise( m_dwWMPEventsCookie );
m_spConnectionPoint.Release();


If you don't get it to work after trying out the above, I need to see your complete CMyEventHandler declaration. Well, you can of course omit the inherited functions from the IWMPEvents interface. I also need the snippet of code where your create whatever you provide in the call to IConnectionPoint::Advise() that should serve as event sink and also where actually make the call to Advise().

Naturally I don't know anything Media Player specific as I haven't been working with it. Not yet, at least. The parts I've understood to be Media Player specific I have just made qualified guesses and put some mocks to explain the bigger picture. E.g. the method PlayStateChanged() may very well be declared incorrectly and it may not at all be the event callback you need.
I've tried to concentrate on the COM stuff, some ATL quirks and how to set up an event sink the way I usually do it.

Phhwwweeee...... That was a long one, I even got a warning saying it's long when trying to post it.... Wink | ;)

"It's supposed to be hard, otherwise anybody could do it!" - selfquote
"High speed never compensates for wrong direction!" - unknown


GeneralRe: ATL compiler error Pin
David Crow16-Mar-10 9:00
David Crow16-Mar-10 9:00 
GeneralRe: ATL compiler error Pin
Roger Stoltz19-Mar-10 2:30
Roger Stoltz19-Mar-10 2:30 
QuestionSystem Tray Context Menu Pin
MrMcIntyre11-Mar-10 9:09
MrMcIntyre11-Mar-10 9:09 
AnswerRe: System Tray Context Menu Pin
loyal ginger11-Mar-10 9:31
loyal ginger11-Mar-10 9:31 
GeneralRe: System Tray Context Menu Pin
MrMcIntyre11-Mar-10 9:40
MrMcIntyre11-Mar-10 9:40 
GeneralRe: System Tray Context Menu Pin
loyal ginger11-Mar-10 9:59
loyal ginger11-Mar-10 9:59 
GeneralRe: System Tray Context Menu Pin
loyal ginger11-Mar-10 10:07
loyal ginger11-Mar-10 10:07 
GeneralRe: System Tray Context Menu Pin
LouisLewis15-Mar-10 11:05
LouisLewis15-Mar-10 11:05 
AnswerRe: System Tray Context Menu Pin
David Crow11-Mar-10 10:45
David Crow11-Mar-10 10:45 
AnswerRe: System Tray Context Menu Pin
Richard MacCutchan11-Mar-10 10:51
mveRichard MacCutchan11-Mar-10 10:51 
QuestionEncoding a string Pin
Herboren11-Mar-10 8:42
Herboren11-Mar-10 8:42 
AnswerRe: Encoding a string Pin
Chris Losinger11-Mar-10 8:48
professionalChris Losinger11-Mar-10 8:48 
AnswerRe: Encoding a string Pin
Jonathan Davies11-Mar-10 8:51
Jonathan Davies11-Mar-10 8:51 
GeneralRe: Encoding a string Pin
Herboren11-Mar-10 9:01
Herboren11-Mar-10 9:01 
GeneralRe: Encoding a string Pin
Jonathan Davies11-Mar-10 9:13
Jonathan Davies11-Mar-10 9:13 
GeneralRe: Encoding a string Pin
Herboren11-Mar-10 9:29
Herboren11-Mar-10 9:29 
GeneralRe: Encoding a string Pin
Herboren11-Mar-10 9:34
Herboren11-Mar-10 9:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.