none
ATL COM 关于 枚举和索引的问题。 RRS feed

  • 问题

  • 我定义了一个接口如下:

    [
     object,
     uuid(3496710F-440F-4E42-9BA0-7FA0E927AE4D),
     dual,
     nonextensible,
     custom(B64784EB-D8D4-4d9b-9ACD-0E30806426F7,""),
     pointer_default(unique)
    ]
    interface IUDTS : IDispatch{
     [propget, id(DISPID_NEWENUM), hidden] HRESULT _NewEnum([out, retval] IUnknown** ppUnk);
     [propget, id(1)] HRESULT Count([out, retval] LONG* pcount);
     [propget, custom(CD2BC5C9-F452-4326-B714-F9C539D4DA58, 0), id(DISPID_VALUE)] HRESULT Item([in] LONG index, [out, retval] IUDT ** ppVal);
    };

    期望该接口是可枚举的。

    对于 C#,VBS 使用 For Each 来枚举是正确的。

    但是 我使用 JavaScript 的 For in 来枚举是不正确的,获取的接口是正确的,使用 For 循环可以获得每一个元素。

    但是使用 For in 就枚举不到。

    可以确定 For in 语句根本就没有执行 IUDTS 接口的 DISPID_NEWENUM 函数。

    同时,可以确定枚举 COM 组件是正确的,我在同一个网页里,执行了一样的 VBS 和 Javascript 脚本。

    所有的输出都是一致的,VBS 的 For Each 输出正确,而 For in 没有任何输出,好像不是可枚举的那样。

    VBScript 语法如下:

    <script type="text/vbscript" language="vbscript">
      document.write "<br/>vbscript"
      Set us = pi.MyUDTS
      Dim count
      count = us.Count
      document.write "<br/>us.Count = " & count
      For i = 1 To count
       document.write "<br/>us[" & i & "].Name = "
       document.write us(i).Name
      Next

      For Each u in us
       document.write "<br/>u.Name = "
       document.write u.Name
      Next

     </script>

     

    JavsScript 语法如下:

     <script type="text/javascript" language="javascript">
      document.write("<br/>javascript");
      var us = pI.MyUDTS;
      var count = us.Count;
      document.write("<BR/>us.Count = " + count);
      for (var i = 0; i < count; ++i) {
       document.write("<BR/>us[" + i + "].Name = ");
       document.write(us(i + 1).Name);
      }
      for (var u in us) {
       document.write("<BR/>u.Name = ");
    //   document.write(us[u].Name);
       document.write(us[u]);
      }

     </script>

    请教一下,是 JavsScript 的语法错误,还是其他的什么问题?

     

    还有一个问题就是,我在 VB 或 VBS 里索引数组的时候,使用的是() 来索引,这和缺省函数没有区别,所以在 VBS 里没有区别。

    而我在 C# 里面使用的[] 来索引,这基于 DISPID_VALUE(0),

    可以我在 JavaScript 里面只能使用() 来索引的,这同样是基于 DISPID_VALUE(0)。

    可是我想使用[] 来索引,

    也就是说我想把语句

     document.write(us(i + 1).Name);

    以下面的方式索引。

    document.write(us[i + 1].Name);

    我尝试了 DISPID_EVALUATE(-5),可惜没有任何反应。

    请教一下,在 JavaScript 里面,如果一个接口需要支持[]索引,请问该怎么做?

     

    我对于 Javascript 语法不是很熟悉,不知道 Javascript 的 For in 和 [] 是否是我想的这样。

     

     


    我也有自己的签名档哦!

    2011年11月4日 8:36

答案

  • function ShowDriveList(){
       var fso, s, n, e, x;                     //Declare variables.
       fso = new ActiveXObject("Scripting.FileSystemObject");
       e = new Enumerator(fso.Drives);          //Create Enumerator on Drives.
       s = "";
       for (;!e.atEnd();e.moveNext())           //Enumerate drives collection.
          {
             x = e.item();
             s = s + x.DriveLetter;
             s += " - ";
             if (x.DriveType == 3)              //See if network drive.
                n = x.ShareName;                //Get share name
             else if (x.IsReady)                //See if drive is ready.
                n = x.VolumeName;               //Get volume name.
             else
                n = "[Drive not ready]";
             s +=  n + "<br>";
          }
       return(s);                               //Return active drive list.
    }
    2011年11月8日 5:19
  • function ShowDriveList(){
       var fso, s, n, e, x;                     //Declare variables.
       fso = new ActiveXObject("Scripting.FileSystemObject");
       e = new Enumerator(fso.Drives);          //Create Enumerator on Drives.
       s = "";
       for (;!e.atEnd();e.moveNext())           //Enumerate drives collection.
          {
             x = e.item();
             s = s + x.DriveLetter;
             s += " - ";
             if (x.DriveType == 3)              //See if network drive.
                n = x.ShareName;                //Get share name
             else if (x.IsReady)                //See if drive is ready.
                n = x.VolumeName;               //Get volume name.
             else
                n = "[Drive not ready]";
             s +=  n + "<br>";
          }
       return(s);                               //Return active drive list.
    }


      for (var e = new Enumerator(us); !e.atEnd(); e.moveNext()) {
       document.write("<br/>u.Name = ");
       document.write(e.item().Name);
      }

    谢谢,终于看到在 Javascript 里面呼叫到 _NewEnum 方法了。

    Enumerator 对象提供了访问集合的任何成员的方法,其操作与 VBScript 中的 For...Each 语句相似。


    我也有自己的签名档哦!
    2011年11月8日 6:44

全部回复

  • 请高手指点一二。

    就是 Javascript 的 for in 和 _IEnumXXXX 有没有对应关系。

     

    因为,我对 Javascript 的语法不是很熟,

    我想知道,如果我在我的 SDK 文档里说某个接口支持枚举,那么 Javascript 在枚举该接口的数据项的时候,怎么去枚举。


    我也有自己的签名档哦!
    2011年11月8日 1:27
  • function ShowDriveList(){
       var fso, s, n, e, x;                     //Declare variables.
       fso = new ActiveXObject("Scripting.FileSystemObject");
       e = new Enumerator(fso.Drives);          //Create Enumerator on Drives.
       s = "";
       for (;!e.atEnd();e.moveNext())           //Enumerate drives collection.
          {
             x = e.item();
             s = s + x.DriveLetter;
             s += " - ";
             if (x.DriveType == 3)              //See if network drive.
                n = x.ShareName;                //Get share name
             else if (x.IsReady)                //See if drive is ready.
                n = x.VolumeName;               //Get volume name.
             else
                n = "[Drive not ready]";
             s +=  n + "<br>";
          }
       return(s);                               //Return active drive list.
    }
    2011年11月8日 5:19
  • function ShowDriveList(){
       var fso, s, n, e, x;                     //Declare variables.
       fso = new ActiveXObject("Scripting.FileSystemObject");
       e = new Enumerator(fso.Drives);          //Create Enumerator on Drives.
       s = "";
       for (;!e.atEnd();e.moveNext())           //Enumerate drives collection.
          {
             x = e.item();
             s = s + x.DriveLetter;
             s += " - ";
             if (x.DriveType == 3)              //See if network drive.
                n = x.ShareName;                //Get share name
             else if (x.IsReady)                //See if drive is ready.
                n = x.VolumeName;               //Get volume name.
             else
                n = "[Drive not ready]";
             s +=  n + "<br>";
          }
       return(s);                               //Return active drive list.
    }


      for (var e = new Enumerator(us); !e.atEnd(); e.moveNext()) {
       document.write("<br/>u.Name = ");
       document.write(e.item().Name);
      }

    谢谢,终于看到在 Javascript 里面呼叫到 _NewEnum 方法了。

    Enumerator 对象提供了访问集合的任何成员的方法,其操作与 VBScript 中的 For...Each 语句相似。


    我也有自己的签名档哦!
    2011年11月8日 6:44