如何与事件界面交谈?

时间:2011-10-26 19:50:36

标签: winapi com

我有一个实时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 个答案:

答案 0 :(得分:1)

它不是“标准”事件实现。通常,事件源对象将公开IConnectionPointContainerIConnectionPoint等。您的界面更像是以不同的方式实现事件。

似乎期待您明确地为感兴趣的事件提供接收器。请注意,虽然这不是典型的COM方法,但整个事件对事件源实现非常具体。接口定义没有说明add_MuteStateChanged参数中预期接口的确切含义。

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

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