你目前正处于脱机状态,正在等待 Internet 重新连接

错误:"0x80070057 (E_INVALIDARG-参数不正确)"当使用 ATL 捕获事件时作为事件的参数使用枚举时出现错误消息

重要说明:本文是由 Microsoft 机器翻译软件进行的翻译并可能由 Microsoft 社区通过社区翻译机构(CTF)技术进行后期编辑,或可能是由人工进行的翻译。Microsoft 同时向您提供机器翻译、人工翻译及社区后期编辑的文章,以便对我们知识库中的所有文章以多种语言提供访问。翻译的文章可能存在词汇、句法和/或语法方面的错误。Microsoft 对由于内容的误译或客户对内容的使用所导致的任何不准确、错误或损失不承担责任。

点击这里察看该文章的英文版: 237771
症状
使用SINK_ENTRYSINK_ENTRY_EX定义 ATL 事件接收器将未能捕捉到事件时枚举作为参数中的一个事件。IDispatch::Invoke 返回的错误代码为"0x80070057 (E_INVALIDARG-参数不正确)。"在另一个容器,如 Visual Basic 中,该事件将会成功。
原因
IDispEventImpl's GetFuncInfoFromID method checks the type of the event parameters and, on encountering type VT_USERDEFINED, calls GetUserDefinedType.目前,此方法检查仅为TKIND_ALIAS ("typedef 结构"数据类型) 和不TKIND_ENUM
解决方案
有几种方法来变通解决此问题。一种方法是使用SINK_ENTRY_INFO宏并定义_ATL_FUNC_INFO结构,以提供有关该事件的方法的类型信息。用于枚举参数 vt_i4 类型类型。 有关 SINK_ENTRY_INFO 的详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章 ︰
194179 AtlEvnt.exe 示例说明如何使用 ATL IDispEventImpl 和 IDispEventSimpleImpl 类来创建 ATL 接收器
如果您使用的 IDispEventImpl<>为接收器,可以重写的虚函数GetFuncInfoFromID。下面是简单的重写。
HRESULT GetFuncInfoFromId(const IID& iid, DISPID dispidMember,LCID lcid, _ATL_FUNC_INFO& info){	// class base class implementation    HRESULT hr = IDispEventImpl<IDC_OBJ, CSinkObj, &DIID__IEnumEventEvents, &LIBID_TESTUNKARTICLELib, 1, 0>::GetFuncInfoFromId(iid, dispidMember,lcid, info);    if (SUCCEEDED(hr))	{        // is this the correct event interface        if (InlineIsEqualGUID(iid, DIID__IEnumEventEvents))		{            //check for dispid of event with enum param            switch(dispidMember)			{                case 1:                    // the enumeration parameter is change to VT_I4                    // info.pVarTypes represents the type of params                    // params are stored in reverse order, with 0 base index                    if (info.pVarTypes[0] == VT_USERDEFINED)                        info.pVarTypes[0] = VT_I4;                      break;			}		}	}    return hr;}				
最直接的方法时使用 IDispEventImpl<>是GetUserDefinedType Atlcom.h 中的实现进行更改。在开始的代码块后行 3968,"如果 (pta && pta-> typekind = = TKIND_ALIAS)",无法插入第二个if语句这会设置正确选项的枚举。可以按如下方式编写此块。
if (pta && pta->typekind == TKIND_ENUM){    vt = VT_I4;}				
状态
Microsoft 已经确认这是"适用于"一节中列出的 Microsoft 产品中的故障。在 Microsoft Visual C++ 的.NET 中,此问题已得到纠正。
参考
有关详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
194179 AtlEvnt.exe 示例说明如何使用 ATL IDispEventImpl 和 IDispEventSimpleImpl 类来创建 ATL 接收器
181277 AtlSink.exe 示例演示如何通过在 Visual C++ 中使用活动模板库 (ATL) 实现调度接口接收器
另请参见 ATL 文章在 Visual C++ 文档中,特别是"ATL 集合和枚举数"和"事件处理在 atl。"

警告:本文已自动翻译

属性

文章 ID:237771 - 上次审阅时间:05/07/2016 23:32:00 - 修订版本: 4.0

Microsoft ActiveX Template Library 3.0

  • kberrmsg kbtshoot kbactivexevents kbautomation kbbug kbconnpts kbfix kbmt KB237771 KbMtzh
反馈
/javascript" src="https://c.microsoft.com/ms.js">