Hey, Scripting Guy! Question

Hey, Scripting Guy! I have an HTA where information gets written to a text area. How can I print just the information found in that text area?

-- DS

SpacerHey, Scripting Guy! AnswerScript Center

Hey, DS. We want you to level with us here: are the Scripting Guys dead? We ask that because we saw the movie The Sixth Sense a few years ago and we understand how this life/death thing works. If you’re familiar with The Sixth Sense, you’ll recall that there were all these eerie happenings and coincidences which could only be explained by one thing: the protagonist (Bruce Willis) was dead. That made for a nifty little movie, only now we Scripting Guys seem to be involved with a bunch of eerie happenings ourselves; after all, in the span of three days we received two emails from people asking these very same question: how can I print just the text area of an HTML Application (HTA)? Coincidence? Let’s hope so; otherwise there can be only one explanation: the Scripting Guys are dead.

Note. Hey, don’t worry about us. After all, one of the nice things about being a Scripting Guy is that it doesn’t matter much whether we’re dead or alive: our days go pretty much the same either way.

Of course, the premise of The Sixth Sense is that even though Bruce Willis was dead he refused to acknowledge it. Taking a page from Bruce’s book, we’ve decided to go ahead and answer your question as if we were are still alive, too. And we were able to come up with an answer for you, even if it was somewhat less-than-elegant. For some reason we had the notion that there was a very straightforward way to print just the information found in a text area, but when we went looking for that answer we couldn’t find it. After a brief but fruitless search we gave up and came up with a workaround that accomplishes the same thing. (And, yes, had we been alive we might have had the energy to search a little harder. But we suppose you have to expect some drawbacks to being dead.)

At any rate, here’s a very simple HTA that contains just two items: a text area named DataArea and a button labeled Print. Any time you click the Print button the HTA saves the information in the text area to a temporary file and then uses the Shell.Application object to print that file. Here’s what the HTA code looks like:

<html>
<head>
<title>HTA Test</title>
<HTA:APPLICATION 
     ID="objTest" 
     APPLICATIONNAME="HTA Test"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
>
</head>

<SCRIPT LANGUAGE="VBScript">

    Sub PrintText
        strText = DataArea.Value

        Set objFSO = CreateObject("Scripting.FileSystemObject")
        strFileName = "temporary_print_file.txt"
        Set objFile = objFSO.CreateTextFile(strFileName)
        objFile.Write strText
        objFile.Close

        Set objFile = objFSO.GetFile(strFileName)
        strPath = objFSO.GetParentFolderName(objFile)

        Set objShell = CreateObject("Shell.Application")
        Set objFolder = objShell.Namespace(strPath) 
        Set objFolderItem = objFolder.ParseName(strFileName)
        objFolderItem.InvokeVerbEx("Print")

    End Sub

</SCRIPT>

<body>
    <textarea name="DataArea" rows=5 cols=70></textarea><p>
    <input id=runbutton  type="button" value="Print" name="run_button" onClick="PrintText">
</body>
</html>

Note. Before we begin explaining how this all works we should note that we won’t discuss the code involved in creating the HTA itself; our focus will be solely on the script that prints the information found in the text area. If you need some background information on creating HTAs then you might check out our HTA Developer’s Center.

So how do we print the information found in the text area? Well, we start by grabbing the information found in the text area and storing it in a variable named strText:

strText = DataArea.Value

After we’ve done that we encounter a block of code that creates an instance of the FileSystemObject and provides a file name (temporary_print_file.txt) for our temporary print file. We then call the CreateTextFile method to create this file (by default it will be created in the same folder as the HTA itself). As soon as the file has been created we call the Write method to write the value of strText to the file, then close the file. All that takes place here:

Set objFSO = CreateObject("Scripting.FileSystemObject")
strFileName = "temporary_print_file.txt"
Set objFile = objFSO.CreateTextFile(strFileName)
objFile.Write strText
objFile.Close

What did that gain us? Well, we’ve now taken all the information found in the text area and saved it to a separate text file. That means that, in order to print just the information in the text area, we don’t have to do anything any more complicated than simply printing the text file. And that’s what we do here:

Set objFile = objFSO.GetFile(strFileName)
strPath = objFSO.GetParentFolderName(objFile)

Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(strPath) 
Set objFolderItem = objFolder.ParseName(strFileName)
objFolderItem.InvokeVerbEx("Print")

Yes, that looks a tiny bit complicated, but that’s primarily because of the eccentricities of the Shell object: in particular, the Shell object requires us to take a slightly roundabout path before we can bind to - and then print - the file. But don’t let the looks deceive you: if you’ve seen The Sixth Sense then you know that things aren’t always what they seem.

In other words, we first use the GetFile method to bind the FileSystemObject to our temporary file. After that we call the GetParentFolderName method to determine the path to the folder where the temporary file lives (for example, if our temporary file is named C:\Scripts\temporary_print_file.txt then the parent folder will be C:\Scripts). That’s what the first two lines of code do:

Set objFile = objFSO.GetFile(strFileName)
strPath = objFSO.GetParentFolderName(objFile)

Once the folder path is stashed away in the variable strPath we can then create the Shell.Application object and use the Namespace method to bind to the folder. In turn, we can call the ParseName method on that folder, passing as the sole parameter the variable strFileName (which is storing the name of the temporary file for us). That’s somewhat-goofy syntax, but the net result is that by binding to a folder and then passing ParseName the name of a file within that folder we get a FolderItem object pointing directly to our text file. Is that good? You bet it is: once the Shell object is bound to the file we can then use the InvokeVerbEx method to call any of the commands that appear on the context menu of that file.

Is that good? Of course. If you right-click a .txt file, one of the commands available to you is Print; if you then click Print the file will automatically be printed to the default printer. As we noted, the InvokeVerbEx method enables us to run any of the commands found on the context menu of a file. To call the Print command, and thus automatically print the file to the default printer, all we need to do is execute this line of code:

objFolderItem.InvokeVerbEx("Print")

Note. What if you don’t like the way the text file prints out? In that case, try saving the file as temporary_print_file.htm and see if you like that printout any better.

That’s all we need to do. Once the file has been sent to the printer we’re home free.

Pretty cool, huh? We have to tell you, it’s scripts like this one that make you glad to be alive.

Well, for those of you who are alive, that is.