您好,脚本专家!百花齐放,百鸟争鸣,春天来了!

Microsoft 脚本专家

哦,春天来了。 我们的心情也雀跃起来了。在过去的这个冬天,降雨、冰暴、暴风雪和暴风都创下了记录 - 有一次还将一棵大树刮倒,正好落在我们一位脚本专家的后院,距房子仅几英寸,把脚本狗也“吓”得藏到了躺椅后面 - 终于,春天来了,在夏季暖热的西北太平洋持续降雨来临之前,让我们尽情享受一下这清凉的细雨吧。

看着窗外的蒙蒙细雨,我们觉得此时很适合做一些“脚本”探险,深入研究一下 HTML 应用程序 (HTA)。我们说探险,并非虚言。在本文中我们不准备作任何类型的入门介绍;我们假定您已了解什么是 HTA 以及如何创建 HTA。如果您对此并不了解,请访问脚本中心的 HTA 开发人员中心。更具体地说,您需要阅读“HTA 初学者”部分的两篇文章。读完这两篇文章后,您就具备了所需的知识,可以回到这来了。

在本期专栏中,我们将阐述如何创建对话框。不仅如此,我们还将讨论如何在主 HTA 和对话框之间来回传递信息。是的,春天的新鲜气息确实让我们豪情万丈,不是吗?好好享受这个春天吧。

您可能知道,对话框有两种:模式对话框和无模式对话框。二者的差别是,当您打开模式对话框时,无法返回到从中打开该对话框的主窗口,除非关闭该对话框;而当您打开无模式对话框时,则可以在两个窗口之间来回切换。不过,无模式对话框会随主窗口一起关闭。

模式对话框和无模式对话框的创建过程是相同的。唯一不同的是,创建模式对话框时调用的是 ShowModalDialog 函数,而创建无模式对话框时则是 ShowModelessDialog 函数。这两个函数接受的参数也是相同的。首先让我们看一个简单的 HTA,它可以打开一个模式对话框(参见图 1)。

Figure 1 简单的初级对话框

<html> 
<head> 
<title>Modal Example</title>
<HTA:APPLICATION 
  APPLICATIONNAME=”MainModal”>
</head>

<script language=”VBScript”> 
Sub ShowDialog 
 intReturn = _
    ShowModalDialog(“modaldialog.hta”) 
 textbox.Value = intReturn
End Sub
</script> 

<body> 
<button onclick=”ShowDialog”>
 Show Dialog Box</button> <p>
<input type=”text” name=”textbox”>
</body> 
</html>

此处我们创建了一个名为 Modal Example 的 HTA。我们在 HTA 的 <body> 区域添加了两个元素:一个标记为“Show Dialog Box”的按钮和一个名为“textbox”的文本框,如图 2 所示。当您单击该按钮时,会运行 ShowDialog 子例程。

图 2 实际的 HTA 模式对话框

图 2** 实际的 HTA 模式对话框 **

ShowDialog 子例程非常简单。首先,调用 ShowModalDialog 函数,将要显示为模式对话框的 HTA 文件的名称作为参数传递,此处为 modaldialog.hta。(我们假定 modaldialog.hta 与该 HTA 位于同一个文件夹内。如果不是,需要在此填入完整的文件路径。)

我们还要捕获 ShowModalDialog 返回的值 (intReturn)。该值会显示在文本框中。您很快就会看到我们是如何获得此返回值的。需要注意的重要一点是,在调用 ShowModalDialog 后,要等待模式对话框关闭后才会返回值。这意味着必须先关闭对话框,才能将返回的值分配给文本框。

现在,让我们看看 modaldialog.hta,这是我们的调用 HTA 打开的对话框(参见图 3)。在此 HTA 中,我们已创建了两个元素:一个名为“listbox”的列表框和一个标记为“OK”的按钮,如图 4 所示。我们已向列表框中添加了四个项,分别标记为 Option 1、Option 2 等,并给每个项赋予了相应的值 1 至 4。单击 OK 按钮后,CloseWindow 子例程随即运行。

Figure 3 modaldialog.hta

<html> 
<head> 
<title>Modal Dialog Box</title>
<HTA:APPLICATION 
  APPLICATIONNAME=”ModalDialog”>
</head>

<script language=”VBScript”> 
Sub CloseWindow
  window.returnValue = listbox.Value
  window.Close 
End Sub
</script> 

<body> 
<select size=”3” name=”listbox”>
 <option value=”1”>Option 1</option>
 <option value=”2”>Option 2</option>
 <option value=”3”>Option 3</option>
 <option value=”4”>Option 4</option>
</select>
<p>
<input type=”button” id=”idBtn” value=”OK” onclick=”CloseWindow”> 
</body> 
</html>

图 4 表示模式对话框的 HTA

图 4** 表示模式对话框的 HTA **

CloseWindow 子例程非常简单。我们要做的第一件事是读取列表框中选定的项的值,然后将该值赋予 window.returnValue 属性。例如,如果用户选择 Option 2,则值 2 将赋予 window.returnValue。然后我们调用 window.Close 方法关闭该对话框。

这样我们就可以恢复对主 HTA 的控制。回想我们对 ShowModalDialog 所做的调用:

intReturn = _
  ShowModalDialog(“modaldialog.hta”) 

赋予 intReturn 的返回值是我们在对话框 HTA 中赋予 window.returnValue 的值。因此,如果我们在对话框中选择 Option 2,这意味着将值 2 赋予 window.returnValue,则 intReturn 将等于 2,下列代码行会将该值显示给该文本框:

textbox.Value = intReturn

现在,我们已知道如何从对话框获取值,接下来,让我们看看如何将值传递给对话框。这次我们使用无模式对话框(参见图 5),但请记住,模式对话框和无模式对话框的工作方式相同,因此,这一过程也同样适用于模式对话框。

Figure 5 转为无模式对话框

<html>
<head>
<title>Modeless Example</title>
<HTA:APPLICATION 
  APPLICATIONNAME=”ModelessMain”>
</head>

<script language=”VBScript”>
Sub ShowDialog
  intReturn = _
    window.ShowModelessDialog _
    (“modelessdialog.hta”, _
    lstServers.Value, _
    “dialogHeight:400px;dialogWidth:300px”)
End Sub
</script>

<body>
<select size=”1” name=”lstServers”>
 <option value=”server1”>Server1</option>
 <option value=”server2”>Server2</option>
 <option value=”server3”>Server3</option>
 <option value=”server4”>Server4</option>
</select>
<p>
<input type=”button” value=”Retrieve Processes” onclick=”ShowDialog”>
</body>
</html>

图 7 传递到无模式对话框的数据

图 7** 传递到无模式对话框的数据 **

此次我们创建了一个名为“lstServers”的下拉列表框(之所以可以判断它为下拉列表,是因为其大小为 1)。另外还有一个标记为“Retrieve Processes”的按钮。单击该按钮后,ShowDialog 子例程随即运行。ShowDialog 子例程只有一行,即对 window.ShowModelessDialog 函数的调用,如下所示:

intReturn = _
  window.ShowModelessDialog _
  (“modelessdialog.hta”, _
  lstServers.Value, _
  “dialogHeight:400px;dialogWidth:300px”)

我们传递给此函数的第一个参数是要在该对话框中运行的 HTA 的名称,此处为 modelessdialog.hta。第二个参数是我们的列表框的 Value 属性。请记住,Value 属性中包含列表框内所选选项的值。因此,如果用户从列表框中选择 Server2,则 Value 将为 server2。我们要通过这个参数将信息传递给对话框。(如果要传递多个值,则可以将这些值放入此参数作为数组或集合来传递)。

马上我们就能看到该对话框是如何接收此参数中的值的。但首先请注意我们插入的第三个参数:

“dialogHeight:400px;dialogWidth:300px”

该参数包含一个字符串,用于指定对话框的高度和宽度。此处,我们指定高度为 400 像素 (400px),宽度为 300 像素。如我们在模式对话框示例中所见到的,我们可以保留此参数为空,对话框将根据计算机的默认大小显示。

现在,让我们来看 modelessdialog.hta(在图 6 中),看看该对话框如何读入传递给它的值。

Figure 6 modelessdialog.hta

<html>
<head>
<title>Modeless Dialog</title>
<HTA:APPLICATION 
  APPLICATIONNAME=”Processes”>
</head>

<script language=”VBScript”>
Sub window_onLoad
  strComputer = window.dialogArguments
  Set objWMIService = GetObject(“winmgmts:” _
    & “{impersonationLevel=impersonate}!\\” _
    & strComputer & “\root\cimv2”)
  Set colProcesses = objWMIService.ExecQuery_
    (“Select * from Win32_Process”)

  strHTML = “<h1>” & strComputer & “</h1><p>”
  For Each objProcess in colProcesses
    strHTML = strHTML & objProcess.Name & _
       “<br>”
  Next

  DataArea.InnerHTML = strHTML
End Sub
</script>

<body>
<span id=”DataArea”></span>
</body>
</html>

在此 HTA 中,我们仅指定了一个元素 span,整个对话框就位于该元素中。在脚本部分,我们定义了一个 window_onLoad 子例程。该子例程会在 HTA 打开后(在此示例中,通过调用 ShowModelessDialog 来实现)立即运行。看看此子例程的第一行:

strComputer = window.dialogArguments

在这一行中,我们将属性 window.dialogArguments 的内容赋予变量 strComputer。您认为该属性中包含什么?嗯,随着春天的到来,您的思维也必定变得活跃了。说得没错,里面包含的是 ShowModelessDialog 调用的第二个参数中传递的值。如果主窗口中选择的是 Server2,则 strComputer 现在包含的值为 server2。

该子例程的其余代码只检索 strComputer 的所有进程并将这些进程显示在 span 区域中。有关此操作的结果,请参见图 7

值得高兴的是,您现在有一整个夏天可以研究 HTA 对话框了。当然,除非您碰巧居住在马上就是冬天的南半球,如果您的冬天和我们这里的冬天一样经常停电的话,那可能会有点困难。

Microsoft 脚本专家服务于,或者干脆说受雇于 Microsoft。在不玩、不教或不看棒球(以及其他活动)的时候,他们维护 TechNet 脚本中心。您可以光临他们的网站 www.scriptingguys.com 了解更多信息。

© 2008 Microsoft Corporation 与 CMP Media, LLC.保留所有权利;不得对全文或部分内容进行复制.