How Can I Center an HTA on the Screen?

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I center an HTA on the screen?

— BH

SpacerHey, Scripting Guy! AnswerScript Center

Hey, BH. Well, we have an answer for you, although it’s not perfect: we can resize (if need be) and center your window, but there will be a momentary flash on the screen when all this happens. It’s not too terribly distracting and the net effect is what you want: the HTA will be centered on screen. We were hoping to make this process a little smoother, but this approach will have to do for now.


Here’s the code for our sample HTA. (To try this out, copy the code, paste it into Notepad, and then save the file with a .hta file extension.) The part we care about (and the only part that really does much of anything) is the Window_Onload subroutine, a subroutine which automatically runs any time the HTA is loaded or refreshed:

<html>
<head>

<title>Centered HTA</title>

<HTA:APPLICATION
ID=”objHTA”
APPLICATIONNAME=”Centered HTA”
SCROLL=”yes”
SINGLEINSTANCE=”yes”
>
</head>

<SCRIPT Language=”VBScript”>
Sub Window_Onload
strComputer = “.”
Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
Set colItems = objWMIService.ExecQuery(“Select * From Win32_DesktopMonitor”)
For Each objItem in colItems
intHorizontal = objItem.ScreenWidth
intVertical = objItem.ScreenHeight
Next
intLeft = (intHorizontal – 800) / 2
intTop = (intVertical – 600) / 2
window.resizeTo 800,600
window.moveTo intLeft, intTop
End Sub
</SCRIPT>

<body></body>
</html>


Start this HTA and – after a brief flash – the window will be resized to 800 pixels by 600 pixels, and will be centered onscreen.


Good question: what is going on here? Well we start off with some standard WMI code that connects to the WMI service on the local computer and then queries the Win32_DesktopMonitor class.







Note. We’re assuming that you have only one monitor connected to your machine. If you have multiple monitors you might have to add a WHERE clause that ensures you will retrieve the screen height and width of the primary monitor.



After connecting to the Win32_DesktopMonitor class we then use these two lines of code to determine the current screen dimensions:

intHorizontal = objItem.ScreenWidth
intVertical = objItem.ScreenHeight

We’ve already decided, in advance, that we want our HTA window to be 800 pixels wide by 600 pixels high. Therefore we can use this code to figure out where the top left-hand corner of the window needs to be positioned:

intLeft = (intHorizontal – 800) / 2
intTop = (intVertical – 600) / 2

As you can see, we’re taking the screen width (stored in the variable intHorizontal) and subtracting 800 pixels (the horizontal size of the HTA window). Let’s assume we have a monitor resolution of 1024×768. Subtracting 800 from 1024 leaves us with 224: that tells how us how much wider the screen is than our HTA window. To center the window, we just need to make sure we have 112 pixels on each side; that’s why we divide 224 (intHorizontal – 800) by 2.


We then repeat the process for the screen height. On our sample monitor, that gives us 768 – 600, or 168. Dividing that by two leaves us with 84 pixels above and below the window.


And that leaves us with two final chores. First, we resize the window to 800 pixels by 600 pixels:

window.resizeTo 800,600

Next, we position the window accordingly. That’s what we do here:

window.moveTo intLeft, intTop

All we’re doing is calling the moveTo method and moving the HTA window so that the top left-hand corner is located 112 pixels in from the left and 84 pixels down from the top.


Incidentally, we put the resizeTo method near the bottom of the subroutine for educational purposes: we wanted to talk about resizeTo and moveTo at the same time. However, you’ll get a slightly less-distracting flash if you start the subroutine off by resizing the window:

Sub Window_Onload
window.resizeTo 800,600
strComputer = “.”
Set objWMIService = GetObject(“Winmgmts:\\” & strComputer & “\root\cimv2”)
Set colItems = objWMIService.ExecQuery(“Select * From Win32_DesktopMonitor”)
For Each objItem in colItems
intHorizontal = objItem.ScreenWidth
intVertical = objItem.ScreenHeight
Next
intLeft = (intHorizontal – 800) / 2
intTop = (intVertical – 600) / 2
window.moveTo intLeft, intTop
End Sub

It’s not a big deal, but it helps a little. And we’ll continue to hunt for ways to eliminate the flashing. (Why is that so difficult? Well, ideally, we’d hide the HTA window until it has been resized and moved, something you can do with Internet Explorer. However, we haven’t found a way to do that with HTAs. But we haven’t given upon that.)