如何使用VbScript创建选项对话框?

时间:2022-03-09 02:08:47

I have a third party application that invokes a vsbscript file for certain operations. I would like to put up a user prompt with a choice of options, either a drop down list or checkbox or some such. However, all I can find is the input box option.

我有一个第三方应用程序,它为某些操作调用vsbscript文件。我想提出一个用户提示,可以选择一个选项,下拉列表或复选框或其他选项。但是,我能找到的只是输入框选项。

I don't think HTAs are an option in my case (unless there is a way to call them from a .vbs file?)

在我的情况下,我认为HTA不是一个选项(除非有办法从.vbs文件中调用它们吗?)

My other thought was some sort of ActiveX control, but I can't locate a built-in one that would be available by default on WindowsXP/Vista.

我的另一个想法是某种ActiveX控件,但我无法找到一个在WindowsXP / Vista上默认可用的内置控件。

Anybody have any ideas on how I could accomplish this?

有人对我如何做到这一点有任何想法?

7 个解决方案

#1


The simple answer is, you really can't. Tmdean's solution is the only way I can think of either. That said, you can spruce up the input box so it doesn't look horrible. Give this a run, I don't think it's an epic fail:

简单的答案是,你真的不能。 Tmdean的解决方案是我能想到的唯一方法。也就是说,你可以修改输入框,这样它看起来并不可怕。给这个跑步,我不认为这是一个史诗般的失败:

Dim bullet
Dim response
bullet = Chr(10) & "   " & Chr(149) & " "
Do
    response = InputBox("Please enter the number that corresponds to your selection:" & Chr(10) & bullet & "1.) Apple" & bullet & "2.) Bannana" & bullet & "3.) Pear" & Chr(10), "Select Thing")
    If response = "" Then WScript.Quit  'Detect Cancel
    If IsNumeric(response) Then Exit Do 'Detect value response.
    MsgBox "You must enter a numeric value.", 48, "Invalid Entry"
Loop
MsgBox "The user chose :" & response, 64, "Yay!"

#2


If you would like to use an hta for this it can be done like this.
The VBScript:

如果您想使用hta,可以这样做。 VBScript:


Set WshShell = CreateObject("WScript.Shell")
'Run the hta.
WshShell.Run "Test.hta", 1, true
'Display the results.
MsgBox "Return Value = " & getReturn
Set WshShell = Nothing

Function getReturn
'Read the registry entry created by the hta.
On Error Resume Next
     Set WshShell = CreateObject("WScript.Shell")
    getReturn = WshShell.RegRead("HKEY_CURRENT_USER\Volatile Environment\MsgResp")
    If ERR.Number  0 Then
        'If the value does not exist return -1
         getReturn = -1
    Else
        'Otherwise return the value in the registry & delete the temperary entry.
        WshShell.RegDelete "HKEY_CURRENT_USER\Volatile Environment\MsgResp"
    End if
    Set WshShell = Nothing
End Function

Then design the hta as desired, and include the following methods

然后根据需要设计hta,并包括以下方法



'Call this when the OK button is clicked.
Sub OK_Click
    For Each objradiobutton In Opt
         If objradiobutton.Checked Then
              WriteResponse objradiobutton.Value
        End If
    Next
    window.Close
End Sub

'Call this when the Cancel button is clicked.
Sub Cancel_Click
     WriteResponse("CANCEL")
     window.Close
End Sub

'Write the response to the registry
Sub WriteResponse(strValue)
    Set WshShell = CreateObject("WScript.Shell")
    WshShell.RegWrite "HKEY_CURRENT_USER\Volatile Environment\MsgResp", strValue
     Set WshShell = Nothing
End Sub

I used a group of radio buttons named "Opt" to make a choice, but you could use any controls you would like.

Because hta's cannot return values, this will create a temperary registry entry. If you are not comforatable messing with the registry, you could also write the result to a temperary text file.

This approach is nice because you can design the hta any way you like, rather than using the supplied inputbox and choosing numbers (thats so DOS).

This could also be nice if you expanded the hta to create itself based on arguments passed to it, like passing in a title, a message to display, an array of options, a set of buttons. That way you could use the same hta any time you needed to get input from the user.

我使用一组名为“Opt”的单选按钮进行选择,但您可以使用任何您想要的控件。因为hta不能返回值,所以这将创建一个临时注册表项。如果您不熟悉注册表,您也可以将结果写入文本文本文件。这种方法很好,因为您可以按照自己喜欢的方式设计hta,而不是使用提供的输入框并选择数字(这就是DOS)。如果你扩展hta以根据传递给它的参数创建自己,例如传入标题,要显示的消息,选项数组,一组按钮,这也可能很好。这样,只要您需要从用户那里获得输入,就可以使用相同的hta。

#3


You can use DialogLib to create forms with dropdowns and checkboxes. DialogLib is still in it's ealy stages, but is's allready quite usefull: http://www.soren.schimkat.dk/Blog/?p=189

您可以使用DialogLib创建带有下拉列表和复选框的表单。 DialogLib仍处于ealy阶段,但已经非常有用了:http://www.soren.schimkat.dk/Blog/?p = 189

#4


Try WshShell.Popup. Depending upon your data that may work for you...

试试WshShell.Popup。取决于您可能适合您的数据......

Otherwise you could investigate PowerShell.

否则你可以调查PowerShell。

#5


One option is to script Internet Explorer. You can use VBScript to launch IE and load a local HTML file, and attach a VBScript sub to a form's submit button (or any other JavaScript events), which can then close the IE window as part of its execution.

一种选择是编写Internet Explorer脚本。您可以使用VBScript启动IE并加载本地HTML文件,并将VBScript子附加到表单的提交按钮(或任何其他JavaScript事件),然后可以关闭IE窗口作为其执行的一部分。

#6


You can launch an HTA from a VBScript.

您可以从VBScript启动HTA。

Set shell = CreateObject("WScript.Shell")
shell.Run "Test.hta"

EDIT

Since you have full control of the VBScript, could you make the 3rd party VBScript simply call your HTA? You could put the UI and whatever processing code inside of the HTA.

由于您可以完全控制VBScript,您是否可以让第三方VBScript简单地调用您的HTA?您可以将UI和任何处理代码放在HTA中。

#7


As an example of @TmDean's suggestion, there's this class that I sometimes use which scripts IE (well, it scripted IE6; I haven't tried the more recent incarnations.)

作为@TmDean建议的一个例子,我有时会使用哪个脚本IE(好吧,它编写了IE6脚本;我没有尝试过最近的版本。)

class IEDisplay
    '~ Based on original work by Tony Hinkle, tonyhinkle@yahoo.com

    private TEMPORARY_FOLDER

    private objShell
    private objIE
    private objFSO
    private objFolder
    private strName
    private streamOut
    private objDIV

    private numHeight
    private numWidth
    private numTop
    private numLeft

    private sub Class_Initialize()
    Dim strComputer
    Dim objWMIService
    Dim colItems
    Dim objItem
    Dim arrMonitors( 10, 1 )
    Dim numMonitorCount

    Set objShell = WScript.CreateObject("WScript.Shell")
    Set objIE = CreateObject("InternetExplorer.Application")

    strComputer = "."
    Set objWMIService = GetObject( "winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery( "Select  * from Win32_DesktopMonitor")

    numMonitorCount = 0 
    For Each objItem in colItems
        arrMonitors( numMonitorCount, 0 ) = objItem.ScreenHeight
        arrMonitors( numMonitorCount, 1 ) = objItem.ScreenWidth
        numMonitorCount = numMonitorCount + 1
    Next

    numHeight = arrMonitors( 0, 0 )
    numWidth = arrMonitors( 0, 1 )

    Set objFSO = CreateObject("Scripting.FileSystemObject")
    TEMPORARY_FOLDER = 2
    set objFolder = objFSO.GetSpecialFolder( TEMPORARY_FOLDER )
    strName = objFSO.BuildPath( objFolder, objFSO.GetTempName ) & ".html"
    WriteFileU strName, Join( Array( "<HTML><HEAD><TITLE>Information</TITLE></HEAD>", _
                     "<BODY SCROLL='NO'><CENTER><FONT FACE='arial black'> <HR COLOR='BLACK'>", _
                     "<DIV id='MakeMeAnObject'></DIV>", _
                     "<HR COLOR='BLACK'></FONT></CENTER></BODY></HTML>" ), vbCRLF ), WF_CREATE        
    numTop = 0
    numLeft = 0
    end sub

    Sub Init( strPosition )
    'NW, N, NE, W, CENTRE, E, SW, S, SE
    Select Case strPosition
    Case "NW"
        numTop = 0
        numLeft = 0
    Case "N"
        numTop = 0
        numLeft = ( numWidth / 2 ) - 250
    Case "NE"
        numTop = 0
        numLeft = numWidth - 500
    Case "W"
        numTop = ( numHeight / 2 ) - 55
        numLeft = 0
    Case "CENTRE"
        numTop = ( numHeight / 2 ) - 55
        numLeft = ( numWidth / 2 ) - 250
    Case "E"
        numTop = ( numHeight / 2 ) - 55
        numLeft = numWidth - 500
    Case "SW"
        numTop = numHeight - 110
        numLeft = 0
    Case "S"
        numTop = numHeight - 110
        numLeft = ( numWidth / 2 ) - 250
    Case "SE"
        numTop = numHeight - 110
        numLeft = numWidth - 500
    Case Else
        numTop = 0
        numLeft = 0
    End Select

    SetupIE( strName )
    Set objDIV = objIE.Document.All("MakeMeAnObject")
    end sub

    private sub Class_Terminate()
    'Close IE and delete the file
    objIE.Quit
    '~ optionally you may want to get rid of the temp file
    end sub

    public sub Display( strMsg, numMillisec )
    objDIV.InnerHTML = strMsg
    WScript.Sleep numMillisec
    end sub

    Private Sub SetupIE(File2Load)
     objIE.Navigate File2Load
     objIE.ToolBar = False
     objIE.StatusBar = False
     objIE.Resizable = False

     Do
     Loop While objIE.Busy

     objIE.Width = 500
     objIE.Height = 110
     objIE.Left = numLeft
     objIE.Top = numTop
     objIE.Visible = True
     objShell.AppActivate("Microsoft Internet Explorer")
    End Sub

end class

here is the missing (from the original posting) WriteFileU function

这里是缺少的(来自原始帖子)WriteFileU函数

Const WF_APPEND = 1
Const WF_CREATE = 2

Const WF_FOR_APPENDING = 8
Const WF_FOR_WRITING = 2
Const WF_CREATE_NONEXISTING = True

Const CONST_READ = 1, CONST_WRITE = 2, CONST_APPEND = 8

Const AS_SYSTEMDEFAULT = -2, AS_UNICODE = -1, AS_ASCII = 0

Sub WriteFileU( sFilename, sContents, nMode )
  Dim oStream
  If nMode = WF_APPEND Then
    Set oStream = oFSO.OpenTextFile( sFilename, WF_FOR_APPENDING, WF_CREATE_NONEXISTING, AS_UNICODE )
  ElseIf nMode = WF_CREATE Then
    Set oStream = oFSO.OpenTextFile( sFilename, WF_FOR_WRITING, WF_CREATE_NONEXISTING, AS_UNICODE )
  Else
    STOP
  End If

  oStream.Write sContents
  oStream.Close
  Set oStream = Nothing
End Sub

and then as an example of it's use

然后作为它的一个例子

set i = new IEDisplay 
a = array("NW", "N", "NE", "W", "CENTRE", "E", "SW","S","SE")
for each aa in a
    i.init aa
    i.display "Here in " & aa & " of screen", 1000
next

Now that's not immediately useful (especially are there are a pile of calls to my own utility routines in there) but it gives a framework. By modifying what HTML is stored, you could add support for listboxes etc.

现在这不是立即有用的(特别是在那里有一堆对我自己的实用程序例程的调用)但是它提供了一个框架。通过修改HTML的存储,您可以添加对列表框等的支持。

#1


The simple answer is, you really can't. Tmdean's solution is the only way I can think of either. That said, you can spruce up the input box so it doesn't look horrible. Give this a run, I don't think it's an epic fail:

简单的答案是,你真的不能。 Tmdean的解决方案是我能想到的唯一方法。也就是说,你可以修改输入框,这样它看起来并不可怕。给这个跑步,我不认为这是一个史诗般的失败:

Dim bullet
Dim response
bullet = Chr(10) & "   " & Chr(149) & " "
Do
    response = InputBox("Please enter the number that corresponds to your selection:" & Chr(10) & bullet & "1.) Apple" & bullet & "2.) Bannana" & bullet & "3.) Pear" & Chr(10), "Select Thing")
    If response = "" Then WScript.Quit  'Detect Cancel
    If IsNumeric(response) Then Exit Do 'Detect value response.
    MsgBox "You must enter a numeric value.", 48, "Invalid Entry"
Loop
MsgBox "The user chose :" & response, 64, "Yay!"

#2


If you would like to use an hta for this it can be done like this.
The VBScript:

如果您想使用hta,可以这样做。 VBScript:


Set WshShell = CreateObject("WScript.Shell")
'Run the hta.
WshShell.Run "Test.hta", 1, true
'Display the results.
MsgBox "Return Value = " & getReturn
Set WshShell = Nothing

Function getReturn
'Read the registry entry created by the hta.
On Error Resume Next
     Set WshShell = CreateObject("WScript.Shell")
    getReturn = WshShell.RegRead("HKEY_CURRENT_USER\Volatile Environment\MsgResp")
    If ERR.Number  0 Then
        'If the value does not exist return -1
         getReturn = -1
    Else
        'Otherwise return the value in the registry & delete the temperary entry.
        WshShell.RegDelete "HKEY_CURRENT_USER\Volatile Environment\MsgResp"
    End if
    Set WshShell = Nothing
End Function

Then design the hta as desired, and include the following methods

然后根据需要设计hta,并包括以下方法



'Call this when the OK button is clicked.
Sub OK_Click
    For Each objradiobutton In Opt
         If objradiobutton.Checked Then
              WriteResponse objradiobutton.Value
        End If
    Next
    window.Close
End Sub

'Call this when the Cancel button is clicked.
Sub Cancel_Click
     WriteResponse("CANCEL")
     window.Close
End Sub

'Write the response to the registry
Sub WriteResponse(strValue)
    Set WshShell = CreateObject("WScript.Shell")
    WshShell.RegWrite "HKEY_CURRENT_USER\Volatile Environment\MsgResp", strValue
     Set WshShell = Nothing
End Sub

I used a group of radio buttons named "Opt" to make a choice, but you could use any controls you would like.

Because hta's cannot return values, this will create a temperary registry entry. If you are not comforatable messing with the registry, you could also write the result to a temperary text file.

This approach is nice because you can design the hta any way you like, rather than using the supplied inputbox and choosing numbers (thats so DOS).

This could also be nice if you expanded the hta to create itself based on arguments passed to it, like passing in a title, a message to display, an array of options, a set of buttons. That way you could use the same hta any time you needed to get input from the user.

我使用一组名为“Opt”的单选按钮进行选择,但您可以使用任何您想要的控件。因为hta不能返回值,所以这将创建一个临时注册表项。如果您不熟悉注册表,您也可以将结果写入文本文本文件。这种方法很好,因为您可以按照自己喜欢的方式设计hta,而不是使用提供的输入框并选择数字(这就是DOS)。如果你扩展hta以根据传递给它的参数创建自己,例如传入标题,要显示的消息,选项数组,一组按钮,这也可能很好。这样,只要您需要从用户那里获得输入,就可以使用相同的hta。

#3


You can use DialogLib to create forms with dropdowns and checkboxes. DialogLib is still in it's ealy stages, but is's allready quite usefull: http://www.soren.schimkat.dk/Blog/?p=189

您可以使用DialogLib创建带有下拉列表和复选框的表单。 DialogLib仍处于ealy阶段,但已经非常有用了:http://www.soren.schimkat.dk/Blog/?p = 189

#4


Try WshShell.Popup. Depending upon your data that may work for you...

试试WshShell.Popup。取决于您可能适合您的数据......

Otherwise you could investigate PowerShell.

否则你可以调查PowerShell。

#5


One option is to script Internet Explorer. You can use VBScript to launch IE and load a local HTML file, and attach a VBScript sub to a form's submit button (or any other JavaScript events), which can then close the IE window as part of its execution.

一种选择是编写Internet Explorer脚本。您可以使用VBScript启动IE并加载本地HTML文件,并将VBScript子附加到表单的提交按钮(或任何其他JavaScript事件),然后可以关闭IE窗口作为其执行的一部分。

#6


You can launch an HTA from a VBScript.

您可以从VBScript启动HTA。

Set shell = CreateObject("WScript.Shell")
shell.Run "Test.hta"

EDIT

Since you have full control of the VBScript, could you make the 3rd party VBScript simply call your HTA? You could put the UI and whatever processing code inside of the HTA.

由于您可以完全控制VBScript,您是否可以让第三方VBScript简单地调用您的HTA?您可以将UI和任何处理代码放在HTA中。

#7


As an example of @TmDean's suggestion, there's this class that I sometimes use which scripts IE (well, it scripted IE6; I haven't tried the more recent incarnations.)

作为@TmDean建议的一个例子,我有时会使用哪个脚本IE(好吧,它编写了IE6脚本;我没有尝试过最近的版本。)

class IEDisplay
    '~ Based on original work by Tony Hinkle, tonyhinkle@yahoo.com

    private TEMPORARY_FOLDER

    private objShell
    private objIE
    private objFSO
    private objFolder
    private strName
    private streamOut
    private objDIV

    private numHeight
    private numWidth
    private numTop
    private numLeft

    private sub Class_Initialize()
    Dim strComputer
    Dim objWMIService
    Dim colItems
    Dim objItem
    Dim arrMonitors( 10, 1 )
    Dim numMonitorCount

    Set objShell = WScript.CreateObject("WScript.Shell")
    Set objIE = CreateObject("InternetExplorer.Application")

    strComputer = "."
    Set objWMIService = GetObject( "winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery( "Select  * from Win32_DesktopMonitor")

    numMonitorCount = 0 
    For Each objItem in colItems
        arrMonitors( numMonitorCount, 0 ) = objItem.ScreenHeight
        arrMonitors( numMonitorCount, 1 ) = objItem.ScreenWidth
        numMonitorCount = numMonitorCount + 1
    Next

    numHeight = arrMonitors( 0, 0 )
    numWidth = arrMonitors( 0, 1 )

    Set objFSO = CreateObject("Scripting.FileSystemObject")
    TEMPORARY_FOLDER = 2
    set objFolder = objFSO.GetSpecialFolder( TEMPORARY_FOLDER )
    strName = objFSO.BuildPath( objFolder, objFSO.GetTempName ) & ".html"
    WriteFileU strName, Join( Array( "<HTML><HEAD><TITLE>Information</TITLE></HEAD>", _
                     "<BODY SCROLL='NO'><CENTER><FONT FACE='arial black'> <HR COLOR='BLACK'>", _
                     "<DIV id='MakeMeAnObject'></DIV>", _
                     "<HR COLOR='BLACK'></FONT></CENTER></BODY></HTML>" ), vbCRLF ), WF_CREATE        
    numTop = 0
    numLeft = 0
    end sub

    Sub Init( strPosition )
    'NW, N, NE, W, CENTRE, E, SW, S, SE
    Select Case strPosition
    Case "NW"
        numTop = 0
        numLeft = 0
    Case "N"
        numTop = 0
        numLeft = ( numWidth / 2 ) - 250
    Case "NE"
        numTop = 0
        numLeft = numWidth - 500
    Case "W"
        numTop = ( numHeight / 2 ) - 55
        numLeft = 0
    Case "CENTRE"
        numTop = ( numHeight / 2 ) - 55
        numLeft = ( numWidth / 2 ) - 250
    Case "E"
        numTop = ( numHeight / 2 ) - 55
        numLeft = numWidth - 500
    Case "SW"
        numTop = numHeight - 110
        numLeft = 0
    Case "S"
        numTop = numHeight - 110
        numLeft = ( numWidth / 2 ) - 250
    Case "SE"
        numTop = numHeight - 110
        numLeft = numWidth - 500
    Case Else
        numTop = 0
        numLeft = 0
    End Select

    SetupIE( strName )
    Set objDIV = objIE.Document.All("MakeMeAnObject")
    end sub

    private sub Class_Terminate()
    'Close IE and delete the file
    objIE.Quit
    '~ optionally you may want to get rid of the temp file
    end sub

    public sub Display( strMsg, numMillisec )
    objDIV.InnerHTML = strMsg
    WScript.Sleep numMillisec
    end sub

    Private Sub SetupIE(File2Load)
     objIE.Navigate File2Load
     objIE.ToolBar = False
     objIE.StatusBar = False
     objIE.Resizable = False

     Do
     Loop While objIE.Busy

     objIE.Width = 500
     objIE.Height = 110
     objIE.Left = numLeft
     objIE.Top = numTop
     objIE.Visible = True
     objShell.AppActivate("Microsoft Internet Explorer")
    End Sub

end class

here is the missing (from the original posting) WriteFileU function

这里是缺少的(来自原始帖子)WriteFileU函数

Const WF_APPEND = 1
Const WF_CREATE = 2

Const WF_FOR_APPENDING = 8
Const WF_FOR_WRITING = 2
Const WF_CREATE_NONEXISTING = True

Const CONST_READ = 1, CONST_WRITE = 2, CONST_APPEND = 8

Const AS_SYSTEMDEFAULT = -2, AS_UNICODE = -1, AS_ASCII = 0

Sub WriteFileU( sFilename, sContents, nMode )
  Dim oStream
  If nMode = WF_APPEND Then
    Set oStream = oFSO.OpenTextFile( sFilename, WF_FOR_APPENDING, WF_CREATE_NONEXISTING, AS_UNICODE )
  ElseIf nMode = WF_CREATE Then
    Set oStream = oFSO.OpenTextFile( sFilename, WF_FOR_WRITING, WF_CREATE_NONEXISTING, AS_UNICODE )
  Else
    STOP
  End If

  oStream.Write sContents
  oStream.Close
  Set oStream = Nothing
End Sub

and then as an example of it's use

然后作为它的一个例子

set i = new IEDisplay 
a = array("NW", "N", "NE", "W", "CENTRE", "E", "SW","S","SE")
for each aa in a
    i.init aa
    i.display "Here in " & aa & " of screen", 1000
next

Now that's not immediately useful (especially are there are a pile of calls to my own utility routines in there) but it gives a framework. By modifying what HTML is stored, you could add support for listboxes etc.

现在这不是立即有用的(特别是在那里有一堆对我自己的实用程序例程的调用)但是它提供了一个框架。通过修改HTML的存储,您可以添加对列表框等的支持。