【问题标题】:Handling ATL/ActiveX events from within JavaScript在 JavaScript 中处理 ATL/ActiveX 事件
【发布时间】:2011-04-04 13:01:47
【问题描述】:

我有一个 ATL ActiveX 控件,它引发三个需要在 IE/JavaScript 中处理的事件(已连接、已验证、已断开)。据我所知,我做的一切都是正确的,特别是:

(1) 我已经告诉 ATL 实现 IProviderClassInfo2 接口,如 here 所述。

(2) 我已经按照here 的指示在我的 ATL 项目中实现了连接点。我现在有一个 CProxy_IMyControlEvents 类,具有适当的 Fire_Authenticated()、Fire_Connected() 和 Fire_Disconnected() 实现。它们或多或少看起来像这样:

template<class T>
class CProxy_IVncServerControlEvents :
 public ATL::IConnectionPointImpl<T, &__uuidof(_IVncServerControlEvents)>
{
public:
HRESULT Fire_Connected()
 {
  HRESULT hr = S_OK;
  T * pThis = static_cast<T *>(this);
  int cConnections = m_vec.GetSize();

  for (int iConnection = 0; iConnection < cConnections; iConnection++)
  {
   pThis->Lock();
   CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
   pThis->Unlock();

   IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

   if (pConnection)
   {
    CComVariant varResult;

    DISPPARAMS params = { NULL, NULL, 0, 0 };
    hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD,  &params, &varResult, NULL, NULL);
   }
  }
  return hr;
 }
};

(3) 我在代码中的适当位置(在主 UI 线程上)调用 Fire_Connected() 等,并且调试器确认它们正在触发。

(4) 我在 HTML 页面中实例化生成的控件,并且能够在其上调用方法。这些方法做他们应该做的事并成功返回。

<object id="MyControl" classid="CLSID:42832F4C-3480-4450-A6B5-156B2EFC408F" codebase="http://localhost:51150/Resources/MyControlInstaller.CAB" />

<script language="javascript">
var myControl = document.getElementById("MyControl");
myControl.connect();
</script>

(5) 我将事件连接到 JavaScript 函数处理程序。这似乎是我遇到麻烦的地方。我已经看到了三种不同的参考方法,但它们似乎都不适合我。

<!-- Method #1 -->
<script language="javascript">
myControl.attachEvent('Connected', onConnected);
myControl.attachEvent('Disconnected', onDisconnected);
myControl.attachEvent('Authenticated', onAuthenticated);
</script>

<!-- Method #2 -->
<script language="javascript">
myControl.Connected = onConnected;
myControl.Disconnected = onDisconnected;
myControl.Authenticated = onAuthenticated;
</script>

<!-- Method #3 -->
<script for="MyControl" language="javascript">
function MyControl::Connected()
{
    onConnected();
}

function MyControl::Disconnected()
{
    onDisconnected();
}

function MyControl::Authenticated()
{
    onAuthenticated();
}
</script>

我已经准备好在 Internet 上找到的有关如何执行此操作的所有内容,而且我似乎没有遗漏任何内容。所以我一定是在做一些愚蠢的事情。关于我可能做错了什么或如何解决问题的任何建议?

【问题讨论】:

    标签: c++ events activex atl


    【解决方案1】:

    我通过查看 VS2010 附带的 Circ 示例项目找到了答案。事实证明(至少在我的情况下)ATL 事件向导没有更新调度接口的 IDL。一旦我从这里更新了 IDL 文件的 dispinterface 部分,生活就变得美好了:

    dispinterface _IMyControlEvents
    {
        properties:
        methods:
    };
    

    到这里:

    dispinterface _IMyControlEvents
    {
        properties:
        methods:
            [id(1)] void Connected();
            [id(2)] void Disconnected();
            [id(3)] void Authenticated();
    };
    

    一旦我这样做了,我就能让各种不同的事件处理语法发挥作用。

    【讨论】:

    • 在 JS 事件中处理来自未通过 标签集成到 DOM 的 COM 对象的热点?比如这是JS从windows.external收到的对象等等……
    【解决方案2】:

    首先,我从 MSDN 看到的所有示例都使用“JScript”作为语言,而不是“javascript”,但我不知道这是否有所不同(也许两者都被接受,但从技术上讲,MS 的 ECMA 实现是 JScript ,我相信)。

    作为方法 3 的变体,可以尝试为脚本指定 EVENT 属性:

    <script for="MyControl" EVENT="Connected()" language="JScript">
      onConnected();
    </script>
    
    <script for="MyControl" EVENT="Disconnected()" language="JScript">
      onDisconnected();
    </script>
    
    <script for="MyControl" EVENT="Authenticated()" language="JScript">
      onAuthenticated();
    </script>
    

    【讨论】:

    • 感谢您的建议。不幸的是,我尝试了它们,但事件仍然没有触发。继续环顾四周……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    • 2013-09-16
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 2012-02-28
    相关资源
    最近更新 更多