Events 使用JScript的HTA中的ActiveX事件处理程序

Events 使用JScript的HTA中的ActiveX事件处理程序,events,activex,jscript,hta,activexobject,Events,Activex,Jscript,Hta,Activexobject,在C#中,我可以编写如下事件处理程序: 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.Applica

在C#中,我可以编写如下事件处理程序:

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)
    'do stuff here
End Sub
我更喜欢使用动态事件处理。但是,在JScript中,即使使用静态事件处理(语法如下所述):

它失败了:

0x800a138f-JScript运行时错误:应为对象

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

两个问题:

  • 如何在HTA环境中处理使用JScript自动创建对象的事件? (注意:我知道在WSH中可以使用传递给
    CreateObject
    的前缀和名为
    wdApp\u Quit
    的函数,但我正在寻找HTA解决方案。)

  • 如何做到这一点而不污染全球范围?



  • 有一个旧问题。

    错误似乎是因为

  • 在Javascript/JScript中,在初始化变量之前。就好像代码是这样写的:

     var wdApp;
     function wdApp::Quit() { ... }
     wdApp = new ActiveXObject('Word.Application');
    
  • Microsoft JScript解析器将特殊命名的声明(带有
    )解释为将函数作为事件处理程序附加的指令

  • 但是在声明点处,处理程序不能附加到
    wdApp
    引用的对象,因为该点处的
    wdApp
    仍然是
    未定义的。因此,出现了错误

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

  • 由于函数声明仅在函数范围内提升,因此将函数声明包装在IIFE中:

     var wdApp = new ActiveXObject('Word.Application');
     (function() {
         function wdApp::Quit() {
             //do stuff here
         }
     })();
    
  • 使用某种字符串->代码机制创建声明--
    eval
    setTimeout
    和字符串、
    window.execScript
    新函数

     var wdApp = new ActiveXObject('Word.Application');
     eval('function wdApp::Quit() { ... }`);
    
  • 在当前
    脚本
    块之前初始化变量。本文中的大多数示例都是通过在
    脚本
    块之前的某个元素上设置
    id
    属性来实现的:


  • 就全局名称空间而言,只有第三个变量要求
    wdApp
    位于全局名称空间中;其他两个变体可以包装在一个生命中


    一,。从技术上讲,IE和HTAs下有第四种方式,但它涉及非标准HTML而不是非标准Javascript;但是,只有使用HTML
    object
    标记声明对象时,才可以使用它,而不是使用
    newActiveXObject(…)

    
    //在这里做事
    
    错误似乎是因为

  • 在Javascript/JScript中,在初始化变量之前。就好像代码是这样写的:

     var wdApp;
     function wdApp::Quit() { ... }
     wdApp = new ActiveXObject('Word.Application');
    
  • Microsoft JScript解析器将特殊命名的声明(带有
    )解释为将函数作为事件处理程序附加的指令

  • 但是在声明点处,处理程序不能附加到
    wdApp
    引用的对象,因为该点处的
    wdApp
    仍然是
    未定义的。因此,出现了错误

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

  • 由于函数声明仅在函数范围内提升,因此将函数声明包装在IIFE中:

     var wdApp = new ActiveXObject('Word.Application');
     (function() {
         function wdApp::Quit() {
             //do stuff here
         }
     })();
    
  • 使用某种字符串->代码机制创建声明--
    eval
    setTimeout
    和字符串、
    window.execScript
    新函数

     var wdApp = new ActiveXObject('Word.Application');
     eval('function wdApp::Quit() { ... }`);
    
  • 在当前
    脚本
    块之前初始化变量。本文中的大多数示例都是通过在
    脚本
    块之前的某个元素上设置
    id
    属性来实现的:


  • 就全局名称空间而言,只有第三个变量要求
    wdApp
    位于全局名称空间中;其他两个变体可以包装在一个生命中


    一,。从技术上讲,IE和HTAs下有第四种方式,但它涉及非标准HTML而不是非标准Javascript;但是,只有使用HTML
    object
    标记声明对象时,才可以使用它,而不是使用
    newActiveXObject(…)

    
    //在这里做事
    
    我已经看了一眼,但什么也做不到。您提到的WSH解决方案使用“ConnectObject”,我曾尝试在HTA中与WScript.Shell一起使用它,但它不起作用。自2009年以来,MSDN上有一个与您的问题类似的未回答问题,因此看起来可能不可能。应该是objectname::eventname。据我所知,事件连接依赖于WScript对象,它不在mshta.exe主机(运行HTAs)中。但是,mshta可以使用wscript.exe主机调用javascript对象,并获得对wscript对象的访问权。这样的解决方案对您合适吗,还是看起来太难看了?@EduardoPoço事件连接,就我所见,取决于WScript对象——正如我在(编辑的)问题中所指出的,Microsoft对Javascript的扩展允许定义形式为
    varName::eventName(){}的全局函数
    将在全局作用域
    varName
    对象的
    eventName
    事件上调用。此机制在WScript和HTAs中都可用。但是我想要一些不需要全局函数声明和全局变量的东西;与C#机制类似--
    wdApp
    不必是全局变量才能附加/删除处理程序。@EduardoPoço Gordon描述了尝试类似的解决方案但没有成功,但只要我不必声明
    <script for="wdApp" event="Quit">
        //do stuff here
    </script>