2011-10-26 37 views
0

我有一个活的IDevicePtr,(IDevice是一个COM组件)。如何与事件界面交谈?

我调用一个方法(“get_DeviceEvents”)来获取它的事件接口,所以现在我有一个活的“IDeviceEvents”对象。此对象具有以下接口:

IDeviceEvents : IDispatch 
{ 
    // 
    // Raw methods provided by interface 
    // 

     virtual HRESULT __stdcall add_TalkPressed (
     /*[in]*/ IUnknown * value) = 0; 
     virtual HRESULT __stdcall remove_TalkPressed (
     /*[in]*/ IUnknown * value) = 0; 
     virtual HRESULT __stdcall add_ButtonPressed (
     /*[in]*/ IUnknown * value) = 0; 
     virtual HRESULT __stdcall remove_ButtonPressed (
     /*[in]*/ IUnknown * value) = 0; 
     virtual HRESULT __stdcall add_MuteStateChanged (
     /*[in]*/ IUnknown * value) = 0; 
     virtual HRESULT __stdcall remove_MuteStateChanged (
     /*[in]*/ IUnknown * value) = 0; 
     virtual HRESULT __stdcall add_AudioStateChanged (
     /*[in]*/ IUnknown * value) = 0; 
     virtual HRESULT __stdcall remove_AudioStateChanged (
     /*[in]*/ IUnknown * value) = 0; 
     virtual HRESULT __stdcall add_FlashPressed (
     /*[in]*/ IUnknown * value) = 0; 
     virtual HRESULT __stdcall remove_FlashPressed (
     /*[in]*/ IUnknown * value) = 0; 
     virtual HRESULT __stdcall add_SmartPressed (
     /*[in]*/ IUnknown * value) = 0; 
     virtual HRESULT __stdcall remove_SmartPressed (
     /*[in]*/ IUnknown * value) = 0; 
     virtual HRESULT __stdcall SetInputReport (
     /*[in]*/ SAFEARRAY * reportBuffer) = 0; 
}; 

说我想拦截我的应用程序中的MuteStateChanged事件。我怎么做?我可以调用“add_MuteStateChanged”。我认为这是某种事件处理程序添加方法。我应该使用什么样的有效载荷?我有一个本地的IDispatch派生类对象准备与拦截任何事件:

STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, 
     LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, 
     EXCEPINFO* pexcepinfo, UINT* puArgErr) 
    { 
     // ALL I want is to get here when some event in IDeviceEvents is fired. 
     return S_OK; 
    } 

背景:我一直在尝试了几天,现在在非MFC/ATL C++ Win32应用程序接收COM事件。事实证明,这是我必须完成的最艰难的任务,时间明智。

回答

1

这不是一个“标准”事件实施。通常情况下,事件源对象会暴露IConnectionPointContainer,IConnectionPoint等。您的界面更像是以不同方式实现事件。

它似乎期待您明确提供您的接收器为感兴趣的事件。请注意,虽然这不是一种典型的COM方法,但整个事件对于事件源实现非常具体。接口定义不提示在add_MuteStateChanged参数中预期的接口是什么。

您可以执行以下操作。将您的COM对象作为参数传递给add_MuteStateChangedIDispatch实现将会很好,它实际上可以是任何COM对象 - 这里的要点是它是您的代码,您可以跟踪此接口指针上的所有调用。检查您的事件源是否正在查询此IUnknown以外的任何接口。应该在事件发生时立即或稍后致电IUnknown::QueryInterface。截获它后,你会看到实际被查询的接口。

如果是IDispatch,该事件可能通过IDispatch::Invoke传递。否则它很可能是你需要直接实现的接口。