Activate and Focus HTA window using VBscripting - windows

I have developed several HTA files where each file calls the other.
There is one HTA file that i need (if called) to stay as the "Always on top" window while it is open.
I have tried "AppActivate" function thru an infinite loop using Vb script however i always find that it activates the window in the taskbar but does not make the HTA file always on top.
Searched up and down, couldn't find working way to get it working in reliable way that does not involve 3rd party applications.
My HTA file code:
<html>
<hta:application id="oHTA"
border="none"
caption="no"
contextmenu="no"
innerborder="no"
scroll="no"
showintaskbar="no"
/>
<script language="VBScript">
Sub Window_OnLoad
'Resize and position the window
width = 133 : height = 25
window.resizeTo width, height
window.moveTo ((Screen.Width / 3)*2),0
End Sub
Sub CallMain ()
Set objShell = CreateObject("WScript.Shell")
objShell.Run("Main.hta")
window.close 'close this HTA
End Sub
</script>
<body background="Strt.png" onclick="CallMain">
</html>
Any suggestions would be appreciated.

Here's an example HTA with multiple pages. This should simplify the issue of focus.
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta charset="UTF-8" http-equiv="X-UA-Compatible" content="IE=9">
<hta:application id=oHTA
border=none
caption=no
contextmenu=no
innerborder=no
scroll=no
showintaskbar=no
>
<script language="VBScript">
Set oWSH = CreateObject("Wscript.Shell")
Set oFSO = CreateObject("Scripting.FileSystemObject")
MyPath = Mid(document.URL,8)
MyFolder = oFSO.GetParentFolderName(MyPath)
oWSH.CurrentDirectory = MyFolder
Sub window_onLoad
StartPage
End Sub
Sub StartPage
HideAllPages
window.document.body.background = "Strt.png"
iStartPage.style.display = "inline"
window.resizeTo 133, 25
window.moveTo ((screen.availWidth / 3)*2),0
End Sub
Sub MainPage
HideAllPages
window.document.body.background = "Main.png"
iMainPage.style.display = "inline"
CenterWindow 800,600
End Sub
Sub SubPage1
HideAllPages
window.document.body.background = "Sub1.png"
iSubPage1.style.display = "inline"
CenterWindow 640,480
End Sub
Sub SubPage2
HideAllPages
window.document.body.background = "Sub2.png"
iSubPage1.style.display = "inline"
CenterWindow 640,480
End Sub
Sub HideAllPages
iStartPage.style.display = "none"
iMainPage.style.display = "none"
iSubPage1.style.display = "none"
iSubPage2.style.display = "none"
End Sub
Sub CenterWindow(x,y)
window.resizeTo x, y
window.moveTo (screen.availWidth - x)/2, (screen.availHeight - y)/2
End Sub
</script>
<style>
body {background-size:cover; background-attachment:fixed; background-repeat:no-repeat}
.sb {background-color:transparent; background-repeat:no-repeat; border:none;
cursor:pointer; overflow:hidden; outline:none; width:100%}
</style>
<body>
<div id=iStartPage>
<input class=sb type=button onclick=MainPage()>
</div>
<div id=iMainPage>
<input type=button value=Back onclick=StartPage()>
<input type=button value=SubPage1 onclick=SubPage1()>
<input type=button value=SubPage2 onclick=SubPage2()>
</div>
<div id=iSubPage1>
<input type=button value=Back onclick=MainPage()>
</div>
<div id=iSubPage2>
<input type=button value=Back onclick=MainPage()>
</div>
</body>
</html>

Related

Dynamically change icon in HTA

NOTE: This question is not a duplicate of Can I embed an icon to a .hta file? - For more details, compare the issues and read the comments
I am trying to build an HTA that will automatically perform certain tasks when executed, without user action. The reason I want to use an HTA instead of just a bare VBScript is to inform the user of progress as the routine executes, since it takes some time, and I don't want the user wondering if it hung, maybe restarting it, and so on. There are ten tasks, and I would like to have ten lines in my HTA display, each one with a few words describing what is happening at that point. So far, so good – that is simple enough.
I would also like to have a small icon before each line, that would initially display one icon. When the task on that line begins, it would switch to a second icon, and when it completes it would switch to a third icon.
For several reasons not pertinent to my question, I want to keep it ALL in my HTA – no references to external files. I found a site that led me to using a tag like:
<img src='data:image/gif;base64,R0lGODlhIAAgAOY…'/>
to display a green check mark. It does that very nicely, but I would like to change that dynamically, and there I am running aground. In my HTA, I have VBScript that does this:
x="<img src='data:image/gif;base64,R0lGODlhIAAgAOY…'/>"
(Shortened – the actual image string is quite long.)
and then I have:
img1.InnerHTML = x
to refer to this placeholder in my HTML code:
<span id = "img1"></span>
The code executes, but does not display the green check, only a small black square with a white 'x'. Am I doing something wrong, or is this just not possible? It seems like it should be possible, but no syntax I have tried so far has worked.
It seems that this question is now unlocked, so I am posting the two answers that I posted in the comments.
The first answer is more imperative, in that we need Javascript to convert SVG into a data URI via the svgToDataURL() function. This example is good because you can see the SVG definition in clear text which makes it easier to maintain and change.
<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<script>
function svgToDataURL(svg) {
return "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg);
//return "data:image/svg+xml;base64," + btoa(svg); // this works too!
//return "data:image/svg+xml;charset=utf-8," + svg; // this only works in modern browsers
}
var assets = {
redCross: svgToDataURL('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path stroke="red" d="M23.985 8.722L16.707 16l7.278 7.278-.707.707L16 16.707l-7.278 7.278-.707-.707L15.293 16 8.015 8.722l.707-.707L16 15.293l7.278-7.278z"/></svg>'),
greenTick: svgToDataURL('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path stroke="green" d="M13.5 22.142L7.59 16.42l.636-.636L13.5 20.87 26.721 7.8l.637.637z"/></svg>')
};
</script>
</style>
</head>
<body>
1 + 1 = 2 <img id="demoSVG" width="16" height="16"> <p>
<script>
var demoSVG = document.getElementById("demoSVG");
demoSVG.src = assets.redCross;
</script>
<button type="button" onclick="demoSVG.src = assets.greenTick">Change SVG!</button>
</body>
</html>
The second answer uses CSS style to configure the image as a background style. This means the Javascript required to change the image is shorter. However, it requires you to URL encode your SVG. Note that this full encoding requirement exists because HTA is more sensitive to what it accepts as a URL. If this was an HTML question instead of HTA, the URL encoding requirement is relaxed and you could have used unencoded SVG in this solution as well.
<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<style>
div.redCross {
display: inline-block;
width: 16px;
height: 16px;
background-image: url(data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%3Cpath%20stroke%3D%22red%22%20d%3D%22M23.985%208.722L16.707%2016l7.278%207.278-.707.707L16%2016.707l-7.278%207.278-.707-.707L15.293%2016%208.015%208.722l.707-.707L16%2015.293l7.278-7.278z%22%2F%3E%3C%2Fsvg%3E);
}
div.greenTick {
display: inline-block;
width: 16px;
height: 16px;
background-image: url(data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%3Cpath%20stroke%3D%22green%22%20d%3D%22M13.5%2022.142L7.59%2016.42l.636-.636L13.5%2020.87%2026.721%207.8l.637.637z%22%2F%3E%3C%2Fsvg%3E);
}
</style>
</head>
<body>
<div>1 + 1 = 2 <div id="demo2" class="redCross"></div></div> <p>
<script>
var demo2 = document.getElementById("demo2");
</script>
<button type="button" onclick="demo2.className = 'greenTick'; ">Change SVG!</button>
</body>
</html>
Below, are two examples that demonstrate how to dynamically select among different base64 embedded images (icons) in an HTA file. The first one switches the display style from none to inline to cycle through the images. The second one changes the image by replacing the innerHTML contents. The complete examples are here.
Here are the examples with the base64 code truncated:
Example 1:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" http-equiv="X-UA-Compatible" content="IE=9">
<script language="VBScript">
window.resizeTo 250,350
Dim Text,TextIndex
Text = "ABCD"
TextIndex = 1
Sub window_onLoad
idTitle.innerText = Text
document.getElementById(Mid(Text,TextIndex,1)).Style.Display = "inline"
idLetter.innerText = Mid(Text,TextIndex,1)
End Sub
Sub GoLeft
If TextIndex=1 Then Exit Sub
document.getElementById(Mid(Text,TextIndex,1)).Style.Display = "none"
TextIndex = TextIndex - 1
document.getElementById(Mid(Text,TextIndex,1)).Style.Display = "inline"
idLetter.innerText = Mid(Text,TextIndex,1)
End Sub
Sub GoRight
If TextIndex=Len(Text) Then Exit Sub
document.getElementById(Mid(Text,TextIndex,1)).Style.Display = "none"
TextIndex = TextIndex + 1
document.getElementById(Mid(Text,TextIndex,1)).Style.Display = "inline"
idLetter.innerText = Mid(Text,TextIndex,1)
End Sub
</script>
<style>
body {background-color:Black; color:White}
.NoShow {display:none}
.Show {display:inline}
.LgFont {font-size:24pt}
</style>
</head>
<body>
<h2 id=idTitle></h2>
<img id=A class=NoShow src='data:image/gif;base64,iVBORw0KGgo...'>
<img id=B class=NoShow src='data:image/gif;base64,iVBORw0KGgo...'>
<img id=C class=NoShow src='data:image/gif;base64,iVBORw0KGgo...'>
<img id=D class=NoShow src='data:image/gif;base64,iVBORw0KGgo...'>
<br><br>
<input class=LgFont id=GL type=button value=👈 onClick=GoLeft()>
<input class=LgFont id=GR type=button value=👉 onClick=GoRight()>
<span class=LgFont id=idLetter>
</body>
</html>
Example 2:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" http-equiv="X-UA-Compatible" content="IE=9">
<script language="VBScript">
window.resizeTo 250,350
Const BeginTag = "<img src='data:image/gif;base64,"
Const EndTag = "'>"
Dim Text,TextIndex
ReDim AImg(128)
AImg(65) = "iVBORw0KGgo..."
AImg(66) = "iVBORw0KGgo..."
AImg(67) = "iVBORw0KGgo..."
AImg(68) = "iVBORw0KGgo..."
Text = "ABCD"
TextIndex = 1
Sub window_onLoad
idTitle.innerText = Text
idImage.innerHTML = BeginTag & AImg(Asc(Mid(Text,TextIndex,1))) & EndTag
idLetter.innerText = Mid(Text,TextIndex,1)
End Sub
Sub GoLeft
If TextIndex=1 Then Exit Sub
TextIndex = TextIndex - 1
idImage.innerHTML = BeginTag & AImg(Asc(Mid(Text,TextIndex,1))) & EndTag
idLetter.innerText = Mid(Text,TextIndex,1)
End Sub
Sub GoRight
If TextIndex=Len(Text) Then Exit Sub
TextIndex = TextIndex + 1
idImage.innerHTML = BeginTag & AImg(Asc(Mid(Text,TextIndex,1))) & EndTag
idLetter.innerText = Mid(Text,TextIndex,1)
End Sub
</script>
<style>
body {background-color:Black; color:White}
.LgFont {font-size:24pt}
</style>
</head>
<body>
<h2 id=idTitle></h2>
<div id=idImage></div>
<br><br>
<input class=LgFont id=GL type=button value=👈 onClick=GoLeft()>
<input class=LgFont id=GR type=button value=👉 onClick=GoRight()>
<span class=LgFont id=idLetter>
</body>
</html>

HTA Browse to file

Im trying to browse to files.
It works fine as a simple vbs but when inside a HTA produces an Error.
Like this:
sUserList = BrowseToFile
msgbox sUserList
Function BrowseToFile
Set wShell=CreateObject("WScript.Shell")
Set oExec=wShell.Exec("mshta.exe ""about:<input type=file id=FILE><script>FILE.click();new ActiveXObject(""Scripting.FileSystemObject"").GetStandardStream(1).WriteLine(FILE.value);close();resizeTo(0,0);</script>""")
BrowseToFile = oExec.StdOut.ReadLine
End Function
ERROR:
Line 130: Is the wShell.exec
Char 203:
Unterminated String Constant.
I could call a separate vbs and write to file then get it that way.
Wrong escaped nested double quotes: instead of
... new ActiveXObject(""Scripting.FileSystemObject"")...
use single quotation marks as follows:
... new ActiveXObject('Scripting.FileSystemObject')...
Edit: in your HTATest.hta I see some weird for me approach:
nested <script> ... <script> ... </script> ... </script>
launched mshta.exe from HTATest.hta i.e., as a matter of fact, from mshta.exe HTATest.hta
Next hta works(?):
<html>
<head>
<title>HTA Test
</title>
<HTA:APPLICATION ID="objTest" APPLICATIONNAME="HTATest" SCROLL="no" SINGLEINSTANCE="yes" >
</head>
<SCRIPT LANGUAGE="VBScript">
Path = BrowseToFile
msgboxx= "Path = " & Path
Function BrowseToFile()
Set wShell=CreateObject("WScript.Shell")
mshtapar="about:<input type=file id=FILE>"_
& "<script>FILE.click();"_
& "new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).WriteLine(FILE.value);"_
& "close();"_
& "resizeTo(0,0);"_
& "<//script>"
msgboxy= "param =" & mshtapar
Set oExec=wShell.Exec( "mshta.exe " & """" & mshtapar & """")
End Function
</SCRIPT>
<body>
</body>
Note <//script> instead of </script> within BrowseToFile() function. However, this workaround I don't regard as a solution...
Here's a simple hta example: does the same as yours one but without troubles
<html>
<head>
<title>HTA Test
</title>
<HTA:APPLICATION ID="objTest" APPLICATIONNAME="HTATest" SCROLL="no" SINGLEINSTANCE="yes" >
</head>
<SCRIPT LANGUAGE="VBScript">
<!--
-->
</SCRIPT>
<body>
<input type="file" id=FILE>
</body>

Classic ASP Auto complete

I'm using classic ASP to create an auto-complete page. I have two different pages, autocomplete.asp and source.asp. My code as below:
autocomplete.asp
<%# language="VBScript" %>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Autocomplete - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<!-- SCRIPT FOR AUTOCOMPETE SEARCH BOX //-->
<script type="text/javascript" language="javascript">
$(function () {
$("#productname").autocomplete({
source: "source.asp",
minLength: 2
});
});
</script>
</head>
<body>
<p> </p>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="productname">
</div>
<p> </p>
</body>
</html>
sourse.asp
<%# language="VBScript" %>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2 /jquery.js" ></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js" ></script>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css"/>
<!-- SCRIPT FOR AUTOCOMPETE SEARCH BOX //-->
</head>
<%
Dim keywords, keywords_cmd, output, firstItem
Set keywords_cmd = Server.CreateObject ("ADODB.Command")
keywords_cmd.ActiveConnection = "DRIVER={SQL Server};SERVER=wsgpdba4.sgp.is.keysight.com;UID=kportal;PWD=q1w2e3r4;DATABASE=A_Sys"
keywords_cmd.CommandText = "SELECT ProductId FROM Product where ProductId like '%" & Request.QueryString("term") & "%'"
keywords_cmd.Prepared = true
Set keywords = keywords_cmd.Execute
output = "["
While (NOT keywords.EOF)
output = output & "{""ProductId"":""" & keywords.Fields.item("ProductId") & """},"
keywords.MoveNext()
Wend
keywords.Close()
Set keywords = Nothing
output=Left(output,Len(output)-1)
output = output & "]"
response.write output
%>
<body>
</body>
</html>
The source.asp return me like this:
[{"ProductId":"111 "}]
Please help
I had to work on a legacy program recently. I had to get autosuggest to work with SQL and ASP. This is what I came up with.
<%# Language=VBScript %>
<!-- #include File="CarrierAutocomplete.inc"-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link href="jquery-ui-1.12.1.custom/jquery-ui.css">
<script src="jquery-ui-1.12.1.custom/external/jquery/jquery.js"></script>
<script src="jquery-ui-1.12.1.custom/jquery-ui.js"></script>
<script>
$(function() {
var strCarriers = [<%=getListOfCarriers()%>];
$( "#carrier_name" ).autocomplete({
source: strCarriers
});
});
</script>
</head>
<body>
<table>
<tr>
<td align="right"><p><b>CARRIER:</b></td>
<label for="carrier_name"></label></td>
<td><input id="carrier_name" name="carrier_name"></td>
</tr>
</table>
</body>
</html>
'CarrierAutoComplete.inc
<!--#include file="ConnStrings.inc"--> 'you won't need this
<%
Function getListOfCarriers()
Set conn = Server.CreateObject("ADODB.Connection")
Set rs = Server.CreateObject("ADODB.Recordset")
Dim sql
Dim allCarriers
Dim strCarriers
Dim n
'conn.Open ConnString 'PRODUCTION
conn.Open ConnString 'DEVELOPMENT
sql = "SELECT [carrier] FROM [dbo].[VerifiedCarriers] order by carrier"
Set RS = Conn.Execute(sql)
if not rs.eof and err.number=0 then
allCarriers = rs.getrows
End If
colStart = LBound(allCarriers, 1)
colEnd = UBound(allCarriers, 1)
rowStart = LBound(allCarriers, 2)
rowEnd = UBound(allCarriers, 2)
For row=rowStart to rowEnd
For col=colStart to colEnd
strCarriers = strCarriers + """" & "" & allCarriers(col,row) & """," & chr(13)
Next
Next
strCarriers = Left(strCarriers,Len(strCarriers) - 2) 'REMOVE THE LAST COMMA
response.write strCarriers
End Function
%>
I'm not 100% clear on the issue here, but the jquery ui control needs to have data in an expected form of value and label:
[{"value":"111", "label":"sample product"}]
Or you can just supply an array of strings if you're not concerned about the values:
["product one", "product two"]
You're also not selecting the product name from your db, just the Id, as I assume your autocomplete needs to show a list of product names?

Setting onclick dynamically and passing in the element itself

element.onclick= aFunction() does not call the function when element (in this case a <SPAN> element) is clicked.
This question has been answered for JavaScript (question by Nick Van Hoogenstyn), but how do you do the same sort of thing for VBScript? The reason why I'm using VBScript instead of JavaScript is that I'm creating an HTA and using VBScript for the file access activities within it.
This
demonstrates that this simple code:
<html>
<head>
<Title>spanclick</Title>
<hta:application id="spanclick" scroll = "no">
<script type="text/vbscript">
Function onSpanClick(oElm)
MsgBox oElm.tagName & " onSpanClick clicked"
End Function
</script>
</head>
<body>
<span onclick="onSpanClick Me">onSpanClick</span>
</body>
</html>
'works' by putting the function name into the onclick attribute of the span element and passing the element (Me) to the function.
VBScript is little bit different form Javascript in Syntax
see the sample
<script language="vbscript">
sub cmdBtn_Click()
msgbox("Click!!!")
end sub
</script>
<input type="button" name="cmdBtn" value="Click Me!" onclick ="vbscript:cmdBtn_Click">

How to format with newline included file in hta

When I load with the current script some csv file. Textarea not present the right format like in csv format:
1.csv:
text1
text2
Now 1.csv output:
text1 text2
Expected 1.csv output:
text1
text2
Actually textarea is not able to create newlines for some unknown reason for me.
The script:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<hta:application
applicationname="MyHTA"
border="thick"
borderstyle="normal"
caption="My HTML Application"
contextmenu="no"
icon="myicon.ico"
maximizebutton="no"
minimizebutton="yes"
navigable="no"
scroll="yes"
selection="no"
showintaskbar="yes"
singleinstance="yes"
sysmenu="yes"
version="1.0"
windowstate="normal"
>
<script language="vbscript">
Sub RunCommonDialog
Set objDialog = CreateObject("UserAccounts.CommonDialog")
objDialog.Filter = "CSV Files (*.csv)|*.csv|All Files|*.*"
objDialog.InitialDir = "C:\Documents and Settings\All Users\Desktop"
intResult = objDialog.ShowOpen
If intResult = 0 Then
Exit Sub
Else
CommonDialog.value = objDialog.FileName
CommonDialog_Span.innerHTML = objDialog.FileName
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile(objDialog.FileName, ForReading)
contents = objTextFile.ReadAll
objTextFile.Close
Set objFSO = Nothing
Set objReadFile = Nothing
PRE.innerHTML = contents
End If
End Sub
Sub reloadHTA()
location.reload True
End Sub
</script>
<body>
<input type="hidden" id="CommonDialog"><input type="button" onclick="RunCommonDialog" value="Browse..."><input class = "StdBtt Meta" type = "BUTTON" value = "Reset" onclick = "reloadHTA"><br>
<p>File: <span id="CommonDialog_Span"></span></p>
<textarea rows="4" cols="88" name="PRE" readonly="readonly">
</textarea>
</body>
If you use a .hta that concentrates on your problem - e.g.
<html>
<head>
<hta:application id="t"></hta>
<title>t</title>
<script language="vbscript">
Sub ol()
MsgBox "ol"
a = Array("line1", "line2")
document.all.ta1.value = Join(a, vbCrLf)
document.all.ta2.innerHTML = Join(a, vbCrLf)
End Sub
</script>
</head>
<body onload="ol">
<textarea id="ta1" rows="4" cols="88"></textarea>
<textarea id="ta2" rows="4" cols="88"></textarea>
</body>
</html>
you'll see at a glance that your problem is caused by using .innerHTML instead of .value.
(BTW: You should use a validator (tidy, ...) on your .html)
Update:
Evidence:

Resources