问题描述
我已经能够在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?
推荐答案
它包括您可以根据需要根据源接口中使用的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事件处理程序的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!