积极答复者
ATL COM 关于 枚举和索引的问题。

问题
-
我定义了一个接口如下:
[
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
NextFor 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:46
答案
-
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日 6:44
-
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
全部回复
-
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日 6:44
-
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