2

我有这个连接到我的电脑的实验室设备。它使用特殊的 OCX 文件与设备进行通信(读取、设置参数等)。我从手册中得到了这段代码,似乎可以正常工作。我收到一个消息框,上面写着“放大率 =1272.814 最后一个错误 = API 未初始化”。

<HTML>
<HEAD>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub window_onLoad()
Dim Value
Dim er
call Api1.Initialise("")
call Api1.Get("AP_MAG",Value)
call Api1.GetLastError(er)
call window.alert("Magnification = " + CStr(Value)+"Last error="+er)
call Api1.ClosingControl()
end sub
-->
</SCRIPT>
<TITLE>New Page</TITLE>
</HEAD>
<BODY>
<object classid="CLSID:71BD42C4-EBD3-11D0-AB3A-444553540000" id="Api1">
<PARAM NAME="_Version" VALUE="65536">
<PARAM NAME="_ExtentX" VALUE="2096">
<PARAM NAME="_ExtentY" VALUE="1058">
<PARAM NAME="_StockProps" VALUE="0">
</OBJECT>
</BODY>
</HTML>

因此,因为我在 vbs 中的知识为 0%,在 jscript 中的知识约为 10%,所以我试图用 Javascript 重写相同的东西。而且我还有一些已经用js编写的必要代码。

<script language="JScript">
var Api1=new ActiveXObject("ApiCtrl");
var value;
var er;
Api1.Initialise("");
Api1.Get("AP_MAG",value);
Api1.GetLastError(er);
window.alert("Magnification = " + value+"\n Last error="+er);
Api1.ClosingControl(); 
</script>

.Get不幸的是,我在使用or的.GetLastError方法中遇到类型不匹配var value; var er;错误var value=""; var er="";

这是 API 手册必须说的

长 GetLastError(VARIANT* 错误)

[out] Error 是与最后一个错误的错误代码关联的错误字符串 备注:此调用将返回与最后一个错误关联的 VT_BSTR VARIANT。返回值:如果调用成功,则返回0。如果调用失败,则函数返回错误码。

长获取(LPCTSTR lpszParam,VARIANT* vValue)

[in] lpszParam 是参数的名称,例如“AP_MAG”<br> [in][out] vValue 是参数的值 备注:本次调用将获取指定参数的值并在 vValue 中返回。在 C++ 中,在调用此函数之前,您必须将变体类型 (vValue.vt) 指定为 VT_R4 或 VT_BSTR。如果没有为 vValue 定义变量类型,则默认为模拟参数 (AP_XXXX) 的 VT_R4 和数字参数 (DP_XXXX) 的 VT_BSTR。如果变体类型是模拟参数的 VT_R4,则在变体中返回浮点表示。如果传递了 VT_BSTR 变量,则模拟值将作为带有单位的缩放字符串返回(例如,AP_WD 将返回“= 10mm”)。对于数字参数,VT_R4 变体产生一个状态编号,VT_BSTR 变体产生一个状态字符串(例如,DP_RUNUPSTATE 将返回状态 0 或“Shutdown”或受支持语言中的等效项)。在 C++ 中,如果变体类型指定为 VT_BSTR,则 API 将在内部分配一个 BSTR,调用者必须使用 SDK 调用 ::SysFreeString (vValue.bstrVal) 取消分配该 BSTR

4

1 回答 1

2

欢迎来到 StackOverflow!

好吧,每种语言都是有目的的。那么在浏览器(或WSH)环境中处理ActiveX对象,VBScript是最好的选择,而JavaScript是最差的。

JavaScript 没有所谓的参数。这意味着所有函数参数都按值传递(作为副本)。让我们通过示例向您展示这一点。

' VBScript
Dim X, Y
X = 1
Y = 2
Foo X, Y
MsgBox "Outer X = " & X & ", Y = " & Y
'> Local args: 6, 8
'> Outer X = 1, Y = 8

Sub Foo(ByVal arg1, ByRef arg2)
    arg1 = 6
    arg2 = 8
    MsgBox "Local args: " & arg1 & ", " & arg2
End Sub

默认情况下,在 VBS 中,参数是通过引用传递的,因此ByRef函数参数声明中的前缀是可选的。为了清楚起见,我将其包括在内。

该示例说明的是“by reference”或“out”参数的含义。它的行为类似于返回值,因为它修改了引用的变量。虽然修改“按值”变量在函数范围之外没有任何影响,因为我们修改了该变量的“副本”。

// JavaScript
function foo(arg1) {
    arg1 = 2;
    alert('Local var = ' + arg1);
}
var x = 0;
foo(x);
alert('Outer var = ' + x);

// Local var = 2
// Outer var = 0

现在看看这个线程。看起来有一种使用空对象的部分解决方案。我不确定在哪些情况下会起作用,但可以肯定的是,它是非常有限的 hack。

如果这对您没有帮助,那么看起来是时候使用 VBScript 了。无论如何,从 VBS 开始很容易。这是我接触过的最用户友好的语言。我需要几天,甚至几周才能开始使用其他语言,而在使用 VBS 几个小时后,我就可以自由使用它了。

[编辑]好吧,我做出了更多的努力来回复,一目了然:) 从您遇到的语言限制开始。之后将解释该限制的性质(什么是“输入/输出”参数),最好的方法是通过示例,这就是我所做的。之后,我将向您展示解决 JS 中此限制的唯一解决方法。我们可以认为这是完整的答案吗?

你没有提到你是否测试了这个“空对象技巧”,但是你仍然问我假设你这样做了,它不适用于你的 OCX,对吧?然后,在这种情况下,您只是被迫通过 VBScript 处理您的 OCX,我从一开始就是这样回答的。由于您更喜欢使用 JS,因此您需要在您的解决方案中集成一段 VB 代码。

正如您也注意到的,这种 VBs/Js 集成是一个全新的问题。是的,当然是个好问题,但这是一个新话题。

好的,假设您在下面附加的问题:“为什么它应该将对象作为函数参数传递”,仍然是主要问题的一部分。好吧,正如你所看到的,即使是每天使用 JS 的人(我不是其中之一)也不知道“幕后”会发生什么,即不要指望 JS 引擎在这种情况下做了什么,或者这个作弊方式的答案JS 引擎做一些它不打算做的事情。就个人而言,由于我很少使用 JS 并且不用于此类任务,因此我什至不确定这个技巧是否有效。但是正如 JS 家伙断言的那样(在某些情况下)它有效,那么我们就会信任他们。但仅此而已。如果这种方法失败,那么它不是一个选择。

现在剩下的就是一些功课,你会研究所有可用的 VBs/Js 集成方法,还要测试它们,看看哪一种最适合你的领域,如果碰巧遇到困难,那就来吧——回到论坛,带着新主题和您要解决的具体问题。

为了尽可能提供帮助,我将通过几个参考资料帮助您入门。

这是计划...

1.如果可以在没有 VBs/Js 集成的情况下工作,则使用独立的 .VBS 文件(在 WSH 环境中),否则......

2.如果您在浏览器环境(HTML 或HTA)中工作,那么您可以同时嵌入(VBs/Js),并且您的集成会很简单。

3.或者可以将 VBs/Js 与Windows 脚本文件 (.wsf)集成。

4.或使用允许从 JScript(或向后/相反)内运行 VBScript 的 ScriptControl。

链接:

什么是批量嵌入脚本:

5.其他一些方法(如果你发现了,那我不知道)。

好吧,在所有这些改进之后,我看不到我可以添加更多内容,而且我认为,现在我的答案已经不完整了。如果您同意我的回答,请单击白色大箭头接受。当然,如果您希望从其他用户那里得到更好的回复,您可能仍然需要等待,但请记住,未回答的问题会在一段时间内保持活跃,然后就会关闭。

于 2013-03-07T22:49:40.640 回答