Excel Automation-使用FindConnectionPoint过滤com事件

Excel Automation - Filter COM events using FindConnectionPoint

本文关键字:com 事件 过滤 FindConnectionPoint Automation- 使用 Excel      更新时间:2023-10-16

i使用C com收听现有Excel应用程序的事件IID_APPLICATIONEVENTS。我的代码放在单独的EXE文件中。连接点以以下代码初始化:

    IConnectionPointContainer* pCPC = NULL;
    hr = pEventSource->QueryInterface(IID_IConnectionPointContainer,
        (void**)&pCPC);
    if (SUCCEEDED(hr)){
        hr = pCPC->FindConnectionPoint(IID_ApplicationEvents, &m_pConnectionPoint);
        if (SUCCEEDED(hr)){
            hr = m_pConnectionPoint->Advise(this, &m_dwConnection);
            if (FAILED(hr))         
                LOG_ERROR(L"m_pConnectionPoint->Advise - FAIL");
        }
        else
            LOG_ERROR(L"FindConnectionPoint - IID_ApplicationEvents: FAIL");
        pCPC->Release();
    }
    else
        LOG_ERROR(L"IID_IConnectionPointContainer: FAIL");
    return hr;

我正在通过Invoke函数接收Excel事件:

STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
    WORD wFlags, DISPPARAMS* pDispParams,
    VARIANT* pVarResult, EXCEPINFO* pExcepInfo,
    UINT* puArgErr)

我的问题如下:为了提高我的应用程序的性能,而不是放慢excel的速度,我只对OnBeforesave和Onclose事件感兴趣。有没有一种方法可以过滤我的过程中的其他Excel事件(我不希望调用我的调用函数)?

正如上面注释中提到的igor,您不能简单地过滤事件。但是,您可以自己构建一些事情来做到这一点。

这是一种方法:

  • 创建将加载在Excel过程中的COM加载项。(请参阅IDTExtensibility2)。
  • 当调用OnConnection时:
    • 创建您自己的本土事件过滤类的实例(实现IDispatch来处理事件和IConnectionPointContainer以提高事件)。
    • 使事件过滤对象"公开"通过将其IUnknown指针分配给Object属性的AddIn对象的属性,该属性作为AddInIst参数为OnConnection
  • 当您的事件过滤器对象接收事件时,请根据规则过滤。如果事件未过滤,请从过滤器对象提出。
  • 在您的外部过程中,在AddIns2集合中找到COM加载项,然后阅读其Object属性。然后,您可以将其视为事件源,而不是Application对象。