使用 Windows 公共控件在 JScript 和 VBScript 中创建 GUI






4.18/5 (7投票s)
本文介绍了如何使用 Windows 公共控件在 VBScript 和 JScript 中编写 GUI 应用程序。
介绍
您可能想使用 VBScript 或 JScript 编写一个使用 Windows 公共控件的 GUI 应用程序。我相信您不想阅读大量的源代码来查找两行有用的代码。本文仅仅是一个入门,一个起点。
首先,VBScript 或 JScript GUI 应用程序不是真正的 Win32 API。这种 GUI 是 HTA 或用于 Internet Explorer 浏览器的 HTML。通过使用其中任何一个,您可以利用易于使用的 Windows 功能。标准窗口控件,如按钮、编辑框、组合框,在使用 HTA 时不需要任何特殊设置。但是 Windows 公共控件,如 TreeView
、ListView
,可以作为 ActiveX 控件使用。
这可能看起来有点像 Web 设计。但实际上这是一种混合编程风格。
如果您需要纯粹的 Win32 API,您可能需要一个用 C/C++ 或任何其他语言编写的脚本化 WinAPI 包装器。但是对于许多 Windows 应用程序来说,HTA 和用于 Internet Explorer 的 HTML 已经足够了。您可能会惊讶于您可以用 HTA 或用于 Internet Explorer 的 HTML 编写多少种应用程序。
背景
这段代码尽可能简明地解释了使用标准 ActiveX 控件作为 Windows 公共控件包装器的主要思想。它可以与客户端脚本在 HTML 页面中使用,或者作为独立的 HTA 应用程序。它非常适合在办公室使用,那里的策略可能禁止使用某些第三方编程语言、浏览器、编译器、组件、非 Windows 操作系统,或者所有这些。您无需安装任何东西,这些应用程序就可以工作。要使用 HTA 应用程序,您需要将脚本复制到您希望使用它们的每台计算机上,或者将它们放在本地网络上的共享文件夹中。或者,您可以将应用程序放在 Web 服务器上,用户将通过 Internet Explorer 浏览器使用它们。
此代码无法使用
此代码与非 Microsoft Windows 操作系统不兼容。此代码与非 Microsoft Internet Explorer 浏览器不兼容。一大优势是具备一定的 ActiveX 基础知识。但并非必需。您可以在不知道 ActiveX 的情况下使用它。
一些技术背景
我无意写一份完整的 ActiveX 控件指南。所有成员函数、属性、事件和传递的参数,您都可以通过 Office VBA、OleView 等工具找到。在 Office VBA 中,您需要通过查找并在引用列表中勾选某个版本的 Microsoft Windows Common Controls 来添加引用,或者通过浏览 mscomctl.ocx 来添加。之后,您将在对象浏览器中看到所有信息。如果您使用 OleView 来完成此操作,我相信您知道如何找到这些对象。
现在,为不熟悉 ActiveX 的人提供一些信息。ActiveX 对象通过 ClassID
(clsid
)标识。这是一个 GUID,看起来像一个由 32 个十六进制数字组成的庞然大物,对人类来说毫无意义。一个更易于人类阅读的标识符是 ProgID
。如果您想使用其他版本,或者 Windows 中存在其他版本的控件,您可能需要使用与我的示例不同的 clsid
。在这种情况下,您需要从类型库中查找 clsid
。如果您没有 OleView,您将无法在 Windows 注册表中找到它们。例如,我使用 TreeView
控件。TreeView
控件的 ProgID
是 MSComctlLib.TreeCtrl
。您必须在 HKEY_CLASSES_ROOT
下的注册表中找到此 ProgID
。
HKEY_CLASSES_ROOT\MSComctlLib.TreeCtrl
或某个其他版本
HKEY_CLASSES_ROOT\MSComctlLib.TreeCtrl.2
在这里,您会找到子键 CLSID
的默认值。这正是您需要的 CLSID
。在我的计算机上,它是 {C74190B6-8589-11D1-B16A-00C0F0283628}。只需删除括号并复制/粘贴到您的代码中。
使用 TreeView
请参阅存档 TreeView.zip。
要使用 TreeView
,您需要插入 TreeView
ActiveX 对象
<object id="ITreeView" classid="clsid:C74190B6-8589-11D1-B16A-00C0F0283628"
height="200" width="200" >
......
</object>
要操作该对象,您需要获取该对象。
在 VBScript 中,您这样做
set treeObj = document.getElementById("ITreeView").object
在 JScript 中也是同样的操作
treeObj = document.getElementById('ITreeView').object;
从 ActiveX 的角度来看,这段代码获取了 ActiveX 对象的 IDispatch
。
让我们用 VBS 添加节点/项到 treeview
set x = treeObj.Nodes.Add(null, TreeRelationship.tvwFirst, "key 1", "The VBS Item 1")
set x1 = treeObj.Nodes.Add(x, TreeRelationship.tvwChild, "key 1.1", "The VBS Item 1.1")
...
JS 中也是一样
x = treeObj.Nodes.Add(null, TreeRelationship.tvwFirst, "key 1", "The JS Item 1");
x1 = treeObj.Nodes.Add(x, TreeRelationship.tvwChild, "key 1.1", "The JS Item 1.1");
函数 add(...)
返回添加的节点。第一个参数应为一个相关的树节点,例如父节点。第二个参数指示节点的添加方式。第三个参数是一个必须唯一的键。
在 VBScript 和 JScript 中使用 ImageList 与 TreeView
请参阅存档 TreeViewAndImages.zip。
要为树节点使用图像/图标,您需要一个图像列表
treeObj.ImageList = imgList
现在,添加一个带有图像的节点只是小菜一碟
set x = treeObj.Nodes.Add(null, TreeRelationship.tvwFirst,
"key 1", "VBS Tree Item 1", "PictureNumber0")
唯一的区别是多了一个参数。最后一个参数。此参数指示 imgList
中图片的 ID。
JScript 中也是一样
x = treeObj.Nodes.Add(null, TreeRelationship.tvwFirst,
"key 1", "salut 1", "PictureNumber0");
imgList
是另一个 ActiveX 对象。可以这样实例化
VBS
set imgList = CreateObject("MSComctlLib.ImageListCtrl.2")
JScript
var imgList = new ActiveXObject("MSComctlLib.ImageListCtrl.2");
在 VBScript 中加载图像如下:
imgList.ListImages.Clear()
imgList.ListImages.add 1, "PictureNumber0", LoadPicture("Icon\Number0.ico")
imgList.ListImages.add 2, "PictureNumber1", LoadPicture("Icon\Number1.ico")
函数 LoadPicture
返回一个 IPictureDisp
。此函数在标准 WSH VBScript 中可用,但在 WSH JScript 中不可用。要在 JScript 中使用它,我们可以编写一个简短且非常简单的 VBScript 包装器,请参阅 TreeViewAndImages.zip 中的 VBScriptWrapper.wsc。
首先,在命令行中使用 regsvr32
注册此包装器:
regsvr32 VBScriptWrapper.wsc
现在我们可以在 JScript 程序中使用 LoadPicture
函数了
var vbsw = new ActiveXObject("IFVBScript.Wrapper");
现在加载图片
imgList.ListImages.Clear();
imgList.ListImages.add(1, "PictureNumber0", vbsw.LoadPicture("Icon\\Number0.ico"));
imgList.ListImages.add(2, "PictureNumber1", vbsw.LoadPicture("Icon\\Number1.ico"));
使用此包装器的另一种方法是将其声明为 HTML <object>
<object id="VBScriptFunctionsWrapper"
classid="clsid:02F3817F-4555-4e51-A741-D87662FA7987" > </object>
在 JScript 中访问它并加载图像
var vbobj = document.getElementById('VBScriptFunctionsWrapper').object;
imgList.ListImages.Clear();
imgList.ListImages.add(1, "PictureNumber0", vbobj.LoadPicture("Icon\\Number0.ico"));
imgList.ListImages.add(2, "PictureNumber1", vbobj.LoadPicture("Icon\\Number1.ico"));
如果您知道在 JScript 中 LoadPicture
的更好方法,请告诉我。
事件
为了响应用户输入,您可能需要处理事件。让我们处理单击某个项以及鼠标在树上移动的事件。请参阅 TreeViewWithEvents.zip。
在 VB 中,您将以标准方式处理 ID 为 SomeObject
的对象的事件 SomeEvent
。您只需添加一个名为 SomeObject_SomeEvent
的过程,然后就完成了:
sub MyTreeView_MouseMove(Button, Shift, x, y)
'processing mouse move here
end sub
sub MyTreeView_NodeClick(node)
'processing the node click here
end sub
在 JavaScript 中,这也很标准。您的添加应该看起来像 SomeObject::SomeEvent
。
function MyTreeView::MouseMove(Button, Shift, x, y)
{
//process the mouse move here
}
function MyTreeView::NodeClick(node)
{
//process your node click here
}
要查找坐标 x,y
下方的项,使用函数 HitTest
。但 HitTest
函数不接受您在 MouseMove
事件中获得的像素坐标。在将坐标传递给 HitTest
之前,需要将其从像素转换为 twips。在我的计算机上,我使用 14.4 进行转换。
VB:
set node = treeObj.HitTest(x * 14.4, y * 14.4)
JScript
node = treeObj.HitTest(x * 14.4, y * 14.4);
关注点
本文尚未完成,将继续更新。