创建COM事件处理程序的问题 [英] Problems creating COM event handler

查看:167
本文介绍了创建COM事件处理程序的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经能够在COM界面中成功调用函数。 但是我继续努力为同一个COM对象创建一个事件处理程序。



我的代码包含以下import语句:

I have been able to successfully invoke functions in a COM interface.  But I continue to struggle with creating an event handler for the same COM object.

My code contains the following import statement:

#import "LogosCOM.tlb"

此.tlb文件是从包含COM对象的.exe文件创建的。 导入创建了2个文件--logoscom.tli和logoscom.tlh - 分别提供接口和头文件定义。



在.tlh文件中,我发现以下内容:

And this .tlb file was created from the .exe file which contains the COM object.  The import creates 2 files - logoscom.tli and logoscom.tlh - which provides the interface and the header file definitions, respectively.

In the .tlh file, I find the following:

struct __declspec(uuid("d80579b0-eb69-4217-a170-f0bec30b2672"))
ILogosApplicationEvents : IDispatch
{
   // Methods:
   HRESULT PanelOpened(IDispatch *Panel);
   HRESULT PanelActivated(IDispatch *Panel);
   HRESULT PanelChanged(IDispatch *Panel, IDispatch* Hint);
   HRESULT PanelClosed(IDispatch * Panel);
   HRESULT Exiting();
};

我希望我的程序能够处理"PanelChanged"。事件。



我根据这个在线文档在我的C ++代码中进行了设置:

https://docs.microsoft.com/ en-us / cpp / cpp / event-handling-in-native-cpp

I want my program to handle the "PanelChanged" event.

I set things up in my C++ code based on this online documentation:
https://docs.microsoft.com/en-us/cpp/cpp/event-handling-in-native-cpp

我试着按照这个例子,并且有95%的路在那里,但遇到一个小的(?)错误... 这是我创建的相关代码:

I tried following the example, and got 95% of the way there, but ran into one small(?) error...  Here's the relevant code I created:

[event_receiver(native)]
class CEventReceiver
{
public:
    void OnLogosPanelChanged(IDispatch * Panel, IDispatch * Hint)
    {
        printf_s("OnLogosPanelChanged was called.\n");
    }

    void hookEvent(Logos4Lib::ILogosApplicationEvents *pEventSource)
    {
        __hook(&Logos4Lib::ILogosApplicationEvents::PanelChanged, pEventSource,
               &CEventReceiver::OnLogosPanelChanged);
    }

    void unhookEvent(Logos4Lib::ILogosApplicationEvents *pEventSource)
    {
        __unhook(&Logos4Lib::ILogosApplicationEvents::PanelChanged, pEventSource,
                 &CEventReceiver::OnLogosPanelChanged);
    }
};

OnLogosPanelChanged()是回调函数。  hookEvent()方法告诉COM对象使用这个回调函数来处理指定的事件。



然后我把这段代码放在我的程序的其他地方(我设置的地方)与COM对象的连接):
$

OnLogosPanelChanged() is the callback function.  The hookEvent() method tells the COM object to use this callback function to handle the specified event.

Then I put this code elsewhere in my program (where I set up the connection to the COM object):

    Logos4Lib::ILogosApplicationEvents eventSource;
    CEventReceiver eventReceiver;
    eventReceiver.hookEvent(&eventSource);

IDE标记了eventSource声明的错误:  "错误C2259:'Logos4Lib :: ILogosApplicationEvents':无法实例化抽象类"。左


我不确定为什么这是抽象的,鉴于上面的定义。  ;当我尝试编译时,收到更多错误消息:



linklogos.cpp(39):警告C4467:不推荐使用ATL属性



这与以下行有关:

The IDE flags an error on the declaration of eventSource:  "error C2259: 'Logos4Lib::ILogosApplicationEvents': cannot instantiate abstract class".

I'm not sure why this is abstract, given its definition above.  When I try to compile, I get more error messages:

linklogos.cpp(39): warning C4467: usage of ATL attributes is deprecated

This relates to the line:

[event_receiver(native)]

linklogos.cpp(50):错误C3723:'Logos4Lib :: ILogosApplicationEvents :: PanelChanged':
无法解决事件

logoscom.tli(113):注意:请参阅'Logos4Lib :: ILogosApplicationEvents :: PanelChanged'的声明。

linklogos.cpp (50):注意:事件处理程序是以下之一:
$
linklogos.cpp(50):注意:可能是'void CEventReceiver :: OnLogosPanelChanged(IDispatch *,IDispatch *)'

linklogos.cpp(50):注意:没有活动:

logoscom.tli(113):注意:     'HRESULT Logos4Lib :: ILogosApplicationEvents :: PanelChanged(IDispatch *,IDispatch *)':
不是活动



此错误与行有关:

linklogos.cpp(50): error C3723: 'Logos4Lib::ILogosApplicationEvents::PanelChanged': could not resolve event
logoscom.tli(113): note: see declaration of 'Logos4Lib::ILogosApplicationEvents::PanelChanged'
linklogos.cpp(50): note: The event handler is one of:
linklogos.cpp(50): note: could be 'void CEventReceiver::OnLogosPanelChanged(IDispatch *,IDispatch* )'
linklogos.cpp(50): note: There are no events:
logoscom.tli(113): note:     'HRESULT Logos4Lib::ILogosApplicationEvents::PanelChanged(IDispatch *,IDispatch* )': is not an event

This error relates to the line:

    __hook(&Logos4Lib::ILogosApplicationEvents::PanelChanged, pEventSource,
               &CEventReceiver::OnLogosPanelChanged);



linklogos.cpp(56):错误C3723:'Logos4Lib :: ILogosApplicationEvents :: PanelChanged':
无法解决事件

logoscom.tli(113):注意:请参阅'Logos4Lib :: ILogosApplicationEvents :: PanelChanged'的声明。 $ b linklogos.cpp(56):注意:事件处理程序是以下之一:
$
linklogos.cpp(56):注意:可能是'void CEventReceiver :: OnLogosPanelChanged(IDispatch *,IDispatch *) '
$
linklogos.cpp(56):注意:没有活动:

logoscom.tli(113):注意:     'HRESULT Logos4Lib :: ILogosApplicationEvents :: PanelChanged(IDispatch *,IDispatch *)':
不是活动



此错误与以下行有关:


linklogos.cpp(56): error C3723: 'Logos4Lib::ILogosApplicationEvents::PanelChanged': could not resolve event
logoscom.tli(113): note: see declaration of 'Logos4Lib::ILogosApplicationEvents::PanelChanged'
linklogos.cpp(56): note: The event handler is one of:
linklogos.cpp(56): note: could be 'void CEventReceiver::OnLogosPanelChanged(IDispatch *,IDispatch* )'
linklogos.cpp(56): note: There are no events:
logoscom.tli(113): note:     'HRESULT Logos4Lib::ILogosApplicationEvents::PanelChanged(IDispatch *,IDispatch* )': is not an event

This error relates to the line:

    __unhook(&Logos4Lib::ILogosApplicationEvents::PanelChanged, pEventSource,
                 &CEventReceiver::OnLogosPanelChanged);



linklogos.cpp(75):错误C2259:'Logos4Lib :: ILogosApplicationEvents':无法实例化抽象类

linklogos.cpp(75):注意:由于以下成员:

linklogos.cpp(75) ):注意:'HRESULT IUnknown :: QueryInterface(const IID&,void **)':
是抽象的

c:\program files(x86 )\ windows kits\10\include\10.0.16299.0\um\unknwnbase.h(113):注意:请参阅'IUnknown :: QueryInterface'的声明

linklogos.cpp (75):注意:'ULONG IUnknown :: AddRef(void)': is abstract

c:\program files(x86)\ windows与kits \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ :注意:请参阅'IUnknown :: AddRef'的声明。

linklogos.cpp(75):注意:'ULONG IUnknown :: Release(void)':是抽象的

c:\program files(x86)\ windows kits \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ :发布'
$
linklogos.cpp(75):注意:'HRESULT IDispatch :: GetTypeInfoCount(UINT *)':是抽象的

c: \program files(x86)\ windows与kits \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ b $ b linklogos.cpp(75):注意:'HRESULT IDispatch :: GetTypeInfo(UINT,LCID,ITypeInfo **)':
是抽象的

c :\program files(x86)\windows kits\10\include\10.0.16299.0 \\oaidl.h(2207):注意:请参阅'IDispatch :: GetTypeInfo'的声明.b
linklogos.cpp(75):注意:'HRESULT IDispatch :: GetIDsOfNames(const IID& ,LPOLESTR *,UINT,LCID,DISPID *)':
是抽象的

c:\ program program(x86)\windows kits\10 \\ \\include\10.0.16299.0\um\oaidl.h(2212):注意:请参阅'IDispatch :: GetIDsOfNames'的声明

linklogos.cpp(75):注意:'HRESULT IDispatch :: Invoke(DISPID,const IID&,LCID,WORD,DISPPARAMS *,VARIANT *,EXCEPINFO *,UINT *)':
是抽象的

c :\ program files(x86)\ windows与kits \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


此错误与行有关:


linklogos.cpp(75): error C2259: 'Logos4Lib::ILogosApplicationEvents': cannot instantiate abstract class
linklogos.cpp(75): note: due to following members:
linklogos.cpp(75): note: 'HRESULT IUnknown::QueryInterface(const IID &,void **)': is abstract
c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\unknwnbase.h(113): note: see declaration of 'IUnknown::QueryInterface'
linklogos.cpp(75): note: 'ULONG IUnknown::AddRef(void)': is abstract
c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\unknwnbase.h(117): note: see declaration of 'IUnknown::AddRef'
linklogos.cpp(75): note: 'ULONG IUnknown::Release(void)': is abstract
c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\unknwnbase.h(119): note: see declaration of 'IUnknown::Release'
linklogos.cpp(75): note: 'HRESULT IDispatch::GetTypeInfoCount(UINT *)': is abstract
c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\oaidl.h(2204): note: see declaration of 'IDispatch::GetTypeInfoCount'
linklogos.cpp(75): note: 'HRESULT IDispatch::GetTypeInfo(UINT,LCID,ITypeInfo **)': is abstract
c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\oaidl.h(2207): note: see declaration of 'IDispatch::GetTypeInfo'
linklogos.cpp(75): note: 'HRESULT IDispatch::GetIDsOfNames(const IID &,LPOLESTR *,UINT,LCID,DISPID* )': is abstract
c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\oaidl.h(2212): note: see declaration of 'IDispatch::GetIDsOfNames'
linklogos.cpp(75): note: 'HRESULT IDispatch::Invoke(DISPID,const IID &,LCID,WORD,DISPPARAMS *,VARIANT* ,EXCEPINFO *,UINT* )': is abstract
c:\program files (x86)\windows kits\10\include\10.0.16299.0\um\oaidl.h(2219): note: see declaration of 'IDispatch::Invoke'

This error relates to the line:

    Logos4Lib::ILogosApplicationEvents eventSource;



第一条错误消息可能是最令人不安的......&n BSP;有什么想法吗?


The first error message is perhaps the most troubling...  Any ideas?

推荐答案

如果您只想使用原生C ++,请查看Raymond Chen的博客文章
将接口作为连接点接口发送

它包括您可以根据需要根据源接口中使用的IID和DISPID修改的示例代码, 我不知道PanelChanged事件的DISPID是否在生成的tlh / tli头文件中;如果不是,你可以使用oleview.exe从
轻松获取它。

It includes sample code that you can modify as needed based on the IID and the DISPIDs that are used in the source interface,  I don't know if the DISPID for the PanelChanged event is in the generated tlh/tli headers; if it isn't you can obtain it from the tlb easily with oleview.exe.

另一种方法是使用ATL的类进行COM事件处理,如
https://docs.microsoft.com/en-gb/cpp/atl/event-handling-and-atl

Another way is to use ATL's classes for COM event handling as described at https://docs.microsoft.com/en-gb/cpp/atl/event-handling-and-atl

我从未使用过ATL属性代码(前一段时间已弃用)因此我无法针对发布的代码提供具体建议。

I've never used ATL attributed code (it was deprecated a while ago) so I can't offer specific suggestions for the posted code.


这篇关于创建COM事件处理程序的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆