使用Javascript的HTA中的ActiveX事件处理程序 [英] ActiveX event handlers in an HTA using Javascript

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

问题描述

  var wdApp = new Microsoft.Office.Interop.Word.Application (); 
wdApp.DocumentBeforeSave + =(Document doc,ref bool saveAsUI,ref bool cancel)=> {
// do stuff here
};

在VBA / VB6中,我可以使用静态事件处理:

  Dim WithEvents wdApp As Word.Application 

Private Sub wdApp_DocumentBeforeSave(ByVal Doc As Document,SaveAsUI As Boolean,Cancel As Boolean)
'在这里做东西
End Sub

我更喜欢使用动态事件处理。但是,在Javascript中,即使使用静态事件处理,使用 here < a>:

  var wdApp = new ActiveXObject('Word.Application'); 
wdApp.Visible = true;

函数wdApp :: Quit(){
window.alert('Quit');
};

它失败:


0x800a138f - JavaScript运行时错误:对象预期


此外,静态事件处理是VBA / VB6中的一个选项,因为声明可以标记为私人。但是,在Javascript中,变量和处理程序都必须在全局范围内声明。



两个问题:


  1. 如何在HTA环境中使用Javascript处理自动化创建的对象的事件?
    (注意:我知道这是可能的在WSH中使用传递给 CreateObject 的前缀,以及名为 wdApp_Quit 的函数,但是我正在寻找一个HTA解决方案。 )


  2. 如果不污染全球范围,我该怎么做?







有一个较旧的问题 here

解决方案

错误似乎是因为


  1. 在Javascript 函数声明被评估为firs t ,在变量初始化之前。就好像代码是这样写的:

      var wdApp; 
    函数wdApp :: Quit(){...}
    wdApp = new ActiveXObject('Word.Application');


  2. Microsoft JScript解析器将特殊声明解释为附加函数的指令一个事件处理程序。


  3. 但是在声明的时候,处理程序不能被附加到 wdApp引用的对象,因为 wdApp 在这一点上仍然是 undefined 。因此,错误。

解决方案是强制函数声明在 wdApp 被初始化。这可以通过以下三种方式之一完成 1




  1. 由于仅提供了函数声明在函数范围内,将函数声明包含在IIFE中:

      var wdApp = new ActiveXObject('Word.Application') ; 
    (function(){
    function wdApp :: Quit(){
    // do stuff here
    }
    })();


  2. 使用某种字符串创建声明 - >代码机制 - eval setTimeout window.execScript 新功能

      var wdApp = new ActiveXObject('Word.Application'); 
    eval('function wdApp :: Quit(){...}`);


  3. 在当前 SCRIPT 块。 脚本事件文章中的大多数示例通过设置 c $ c $ id $ <$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ >

     < object progid =ordersystem.clsorderid =myorderevents =true/> 
    < script language =jscript>
    function myorder :: onNew(){
    WScript.Echo(new order received from myorder)
    }
    // ...


    但这也可以使用多个 SCRIPT 块:

     < SCRIPT> 
    var wdApp = new ActiveXObject('Word.Application');
    < / SCRIPT>
    < SCRIPT>
    function wdApp :: Quit(){
    // do stuff here
    }
    < / SCRIPT>







在污染全局命名空间方面,只有第三个变体需要 wdApp 在全局命名空间中;另外两个变体可以包裹在一个IIFE中。






1。在技​​术上,IE和HTA有第四种方式,但它涉及非标准HTML而不是非标准Javascript;但是只有在使用HTML OBJECT 标记声明对象时才能使用该对象,而不是使用新的ActiveXObject(...)

 < script for =wdAppevent =Quit> 
// do stuff here
< / script>


In C# I can write event handlers as follows:

var wdApp = new Microsoft.Office.Interop.Word.Application();
wdApp.DocumentBeforeSave += (Document doc, ref bool saveAsUI, ref bool cancel) => {
   //do stuff here
};

In VBA/VB6, I can use static event handling:

Dim WithEvents wdApp As Word.Application

Private Sub wdApp_DocumentBeforeSave(ByVal Doc As Document, SaveAsUI As Boolean, Cancel As Boolean)
    'do stuff here
End Sub

I would prefer to use dynamic event handling. However, in Javascript, even when using static event handling with the syntax described here:

var wdApp = new ActiveXObject('Word.Application');
wdApp.Visible = true;

function wdApp::Quit() {
    window.alert('Quit');
};

it fails:

0x800a138f - JavaScript runtime error: Object expected

Also, static event handling is an option in VBA/VB6, because the declarations can be marked Private. However, in Javascript, both the variable and the handler have to be declared in the global scope.

Two questions:

  1. How can I handle events of Automation-created objects with Javascript in an HTA environment? (Note: I know that it is possible in WSH using a prefix passed to CreateObject, and a function named wdApp_Quit, but I am looking for an HTA solution.)

  2. How can I do this without polluting the global scope?


There is an older question here.

解决方案

The error appears to be because

  1. in Javascript function declarations are evaluated first, before the variable is initialized. It's as if the code was written thus:

    var wdApp;
    function wdApp::Quit() { ... }
    wdApp = new ActiveXObject('Word.Application');
    

  2. The Microsoft JScript parser interprets the specially-named declaration as an instruction to attach the function as an event handler.

  3. But at the point of the declaration, the handler cannot be attached to the object referred to by wdApp, because wdApp at that point is still undefined. Hence, the error.

The solution is to force the function declaration to be evaluated after wdApp is initialized. This can be done in one of three ways1:

  1. Since the function declaration is hoisted only to within the function scope, wrap the function declaration in an IIFE:

    var wdApp = new ActiveXObject('Word.Application');
    (function() {
        function wdApp::Quit() {
            //do stuff here
        }
    })();
    

  2. Create the declaration using some sort of string -> code mechanism -- eval, setTimeout, window.execScript, or new Function:

    var wdApp = new ActiveXObject('Word.Application');
    eval('function wdApp::Quit() { ... }`);
    

  3. Initialize the variable before the current SCRIPT block. Most of the examples in the Scripting Events article do this by setting the id property on some element before the SCRIPT block:

    <object progid="ordersystem.clsorder" id="myorder" events="true"/>
    <script language="jscript">
        function myorder::onNew() {
          WScript.Echo("new order received from myorder")
        }
    //...
    

    but this could also be done using multiple SCRIPT blocks:

    <SCRIPT>
        var wdApp = new ActiveXObject('Word.Application');
    </SCRIPT>
    <SCRIPT>
        function wdApp::Quit() {
            //do stuff here
        }
    </SCRIPT>
    


As far as polluting the global namespace, only the third variant requires wdApp to be in the global namespace; the other two variants can be wrapped in an IIFE.


1. Technically, there is a fourth way under IE and HTAs, but it involves non-standard HTML instead of non-standard Javascript; But it can only be used if the object is declared using the HTML OBJECT tag, not with new ActiveXObject( ... ).

<script for="wdApp" event="Quit">
    //do stuff here
</script>

这篇关于使用Javascript的HTA中的ActiveX事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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