无法在 MFC ActiveX 中调用方法

Posted

技术标签:

【中文标题】无法在 MFC ActiveX 中调用方法【英文标题】:Can't Call Methods in MFC ActiveX 【发布时间】:2014-07-23 02:52:39 【问题描述】:

我在VS2012中用一些接口方法创建了一个MFC ActiveX控件,这些方法效果很好。 今天我在ActiveX中添加一些新方法时,我可以在“activex control test container”中看到新方法,但是我不能调用它们(调用方法和没啥事儿)。当我尝试使用 JS 调用该方法时,这也发生在 IE11 中。这些新方法中的断点永远不会到达。 旧方法表现正常,我以相同的方式添加新方法。我不知道如何计算它,有人可以帮助我吗?非常感谢。 这是一个新方法的实现。

LONG CDCMonitorControllerClientCtrl::Init(LPCTSTR config)

    AFX_MANAGE_STATE(AfxGetStaticModuleState());

    MessageBox(_T("Call Init"));
    return 0;

/************************************************ ******************************/

我刚刚解决了这个问题。

dispatch map 中的语句必须与它们在头文件中的 dispatch ID 出现的顺序相同。

我在添加旧方法后添加了一些事件。当我添加一个新方法时,VS 将调度语句添加到 BEGIN_DISPATCH_MAP 部分的末尾,该部分位于事件调度语句之后。我将新方法的调度语句移动到旧方法的最后一个调度语句的下一个,一切正常。 这是调度和事件 id(InitStopListen 是新方法):

enum 
    dispidStopListen = 11L,
    dispidInit = 10L,
    dispidTsapiDisconnected = 20L,
    dispidInterceptEnded = 19L,
    dispidInsertEnded = 18L,
    dispidListenEnded = 17L,
    dispidForceReleaseFailed = 16L,
    dispidForceReleseSuccess = 15L,
    dispidInterceptFailed = 14L,
    dispidInterceptSuccess = 13L,
    dispidStopInsertFailed = 12L,
    dispidStopInsertSuccess = 11L,
    dispidInsertFailed = 10L,
    dispidInsertSuccess = 9L,
    dispidStopListenFailed = 8L,
    dispidStopListenSuccess = 7L,
    dispidListenFailed = 6L,
    dispidListenSuccess = 5L,
    dispidLogoutFailed = 4L,
    dispidLogoutSuccess = 3L,
    dispidLoginFailed = 2L,
    dispidLoginSuccess = 1L,
    dispidForceLogout = 9L,
    dispidForceBusy = 8L,
    dispidForceFree = 7L,
    dispidIntercept = 6L,
    dispidForceRelease = 5L,
    dispidInsert = 4L,
    dispidListen = 3L,
    dispidMonitorLogout = 2L,
    dispidMonitorLogon = 1L
;

这是新的 BEGIN_DISPATCH_MAP 部分:

BEGIN_DISPATCH_MAP(CDCMonitorControllerClientCtrl, COleControl)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "MonitorLogon", dispidMonitorLogon, MonitorLogon, VT_I4, VTS_BSTR VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "MonitorLogout", dispidMonitorLogout, MonitorLogout, VT_I4, VTS_BSTR VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "Listen", dispidListen, Listen, VT_I4, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "Insert", dispidInsert, Insert, VT_I4, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "ForceRelease", dispidForceRelease, ForceRelease, VT_I4, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "Intercept", dispidIntercept, Intercept, VT_I4, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "ForceFree", dispidForceFree, ForceFree, VT_I4, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "ForceBusy", dispidForceBusy, ForceBusy, VT_I4, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "ForceLogout", dispidForceLogout, ForceLogout, VT_I4, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "Init", dispidInit, Init, VT_I4, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "StopListen", dispidStopListen, StopListen, VT_I4, VTS_NONE)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "LoginSuccess", dispidLoginSuccess, LoginSuccess, VT_EMPTY, VTS_NONE)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "LoginFailed", dispidLoginFailed, LoginFailed, VT_EMPTY, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "LogoutSuccess", dispidLogoutSuccess, LogoutSuccess, VT_EMPTY, VTS_NONE)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "LogoutFailed", dispidLogoutFailed, LogoutFailed, VT_EMPTY, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "ListenSuccess", dispidListenSuccess, ListenSuccess, VT_EMPTY, VTS_NONE)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "ListenFailed", dispidListenFailed, ListenFailed, VT_EMPTY, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "StopListenSuccess", dispidStopListenSuccess, StopListenSuccess, VT_EMPTY, VTS_NONE)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "StopListenFailed", dispidStopListenFailed, StopListenFailed, VT_EMPTY, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "InsertSuccess", dispidInsertSuccess, InsertSuccess, VT_EMPTY, VTS_NONE)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "InsertFailed", dispidInsertFailed, InsertFailed, VT_EMPTY, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "StopInsertSuccess", dispidStopInsertSuccess, StopInsertSuccess, VT_EMPTY, VTS_NONE)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "StopInsertFailed", dispidStopInsertFailed, StopInsertFailed, VT_EMPTY, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "InterceptSuccess", dispidInterceptSuccess, InterceptSuccess, VT_EMPTY, VTS_NONE)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "InterceptFailed", dispidInterceptFailed, InterceptFailed, VT_EMPTY, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "ForceReleseSuccess", dispidForceReleseSuccess, ForceReleseSuccess, VT_EMPTY, VTS_NONE)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "ForceReleaseFailed", dispidForceReleaseFailed, ForceReleaseFailed, VT_EMPTY, VTS_BSTR)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "ListenEnded", dispidListenEnded, ListenEnded, VT_EMPTY, VTS_NONE)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "InsertEnded", dispidInsertEnded, InsertEnded, VT_EMPTY, VTS_NONE)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "InterceptEnded", dispidInterceptEnded, InterceptEnded, VT_EMPTY, VTS_NONE)
    DISP_FUNCTION_ID(CDCMonitorControllerClientCtrl, "TsapiDisconnected", dispidTsapiDisconnected, TsapiDisconnected, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()

我更改了 InitStopListen 的位置。

【问题讨论】:

您注册新的activex dll了吗? 只是猜测 - 可能 Release 版本是已注册的版本,而您的新方法已添加到位于不同位置的 Debug 版本中。 @PankajM 我已经注册和注销了好几次activex,都没有工作。 @RogerRowland 我只有这个 activex 控件的一个调试版本。在 OLEVIEW 工具中检查此控件时,我可以看到新方法,但它们不起作用。太奇怪了 您没有忘记在 MFC 调度映射中输入一个条目吧? (即在BEGIN_DISPATCH_MAP 部分)? 【参考方案1】:

我刚刚解决了这个问题。

dispatch map 中的语句必须与它们在头文件中的 dispatch ID 出现的顺序相同。

我已经更新了问题的细节,感谢@RogerRowland

【讨论】:

以上是关于无法在 MFC ActiveX 中调用方法的主要内容,如果未能解决你的问题,请参考以下文章

activex 如何调用OnDraw函数

在 MFC 项目中删除对某些 ActiveX 库的依赖的最简单方法是啥?

将 ActiveX 包装到拦截调用(ActiveX 代理包装器)

MFC ActiveX 击键

chrome中怎么用js调用activex控件中的方法

如何使用 MFC 以编程方式更改 ActiveX 控件的属性?