Adding a GUI to VBScript

前端 未结 3 893
太阳男子
太阳男子 2020-12-03 23:39

I\'m currently working on a vbs script but I need user interaction with script. Basically I need two buttons and 4 checkboxes ( checkboxes isn\'t important).

Thanks

相关标签:
3条回答
  • 2020-12-03 23:56

    The best approach I found is to open HTA file from VBS using "WScript.Shell Run" and communicate back to the VBS using an XML file.

    Example (dialog.vbs)

    Set fso = CreateObject("Scripting.FileSystemObject") 
    Set oFile = fso.GetFile(Wscript.ScriptFullName) 
    sFolder = oFile.ParentFolder 
    sHtaFilePath = sFolder & "\dialog.hta"
    Dim oShell: Set oShell = CreateObject("WScript.Shell")
    oShell.Run sHtaFilePath, 1, True
    
    'Load return data from XML File
    If fso.FileExists(sHtaFilePath & ".xml") Then
        Set oXml = CreateObject("Microsoft.XMLDOM")
        oXML.async = False
        oXML.load sHtaFilePath & ".xml"
    
        MsgBox "Value 1: " & oXML.SelectSingleNode("/root/txt1").text
        MsgBox "Value 2: " & oXML.SelectSingleNode("/root/txt2").text
    
        fso.DeleteFile sHtaFilePath & ".xml"
    End If
    

    Example HTA (dialog.hta)

    <html>
      <title>Test</title>
      <head>
      <HTA:APPLICATION 
      ID=oHTA 
      SINGLEINSTANCE="yes"
      SCROLL="no"
      />
    </head>
    
    <script language="vbscript">
      Window.ResizeTo 300, 200
      Set fso = CreateObject("Scripting.FileSystemObject") 
    
      Sub Send()
        Dim sFilePath: sFilePath = Replace(location.href,"file:///","")
        sFilePath = Replace(sFilePath,"/","\")
        sFilePath = Replace(sFilePath," %20"," ")
    
        'Save return date to XML File
        Set oXml = CreateObject("Microsoft.XMLDOM")
        Set oRoot = oXml.createElement("root")
        oXml.appendChild oRoot
        AddXmlVal oXml, oRoot, "txt1", txt1.value
        AddXmlVal oXml, oRoot, "txt2", txt2.value
        oXml.Save sFilePath & ".xml"
    
        self.Close()
      End Sub
    
      Sub AddXmlVal(oXml, oRoot, sName, sVal)
        Set oNode = oXml.createElement(sName)
        oNode.Text = sVal
        oRoot.appendChild oNode
      End Sub
    
    </script>
    
    <body>
      <div>
        Value 1 
        <input id="txt1" style="width: 100px;">
      </div>
    
      <div>
        Value 2 
        <select id=txt2 style="width: 100px;">
          <option value="A">A</option>
          <option value="B">B</option>
          <option value="C">D</option>
        </select>
      </div>
    
    <p align=center>
      <input type="button" value="Send" onclick="Send()">
      <input type="button" value="close" onclick="self.Close()">
    </p>
    
    </body>
    </html>
    

    Even better approach is for the HTA file to be created by the VBS file and then deleted. This way HTA does not have to be distributed along with the VBS.

    Set fso = CreateObject("Scripting.FileSystemObject") 
    
    sHtml = "<div>Value 1 " & _
        "<input id='txt1' style='width: 100px'>" & _
      "</div>" & _
      "<div>Value 2 " & _
        "<select id='txt2' style='width: 100px'>" & _
          "<option value='A'>A</option>" & _
          "<option value='B'>B</option>" & _
          "<option value='C'>D</option>" & _
        "</select>" & _
      "</div>" & _
      "<p align=center>" & _
        "<input type='button' value='Send' onclick='Send()'> " & _
        "<input type='button' value='Close' onclick='self.Close()'>" & _
      "</p>"
    
      Set oRet = OpenDialog(sHtml, "txt1,txt2", 300, 200, "Dialog 1")
      MsgBox "Value 1: " & oRet("txt1") & ", Value 2: " & oRet("txt2")
    
    '==================================
    Function OpenDialog(sHtml, sFields,iWidth,iHeight, sTitle)
      sHtaFilePath = Wscript.ScriptFullName & ".hta"
    
      CreateHtaFile sHtaFilePath, sHtml, sFields,iWidth,iHeight,sTitle
    
      Set f = fso.GetFile(sHtaFilePath)
      f.attributes = f.attributes + 2 'Hidden
    
      Dim oShell: Set oShell = CreateObject("WScript.Shell")
    
      oShell.Run """" & sHtaFilePath & """", 1, True
    
      If fso.FileExists(sHtaFilePath) Then
        fso.DeleteFile sHtaFilePath
      End If
    
      Set oRet = CreateObject("Scripting.Dictionary")
    
      'Load return data from XML File
      If fso.FileExists(sHtaFilePath & ".xml") Then
          Set oXml = CreateObject("Microsoft.XMLDOM")
          oXML.async = False
          oXML.load sHtaFilePath & ".xml"
    
          For each sField In Split(sFields,",")
            oRet.Add trim(sField), oXML.SelectSingleNode("/root/" & trim(sField)).text
          Next
    
          fso.DeleteFile sHtaFilePath & ".xml"
      End If
    
      Set OpenDialog = oRet
    End Function
    
    Sub CreateHtaFile(sHtaFilePath, sHtml, sFields, iWidth, iHeight, sTitle)
      Set f = fso.CreateTextFile(sHtaFilePath, True)
      f.WriteLine "<html><title>FL Reporting</title><head><HTA:APPLICATION ID=oHTA SINGLEINSTANCE=""yes"" SCROLL=""no""/></head>"
      f.WriteLine "<script language=""vbscript"">"
      f.WriteLine "Window.ResizeTo " & iWidth & ", " & iHeight
      f.WriteLine "Set fso = CreateObject(""Scripting.FileSystemObject"")"
      f.WriteLine ""
      f.WriteLine "Sub Send()"
      f.WriteLine " Dim sFilePath: sFilePath = Replace(location.href,""file:///"","""")"
      f.WriteLine " sFilePath = Replace(sFilePath,""/"",""\"")"
      f.WriteLine " sFilePath = Replace(sFilePath,""%20"","" "")"
      f.WriteLine " Set oXml = CreateObject(""Microsoft.XMLDOM"")"
      f.WriteLine " Set oRoot = oXml.createElement(""root"")"
      f.WriteLine " oXml.appendChild oRoot"
    
      For each sField In Split(sFields,",")
        f.WriteLine " AddXmlVal oXml, oRoot, """ & sField & """, GetVal(" & sField & ")"
      Next
    
      f.WriteLine " oXml.Save sFilePath & "".xml"""
      f.WriteLine " self.Close()"
      f.WriteLine "End Sub"
      f.WriteLine ""
      f.WriteLine "Sub AddXmlVal(oXml, oRoot, sName, sVal)"
      f.WriteLine " Set oNode = oXml.createElement(sName)"
      f.WriteLine " oNode.Text = sVal"
      f.WriteLine " oRoot.appendChild oNode"
      f.WriteLine "End Sub"
      f.WriteLine ""
      f.WriteLine "Function GetVal(o)"
      f.WriteLine " GetVal = o.value"
      f.WriteLine " If o.Type = ""checkbox"" Then"
      f.WriteLine "   If o.checked = False Then"
      f.WriteLine "     GetVal = """""
      f.WriteLine "   End If"
      f.WriteLine " End If"
      f.WriteLine "End Function"  
      f.WriteLine "</script>"
      f.WriteLine "<body>"
      f.WriteLine sHtml
      f.WriteLine "</body></html>"
      f.Close
    End Sub
    
    0 讨论(0)
  • 2020-12-03 23:58

    VBScript has dialogs, only not many and no checkboxes, you would need a COM object to do so (and there are). I'm sure you know Messagebox and here an example of the less known Popup

    Dim WshShell, BtnCode
    Set WshShell = WScript.CreateObject("WScript.Shell")
    
    BtnCode = WshShell.Popup("Do you feel alright?", 7, "Answer This Question:", 4 + 32)
    
    Select Case BtnCode
       case 6      WScript.Echo "Glad to hear you feel alright."
       case 7      WScript.Echo "Hope you're feeling better soon."
       case -1     WScript.Echo "Is there anybody out there?"
    End Select
    

    However, the best way to have more dialogs in vbscript is using HTA. Here an example

    <HTML><HEAD>
       <HTA:APPLICATION
       ID = "oApp"
       APPLICATIONNAME = "Example"
       BORDER = "thick"
       CAPTION = "yes"
       ICON = "app.ico"
       SHOWINTASKBAR = "yes"
       SINGLEINSTANCE = "yes"
       SYSMENU = "yes"
       WINDOWSTATE = "normal"
       SCROLL = "yes"
       SCROLLFLAT = "yes"
       VERSION = "1.0"
       INNERBORDER = "yes"
       SELECTION = "no"
       MAXIMIZEBUTTON = "yes"
       MINIMIZEBUTTON = "yes"
       NAVIGABLE = "yes"
       CONTEXTMENU = "yes"
       BORDERSTYLE = "normal"
       >
    
       <SCRIPT language="vbscript">
       sub SimpleExeample()
         document.body.innerHTML = "<form name=myform><input type=checkbox name=chk1>Check me<br><br><button onclick='alert(myform.chk1.checked)'>Show if checked</button></form>"
       end sub
       </SCRIPT>
    
    </HEAD>
    <BODY onLoad="SimpleExeample()">
    </BODY>
    </HTML>
    

    In one thing i agree with Cody, vbscript is nearly dead, if you start programming choose another language. Take a look at Ruby, the start is easy to learn an it is FUN. Here an example of u ruby script using shoes as GUI

    require 'green_shoes'
    Shoes.app{
      button("Click me!"){alert("You clicked me.")}
    }
    

    EDIT: since my Ruby alternative rises some questions, here a more traditionel way closer to Vbscript uses of the same sample. The sample above is used more for a functional chained way of programming.

    require 'green_shoes'
    Shoes.app do
      button("Click me!") do
        alert("You clicked me.")
      end
    end
    
    0 讨论(0)
  • 2020-12-04 00:04

    Today, I would like to introduce two projects that will interest you.

    • wsh-js-gtk - Make your own GUI from JScript/VBScript with GTK-server
    • welsonjs - Build a windows desktop apps based on WSH/HTA with ES6/HTML5 compatibility polyfills, module.exports(NodeJS) styled module implementation.
    0 讨论(0)
提交回复
热议问题