HTML-приложения

Опубликовано: 09.12.2009
Автор: Виталий Бочкарев
Поддержать автора статьи по этой ссылке
Введение

До определенного момента развития информационных технологий программы могли создавать только профессионалы в области программирования, с появлением и последующим развитием скриптовых языков, а также браузерных технологий, создание приложений стало более простым для обычного пользователя компьютера. Итак, HTA (HTML Application) - это простая технология, позволяющая создавать полезные приложения даже без знания серьезных языков программирования.

Создать HTA-приложение можно, просто написав HTML-страницу и сохранив ее с расширением .hta, которое обрабатывается программой mshta.exe, её задача - обеспечить связь вашей программы с браузером. Так как такие приложения используют движок браузера, то они объединяют в себе все их возможности - их объектную модель, разметку страницы (HTML), каскадные листы стилей (CSS), скрипты (VBS и JS). Также на такие приложения не накладывается ограничения безопасности - они работают как любой исполняемый файл.

То есть при помощи HTML создается абсолютно любой пользовательский интерфейс, причем с минимальными усилиями и без каких-либо существенных ограничений, логика программы организуется кодом на Java Script или Visual Basic Script, а само приложение выходит за рамки браузера - программа на стадии выполнения ничем не будет отличаться от обычных оконных приложений для Windows - запущенное приложение будет присутствовать на панели задач, иметь собственные окно, меню и значок. Хотя здесь нужно оговориться: программа не будет видна среди запущенных приложений в диспетчере задач, единственное средство, которым можно контролировать запущенную программу - это процесс mshta.exe.

Создание приложения

HTA-приложения можно писать в любом текстовом редакторе или специализированном HTML-конструкторе. Я, например, пользуюсь программой Notepad2.

Чтобы создать новое приложение, откроем блокнот, скопируем туда структуру HTML документа и сохраним как htm-файл.

<html>
	   <head>
	       <title>Моё HTA-приложение</title>
	   </head>
	   <body>
	       <div>Мое тестовое HTA-приложение</div>
	   </body>
	</html>

Итак, мы получили HTML-документ, который уже можно посмотреть в браузере. Теперь, чтобы сделать из этой страницы HTA-приложение, необходимо изменить расширение HTML-документа на .hta, после чего его можно запустить двойным щелчком по файлу.

Для того чтобы полностью использовать возможности таких приложений, необходимо в раздел <head> включить тэг <hta:application>. Преобразуем наш тестовый файл таким образом:

<html>
	   <head>
	       <title>Моё HTA-приложение</title>
	       <hta:application
	           id="oHTA"
	           ApplicationName = "MyTestHTA"
	           Border = "dialog"
	           Caption = "yes"
	           Scroll = "no"
	           SingleInstance = "yes"
	           SysMenu = "yes"
	           WindowState = "normal"
	           Version = "1.1"
	       />
	   </head>
	   <body>
	       <div>Моё тестовое HTA-приложение</div>
	   </body>
	</html>

Расширение .hta указывает системе, как работать с приложением, а специальный тэг <hta:application> указывает, как отображать окно. Этот тэг предоставляет набор атрибутов, управляющих свойствами окна приложения.

Атрибуты и свойства тега <hta:application>

Итак, чтобы указать HTA-приложению, как отобразить окно программы, необходимо задать атрибуты тега <hta:application>.

Помимо управлением окном приложения, этот тег также дает возможность обращаться к свойствам приложения из скриптов, расположенных в коде HTA-приложения. Стоит заметить, что все свойства этого тега доступны только для чтения.

Атрибут и свойство id

Определяет идентификатор объекта - уникального имени внутри файла HTA-приложения.

Атрибут и свойство ApplicationName

Содержит имя приложения. Если свойствоSingleInstanceустановлено в "True", то значение ApplicationName автоматически проверяется перед запуском экземпляра приложения. Чтобы проверка была успешной, значение ApplicationName должно быть уникальным. То есть, значение свойства ApplicationName используется для идентификации единственности запущенного приложения.

Атрибут и свойство Border

Содержит тип бордюра окна. Свойство Border влияет на толщину бордюра и действительно только для окон HTA, у которых есть панель заголовка и сам заголовок. УстанавливаяBorderв "None", вы убираете панель заголовка, иконку программы, и кнопки максимизирования и минимизирования. Это свойство может быть использовано совместно со свойством BorderStyle. Возможные значения:

Dialog Бордюр диалогового окна - пользователь не может изменить размер окна.
None Окно без бордюра.
Thick Толстый бордюр окна, плюс бордюр для изменения размера окна. (Значение по умолчанию).
Thin Тонкий бордюр окна с заголовком.
Атрибут и свойство BorderStyle

Содержит стиль бордюра клиентской области окна. Свойство BorderStyle устанавливает стиль для бордюра содержимого окна, в то время как свойство Border контролирует бордюр окна приложения. Возможные значения:

Complex Приподнятый и утопленный бордюр.
Normal Нормальный бордюр. (Значение по умолчанию).
Raised Приподнятый 3-D бордюр.
Static 3-D бордюр, обычно используемый для окон, не обрабатывающих ввод пользователя.
Sunken Утопленный 3-D бордюр.
Атрибут и свойство Caption

Определяет, будет ли в окне HTML приложения отображаться панель заголовка. Заголовок приложения отображается только тогда, когда свойствоCaptionустановлено в "Yes". Отключение свойстваCaptionтакже отключит кнопки "Свернуть", "Развернуть" и программную иконку. В этом случае нужно не забыть предоставить альтернативный способ выхода из приложения, например, кнопку "Закрыть" на форме приложения, вызывающую метод Window.Close. Возможные значения:

Yes Панель заголовка отображается. (Значение по умолчанию).
No Панель заголовка не отображается.
Свойство CommandLine

Строка, которая содержит путь и параметры командной строки, которые использовались для запуска HTA-приложения. Если HTA-приложение было запущено с использованием HTTP протокола, свойство CommandLine содержит пустую строку.

Атрибут и свойство ContextMenu

Определяет, появляется ли контекстное меню при нажатии на правую кнопку мыши. Возможные значения:

Yes Контекстное меню появляется. (Значение по умолчанию).
No Контекстное меню не появляется.
Атрибут и свойство Icon

Определяет путь к файлу иконки, используемой в HTML приложении. HTA использует системную иконку, если значение не определено. АтрибутIcon распознаёт стандартные файлы с расширением .ico, содержащие изображение размером 32x32 пикселя, а также успешно распознаёт первую иконку из файлов "*.exe", "*.icl" (библиотека иконок), "*.dll", и "*.ocx".

Атрибут и свойство InnerBorder

Определяет, отображается ли внутренняя 3-D граница. Возможные значения:

Yes Внутренняя 3-D граница отображается. (Значение по умолчанию).
No Внутренняя 3-D граница не отображается.
Атрибут и свойство MaximizeButton

Определяет, отображается ли кнопка "Развернуть" на панели заголовка окна HTML приложения. Чтобы отображались кнопки "Свернуть" и "Развернуть", окно должно иметь панель заголовка (атрибут Caption). Возможные значения:

Yes Кнопка "Развернуть" отображается. (Значение по умолчанию).
No Кнопка "Развернуть" не отображается.
Атрибут и свойство MinimizeButton

Определяет, отображается ли кнопка "Свернуть" на панели заголовка окна HTML приложения. Чтобы отображались кнопки "Свернуть" и "Развернуть", окно должно иметь панель заголовка (атрибут Caption). Возможные значения:

Yes Кнопка "Свернуть" отображается. (Значение по умолчанию).
No Кнопка "Свернуть" не отображается.
Атрибут и свойство Navigable

Определяет, в каком окне будут открываться загружаемые документы. Возможные значения:

No Будут открываться в новых окнах. (Значение по умолчанию).
Yes Будут открываться в основном окне.
Атрибут и свойство Scroll

Определяет, будут ли отображаться полосы прокрутки. Возможные значения:

Yes Полосы прокрутки отображаются. (Значение по умолчанию).
No Полосы прокрутки не отображаются.
Auto Полосы прокрутки появляются только тогда, когда содержимое документа не умещается в клиентской области окна.
Атрибут и свойство ScrollFlat

Определяет, в каком виде будут отображаться полосы прокрутки. Возможные значения:

Yes Полосы прокрутки двухмерные.
No Полосы прокрутки трёхмерные. (Значение по умолчанию).
Атрибут и свойство Selection

Определяет, может ли содержимое документа быть выбрано мышкой или с помощью клавиатуры. Значение "No" запрещает появление контекстного меню и присвоение атрибуту ContextMenu значения "Yes" не произведёт никакого эффекта. Возможные значения:

Yes Содержимое может быть выбрано. (Значение по умолчанию).
No Содержимое не может быть выбрано.
Атрибут и свойство ShowInTaskBar

Определяет, будет ли HTML приложение появляться на панели задач Windows. Возможные значения:

Yes Приложение отображается на панели задач. (Значение по умолчанию).
No Приложение не отображается на панели задач.
Атрибут и свойство SingleInstance

Определяет, может ли быть запущенно больше одного экземпляра HTML приложения одновременно. Возможные значения:

Yes Может быть запущен только один экземпляр приложения.
No Может быть запущенно несколько экземпляров приложения одновременно. (Значение по умолчанию).
Атрибут и свойство SysMenu

Определяет, отображается ли системное меню в HTML приложении. Системное меню HTA обозначается программной иконкой в левом углу панели заголовка. Системное меню HTA показывает все команды, входящие в стандартное системное меню Windows, включая "Восстановить", "Переместить", "Размер", "Свернуть", "Развернуть", и "Закрыть". Возможные значения:

Yes Системное меню отображается в панели заголовка. (Значение по умолчанию).
No Системное меню не отображается в панели заголовка.
Атрибут и свойство Version

Определяет номер версии HTML приложения.

Атрибут и свойство WindowState

Определяет начальные размеры окна HTML приложения. Возможные значения:

Normal Размер окна - стандартный размер для Microsoft Internet Explorer. (Значение по умолчанию).
Minimize Появляется только заголовок окна на панели задач.
Maximize Окно появляется развёрнутым во весь экран.
Пример использования атрибутов HTA-приложения

В данном примере используются все атрибуты тега <hta:application>, несмотря на то, что значения некоторых атрибутов перекрываются другими параметрами, или некоторые значения уже заданы по умолчанию и не требуют объявления. Это сделано для того, чтобы показать, как использовать все атрибуты данного тега. В обычной практике объявляют только те атрибуты, значения которых нужно изменить.

<html>
	   <head>
	       <title>Моё HTA-приложение</title>
	       <hta:application
	           id = "oHTA"
	           ApplicationName = "MyTestApplication"
	           Border = "Dialog"
	           BorderStyle = "Complex"
	           Caption = "Yes"
	           ContextMenu = "No"
	           Icon = "C:\Program Files\Windows NT\hypertrm.exe"
	           InnerBorder = "No"
	           MaximizeButton = "No"
	           MinimizeButton = "No"
	           Navigable = "No"
	           Scroll = "No"
	           ScrollFlat = "No"
	           Selection = "No"
	           ShowInTaskBar = "No"
	           SingleInstance = "Yes"
	           SysMenu = "Yes"
	           Version = "1.2"
	           WindowState = "Normal"
	       />
	   </head>
	   <body>
	       <h1>Пример использования атрибутов HTA-приложения</h1>
	       <div>
	           Данное приложение имеет следующие вид:<br />
	           <ol>
	               <li>бордюр: неизменяемый;</li>
	               <li>стиль бордюра: приподнятый и утопленный;</li>
	               <li>заголовок окна: присутствует;</li>
	               <li>иконка: от программы Hyper Terminal;</li>
	               <li>внутренняя 3-D граница: не отображается;</li>
	               <li>кнопка "развернуть": отсутсвует;</li>
	               <li>кнопка "свернуть": отсутсвует;</li>
	               <li>загружаемые документы: открываются в новом окне;</li>
	               <li>полосы прокрутки: не отображаются;</li>
	               <li>стиль полос прокрутки: трёхмерный;</li>
	               <li>содержимое документа быть выбрано мышкой: нет;</li>
	               <li>приложение появляетсяя на панели задач: нет;</li>
	               <li>запускается только один экземляр приложения: да;</li>
	               <li>системное меню: присутствует;</li>
	               <li>размер окна: обычный.</li>
	           </ol>
	       </div>
	       <div style="text-align: right;">
	           <input id="CloseButton" type="button" value="Закрыть" onclick="window.close()" />
	       </div>
	   </body>
	</html>
Скрипты в HTA-приложениях

Так как HTA-приложения, по сути, являются HTML-страничками, то в них можно использовать скриптовые языки. Так как я хорошо знаю язык Visual Basic Script , то все последующие примеры будут основаны на нем, тем не менее Вы можете использовать как VBS, так и JS для создания своих приложений.

Скрипты пишутся в теге <script> и располагаются в разделе <head> либо во внешнем файле. В разделе скриптов описывают действия, которые выполняются при определенных событиях элементов формы приложения. Например, чтобы приложение выполнило скрипт при загрузке формы (инициализации программы), необходимо в теге <body> указать процедуру, которая должна запуститься по событию OnLoad, а сами действия описать в теге <script>.

Наиболее востребованным скриптом при загрузке формы является изменение размеров окна и размещение его по центру экрана.

Пример использования скриптов

Изменим наш пример следующим образом: удалим неиспользуемые атрибуты тега <hta:application>, добавим скрипт изменения размера окна, добавим скрипт вывода версии скрипта на форму, а содержание формы оформим невидимой таблицей для того, чтобы каждый элемент стоял на своем месте вне зависимости от содержания формы.

<html>
	   <head>
	       <title>Моё HTA-приложение</title>
	       <hta:application
	           id = "oHTA"
	           ApplicationName = "MyTestApplication"
	           Border = "Dialog"
	           BorderStyle = "Complex"
	           Icon = "C:\Program Files\Windows NT\hypertrm.exe"
	           InnerBorder = "No"
	           MaximizeButton = "No"
	           MinimizeButton = "No"
	           Scroll = "No"
	           Selection = "No"
	           ShowInTaskBar = "No"
	           SingleInstance = "Yes"
	           Version = "1.3"
	       />
	       <script language="VBScript">
	           ' Процедура инициализации окна формы
	           Sub WindowOnLoad
	               ' Размер окна
	               iWidth = 800
	               iHeight = 600
	               ' Разрешение экрана по умолчанию
	               iHorizontal = 1024
	               iVertical = 768
	               ' Получение текущего разрешения экрана
	               Set oWMIService = GetObject("winmgmts:\\.\root\cimv2")
	               Set colItems = oWMIService.ExecQuery("Select * From Win32_DesktopMonitor")
	               For Each oItem in ColItems
	                   iHorizontal = oItem.ScreenWidth
	                   iVertical = oItem.ScreenHeight
	                   Exit For
	               Next
	               ' Изменение размера окна и его центрирование
	               iLeft = (iHorizontal - iWidth) / 2
	               iTop = (iVertical - iHeight) / 2
	               Self.Focus()
	               Self.resizeTo iWidth, iHeight
	               Self.moveTo iLeft, iTop
	               ' Вывод версии приложения на форму
	               Version_Div.InnerHTML = "Версия: " & oHTA.Version
	           End Sub
	       </script>
	   </head>
	   <body onload="WindowOnLoad()">
	       <table style="height: 100%; width: 100%;">
	           <tr style="height:50px;">
	               <td><h1>Моё HTA-приложение</h1></td>
	           </tr>
	           <tr style="vertical-align: top;">
	               <td>
	                   <div>
	                   Данное приложение имеет следующие вид:<br />
	                   <ol>
	                       <li>бордюр: неизменяемый;</li>
	                       <li>стиль бордюра: приподнятый и утопленный;</li>
	                       <li>заголовок окна: присутствует;</li>
	                       <li>иконка: от программы Hyper Terminal;</li>
	                       <li>внутренняя 3-D граница: не отображается;</li>
	                       <li>кнопка "развернуть": отсутсвует;</li>
	                       <li>кнопка "свернуть": отсутсвует;</li>
	                       <li>загружаемые документы: открываются в новом окне;</li>
	                       <li>полосы прокрутки: не отображаются;</li>
	                       <li>стиль полос прокрутки: трёхмерный;</li>
	                       <li>содержимое документа быть выбрано мышкой: нет;</li>
	                       <li>приложение появляетсяя на панели задач: нет;</li>
	                       <li>запускается только один экземляр приложения: да;</li>
	                       <li>системное меню: присутствует;</li>
	                       <li>размер окна: обычный.</li>
	                   </ol>
	                   </div>
	               </td>
	           </tr>
	           <tr style="height:30px;">
	               <td>
	                   <div id="Version_Div" style="float: left">
	                       Версия: X.X
	                   </div>
	                   <div style="float: right">
	                       <input id="CloseButton" type="button" value="Закрыть"
	                         onclick="window.close()" />
	                   </div>
	               </td>
	           </tr>
	       </table>
	   </body>
	</html>
Взаимодействие с операционной системой

HTA-приложения очень удобны для централизации сценариев управления ИТ-инфраструктурой компании, которые администратор использует повседневно. Прежде чем мы создадим такое приложение, необходимо ознакомиться с особенностями взаимодействия скриптов HTA-приложений с операционной системой.

Взаимодействие приложения с операционной системой осуществляется путем внедрения в код специальных скриптов. Такие скрипты не просто выполняют логику приложения, они через специальные библиотеки отправляют запросы операционной системе, а операционная система возвращает им запрошенные данные или выполняет необходимые действия.

Методы и свойства корневого класса WScript

В HTA нельзя напрямую использовать методы и свойства базового класса WScript. Методы CreateObject(<Library>.<Class>), GetObject(<FilePath>), ConnectObject(<Object>, <Prefix>), DisconnectObject(<Object>) вызываются без указания родительского класса, а все остальные методы базового класса не доступны для использования.

Иначе говоря, нельзя вызвать такой простой, но очень полезный метод, как WScript.Sleep. Чтобы обойти это ограничение, необходимо использовать методы с аналогичными действиями из других библиотек. Ниже представлен пример процедуры, которая замещает отсутствующий метод WScript.Sleep.

Sub ccSleep(seconds)
	   Set oShell = CreateObject("Wscript.Shell")
	   sCommand = "%COMSPEC% /c ping -n " & 1 + seconds & " 127.0.0.1>nul"
	   oShell.Run sCommand,0,1
	End Sub

Данная процедура использует такое свойство стандартной команды ping, что интервал между отправками пакетов к хосту 1 секунда. То есть если нам требуется задержка в выполнении сценария в 1 секунду, то нужно отправить 2 пакета, интервал между ними и будет 1 секунда. Второй момент данного способа в том, что пакеты посылаются на хост-заглушку 127.0.0.1 - то есть самому себе, поэтому время ответа от хоста равно миллисекундам и мало влияет на расчет времени между отправками пакетов. Третий момент - это выполнение команды ping в скрытом режиме.

Методы и свойства класса Shell

Для работы с операционной системой используется специальный класс Shell, который позволяет выполнять такие операции как запуск программ, изменение реестра, создание ярлыков, доступ к системным папкам и системным переменным, доступ к системному журналу.

Наиболее востребованной процедурой являются запуск внешнего приложения. Ниже представлен пример процедуры запуска приложения.

Sub RunApplication(sApplication)
	   sCommandLine =""
	   Set oShell = CreateObject("Wscript.Shell")
	   Select Case sApplication
	       Case "CommandPrompt"
	           sCommandLine = "%ComSpec%"
	       Case "TestScript"
	           sCommandLine = "%COMSPEC% /C CScript C:\Scripts\Test.vbs"
	       Case "FarManager"
	           sCommandLine = "C:\FarManager\Far.exe"
	       Case "Notepad"
	           sCommandLine = "notepad.exe"
	       Case Else
	           sCommandLine =""
	   End Select
	   If Len(sCommandLine) > 0 Then oShell.Run sCommandLine,1,0
	End Sub

Данная процедура в качестве параметра получает идентификатор элемента, вызвавшего ее, выбирает нужную командную строку и запускает ее, если строку запуска удалось подобрать.

Методы и свойства класса FileSystemObject

Очень часто встречаются такие случаи, когда необходимо что-то создать, удалить, переместить или изменить на диске компьютера. Эту задачу позволяет решить класс FileSystemObject, предназначенный для работы с файловой системой.

Наиболее распространенная задача из операций с файловой системой - это чтение файла. Ниже представлена функция чтения текстового файла, которая в качестве параметра принимает путь к файлу, а отдает массив строк считанного файла.

Function ReadFile(sFileName)
	   Set oFSO = CreateObject("Scripting.FileSystemObject")
	   Set oInFile = oFSO.OpenTextFile(sFileName, 1, False, 0)
	   sFileContent = oInFile.ReadAll
	   oInFile.Close
	   ReadFile = sFileContent
	End Function

Еще одна полезная функция - это проверка существования файла, например, перед запуском внешней программы или перед считыванием текстового файла. Входным параметром функции является путь к файлу, выходным - логическая переменная.

Function CheckFile(sFilePath)
	   Set oFSO = CreateObject("Scripting.FileSystemObject")
	   If oFSO.FileExists(sFilePath) Then
	       CheckFile = True
	   Else
	       CheckFile = false
	   End If
	End Function
Классы Windows Management Instrumentation

Windows Management Instrumentation (WMI) - это набор интерфейсов для управления операционной системой через специальные компоненты, причем как локально, так и по сети. Это очень богатый набор инструментов, с помощью которого можно выполнить любое действие в среде семейства Windows.

Наиболее простым и востребованным примером использования WMI является определение параметров дисплея пользователя для центрирования формы приложения на экране.

Function GetDisplayResolution()
	   Set oWMIService = GetObject("winmgmts:\\.\root\cimv2")
	   Set colItems = oWMIService.ExecQuery("Select * From Win32_DesktopMonitor")
	   For Each oItem In colItems
	       iHorizontal = oItem.ScreenWidth
	       iVertical = oItem.ScreenHeight
	   Exit For
	   Next
	   GetDisplayResolution = iHorizontal & ";" & iVertical
	End Function

Второй пример использования WMI также полезен и часто используется - это функция определения доступности компьютера в сети.

Function PingComputer(sComputer)
	   Set oPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery("SELECT" & _
	      * FROM Win32_PingStatus WHERE address = '" & sComputer & "'")
	   For Each oStatus In oPing
	       If IsNull(oStatus.StatusCode) Or oStatus.StatusCode <> 0 Then
	           PingComputer = False
	       Else
	           PingComputer = True
	       End If
	   Next
	End Function
Пример использования функций взаимодействия с операционной системой

Преобразуем наше приложение следующим образом: изменим текст формы, добавим все вышеописанные примеры, на форме разместим несколько кнопок для запуска заданий, в директории, где располагается файл HTA-приложения, создадим папку "MyHTA_files", в которой разместим несколько файлов:

  • text.txt- любой текстовый файл;
  • test.vbs- файл, содержащий только одну строку:MsgBox("Hello script!");
  • MyHTA.ico- любая иконка;
  • MyHTA.vbs- файл, содержащий все вышеописанные скрипты.

Листинг файла "MyHTA.hta"

<html>
	   <head>
	       <title>Моё HTA-приложение</title>
	       <hta:application
	           Id = "oHTA"
	           ApplicationName = "MyTestApplication"
	           Border = "Dialog"
	           Icon = "MyHTA_files\MyHTA.ico"
	           InnerBorder = "No"
	           MaximizeButton = "No"
	           MinimizeButton = "No"
	           Scroll = "No"
	           Selection = "No"
	           ShowInTaskBar = "No"
	           SingleInstance = "Yes"
	           Version = "1.4"
	       />
	       <script src="MyHTA_files/MyHTA.vbs" type="text/vbscript"></script>
	   </head>
	   <body onload="WindowOnLoad()">
	       <table style="height: 100%; width: 100%;">
	           <tr style="height:40px;">
	               <td><h1>Моё HTA-приложение</h1></td>
	           </tr>
	           <tr>
	               <td>
	                   <div style="text-align: center;">
	                   <input id="CommandPrompt" type="button" value="Командная строка"
	                     onclick="RunApplication(me.id)" />
	                   <input id="TestScript" type="button" value="Сценарий test.vbs"
	                     onclick="RunApplication(me.id)" />
	                   <input id="TextFile" type="button" value="Файл test.txt"
	                     onclick="RunApplication(me.id)" />
	                   <input id="TempDir" type="button" value="Папка Temp"
	                     onclick="RunApplication(me.id)" />
	                   </div>
	               </td>
	           </tr>
	           <tr style="height:30px;">
	               <td>
	                   <div id="Version_Div" style="float: left;">Версия: X.X</div>
	                   <div style="float: right;">
	                       <input id="Button5" type="button" value="Закрыть"
	                         onclick="window.close()" />
	                   </div>
	               </td>
	           </tr>
	       </table>
	   </body>
	</html>

Листинг файла "MyHTA_files\MyHTA.vbs"

' Процедура инициализации окна формы
	Sub WindowOnLoad
	   Dim CurrentResolution
	   ' Размер окна
	   iWidth = 800
	   iHeight = 600
	   ' Получение текущего разрешения экрана
	   CurrentResolution = GetDisplayResolution()
	   ' Изменение размера окна и его центрирование
	   iLeft = (Split(CurrentResolution,";")(0) - iWidth) / 2
	   iTop = (Split(CurrentResolution,";")(1) - iHeight) / 2
	   Self.Focus()
	   Self.resizeTo iWidth, iHeight
	   Self.moveTo iLeft, iTop
	   ' Вывод версии приложения на форму
	   Version_Div.InnerHTML = "Версия: " & oHTA.Version
	End Sub
	
	Sub RunApplication(sApplication)
	   sCommandLine =""
	   Set oShell = CreateObject("Wscript.Shell")
	   Select Case sApplication
	       Case "CommandPrompt"
	           sCommandLine = "%ComSpec%"
	       Case "TestScript"
	           If CheckFile(oShell.CurrentDirectory & "\MyHTA_files\Test.vbs") = True Then
	               sCommandLine = "WScript """ & oShell.CurrentDirectory & _
	                 "\MyHTA_files\Test.vbs"""
	           Else
	               MsgBox("Файл не найден")
	           End If
	       Case "TextFile"
	           If CheckFile(oShell.CurrentDirectory & "\MyHTA_files\Test.txt") = True Then
	               sCommandLine = "Notepad """ & oShell.CurrentDirectory & _
	                 "\MyHTA_files\Test.txt"""
	           Else
	               MsgBox("Файл не найден")
	           End If
	       Case "TempDir"
	           sCommandLine = "Explorer " & oShell.ExpandEnvironmentStrings("%Temp%")
	       Case Else
	           sCommandLine =""
	   End Select
	   If Len(sCommandLine) > 0 Then oShell.Run sCommandLine,1,0
	End Sub
	
	Function ReadFile(sFileName)
	   Set oFSO = CreateObject("Scripting.FileSystemObject")
	   Set oInFile = oFSO.OpenTextFile(sFileName, 1, False, 0)
	   sFileContent = oInFile.ReadAll
	   oInFile.Close
	   ReadFile = sFileContent
	End Function
	
	Function CheckFile(sFilePath)
	   Set oFSO = CreateObject("Scripting.FileSystemObject")
	   If oFSO.FileExists(sFilePath) Then
	       CheckFile = True
	   Else
	       CheckFile = false
	   End if
	End Function
	
	Function GetDisplayResolution()
	   Set oWMIService = GetObject("winmgmts:\\.\root\cimv2")
	   Set colItems = oWMIService.ExecQuery("Select * From Win32_DesktopMonitor")
	   For Each oItem In colItems
	       iHorizontal = oItem.ScreenWidth
	       iVertical = oItem.ScreenHeight
	   Exit For
	   Next
	   GetDisplayResolution = iHorizontal & ";" & iVertical
	End Function
	
	Function PingComputer(sComputer)
	   Set oPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery( _
	     "select * from Win32_PingStatus where address = '" & sComputer & "'")
	   For Each oStatus In oPing
	       If IsNull(oStatus.StatusCode) Or oStatus.StatusCode <> 0 Then
	           PingComputer = False
	       Else
	           PingComputer = True
	       End If
	   Next
	End Function

Итак, теперь мы имеем форму, в которой к каждой из кнопок привязано определенное действие. Чтобы оживить форму и сделать интерфейс более приятным, нам потребуется использовать таблицы стилей, а так же свойства объектов формы, которые мы будем менять динамически по мере возникновения новых событий формы.

Динамический интерфейс

Динамический интерфейс или интерфейс, меняющийся в зависимости от действий пользователя, реализуется при помощи DHTML. Реализация DHTML стоит а трёх "китах": непосредственно HTML, каскадных таблицах стилей (CSS) и языке сценариев (Java Script или Visual Basic Script). Эти три компонента DHTML связаны между собой объектной моделью документа (DOM), являющейся, по сути, интерфейсом прикладного программирования (API). DOM связывает воедино три перечисленных компонента, придавая простому документу HTML новое качество, - возможность динамического изменения своего содержимого без перегрузки страницы.

На самом деле мы уже использовали динамический интерфейс в предыдущих примерах - это изменение размера и положения формы при загрузке, а также вывод версии приложения на форму.
Пример создания динамического интерфейса

Итак, первое, что нам потребуется - это создать статическую структуру нашей формы. В нашем примере мы уже создали основу формы - таблицу. Теперь нам потребуется дополнить ее областями, которые будут принимать в себя динамические данные. Для этого изменим тело таблицы согласно схеме, показанной на рисунке.

Hypertext Applications

Листинг файла "MyHTA.hta"

<html>
	 <head>
	   <title>Моё HTA-приложение</title>
	   <hta:application
	       Id = "oHTA"
	       ApplicationName = "MyTestApplication"
	       Border = "Dialog"
	       Icon = "MyHTA_files\MyHTA.ico"
	       InnerBorder = "No"
	       MaximizeButton = "No"
	       MinimizeButton = "No"
	       Scroll = "No"
	       Selection = "No"
	       ShowInTaskBar = "No"
	       SingleInstance = "Yes"
	       Version = "1.5"
	   />
	   <script src="MyHTA_files/MyHTA.vbs" type="text/vbscript"></script>
	   <link href="MyHTA_files/MyHTA.css" rel="stylesheet" type="text/css" media="screen" />
	 </head>
	 <body onload="WindowOnLoad()">
	   <table>
	     <tr class="Header_Row">
	       <td colspan="2">
	         <h1>Моё HTA-приложение</h1>
	       </td>
	     </tr>
	     <tr class="Content_Row">
	       <td id="StaticMenu_Cell">
	         <input id="CommandPrompt" type="button" value="Командная строка"
	           onclick="RunApplication(me.id)" />
	         <input id="TestScript" type="button" value="Сценарий test.vbs"
	           onclick="RunApplication(me.id)" />
	         <input id="TextFile" type="button" value="Файл test.txt"
	           onclick="RunApplication(me.id)" />
	         <input id="TempDir" type="button" value="Папка Temp"
	           onclick="RunApplication(me.id)" />
	       </td>
	       <td id="DynamicContent_Cell">
	         <div id="DynamicContent_Div">
	           Добро пожаловать
	         </div>
	       </td>
	     </tr>
	     <tr class="Footer_Row">
	       <td>
	         <div id="Version_Div">
	           Версия: X.X
	         </div>
	       </td>
	       <td>
	         <div id="Button_Div">
	           <input id="CloseButton" type="button" value="Закрыть" onclick="window.close()" />
	         </div>
	       </td>
	     </tr>
	   </table>
	 </body>
	</html>

Теперь, когда структура формы готова, необходимо создать таблицу стилей, которая и будет определять внешний вид всех объектов формы. Если вы уже заметили, из разметки формы пропали все атрибуты, отвечающие за отображение объектов - теперь все атрибуты определяются CSS-файлом "MyHTA.css". Этот файл таблицы стилей располагается в папке "MyHTA_files", и подключается командой <link rel="stylesheet" /> в файле приложения "MyHTA.hta".

Листинг файла "MyHTA_files\MyHTA.css"

body
	{
	   background-color: buttonface;
	   font-family: Tahoma;
	}
	
	table
	{
	   height: 100%;
	   width: 100%;
	}
	
	.Header_Row
	{
	   height:40px;
	}
	
	.Content_Row
	{
	   vertical-align: top;
	}
	
	#StaticMenu_Cell
	{
	   width: 20%;
	   text-align: center;
	}
	
	#StaticMenu_Cell input
	{
	   width: 150px;
	   margin: 2px 2px 2px 2px;
	}
	
	#DynamicContent_Cell
	{
	   margin: 2px 2px 2px 2px;
	}
	
	#DynamicContent_Cell #DynamicContent_Div
	{
	   text-align: center;
	}
	
	#DynamicContent_Cell #DynamicContent_Div .NormalLink
	{
	   font-family: Tahoma;
	   font-size: 10pt;
	   color: black;
	   cursor: default;
	   vertical-align: text-bottom;
	   text-align: left;
	   padding-right: 20px
	}
	
	#DynamicContent_Cell #DynamicContent_Div .NormalLinkMouseOver
	{
	   font-family: Tahoma;
	   font-size: 10pt;
	   color: Navy;
	   text-decoration: underline;
	   cursor: hand;
	   vertical-align: text-bottom;
	   text-align: left;
	   padding-right: 20px
	}
	
	#DynamicContent_Cell #DynamicContent_Div .TextFile
	{
	   font-family: Tahoma;
	   font-size: 10pt;
	   text-align: left;
	}
	
	.Footer_Row
	{
	   height:30px;
	}
	
	#Version_Div
	{
	   float: left;
	}
	
	#Button_Div
	{
	   float: right;
	}

Последнее и самое сложное, что нужно сделать - это написать логику работы формы - сценарий на языке Visual Basic. Сценарий должен обрабатывать события формы и изменять ее интерфейс в зависимости от потребностей пользователя.

Первое событие, которое возникает в приложении - это загрузка формы. При этом событии сценарий должен получить от системы разрешение экрана, отцентровать форму и изменить ее размеры. Далее могут возникать события нажатия кнопок, при которых нужно определять нажатую кнопку, выполнять соотвествующую команду и перерисовать динамическую зону формы. Последнее событие - это нажатие на кнопку "Закрыть", при котором форма закрывает себя.

Если более подробно рассмотреть событие нажатия кнопки "Файл test.txt", то можно выделить несколько этапов логики:

  1. проверка наличия файла на диске компьютера;
  2. вывод в динамическую зону вопроса о том, как отобразить текстовый файл - создание двух новых объектов с обработкой событий "при нажатии";
  3. обработка события выбранного отбъекта - открыть в блокноте или вывести на форму;
  4. открытие тектового файла в блокноте, если выбрано это действие;
  5. вывод в динамическую зону формы содержимого текстового файла, если выбрано это действие.

Сценарий-обработчик событий располагается в папке "MyHTA_files", и подключается командой <script type="text/vbscript"></script> в файле приложения "MyHTA.hta".

Листинг файла "MyHTA_files\MyHTA.vbs"

' Процедура инициализации окна формы
	Sub WindowOnLoad
	   Dim CurrentResolution
	   ' Размер окна
	   iWidth = 800
	   iHeight = 600
	   ' Получение текущего разрешения экрана
	   CurrentResolution = GetDisplayResolution()
	   ' Изменение размера окна и его центрирование
	   iLeft = (Split(CurrentResolution,";")(0) - iWidth) / 2
	   iTop = (Split(CurrentResolution,";")(1) - iHeight) / 2
	   Self.Focus()
	   Self.resizeTo iWidth, iHeight
	   Self.moveTo iLeft, iTop
	   ' Вывод версии приложения на форму
	   Version_Div.InnerHTML = "Версия: " & oHTA.Version
	End Sub
	
	Sub RunApplication(sApplication)
	   sCommandLine =""
	   Set oShell = CreateObject("Wscript.Shell")
	   Select Case sApplication
	       Case "CommandPrompt"
	           sCommandLine = "%ComSpec%"
	            DynamicContent_Div.InnerHTML = "Командная строка открыта"
	       Case "TestScript"
	           If CheckFile(oShell.CurrentDirectory & "\MyHTA_files\Test.vbs") = True Then
	               sCommandLine = "WScript """ & oShell.CurrentDirectory & _
	                 "\MyHTA_files\Test.vbs"""
	               DynamicContent_Div.InnerHTML = "Скрипт " & oShell.CurrentDirectory & _
	                 "\MyHTA_files\Test.vbs" & " выполнен"
	           Else
	               DynamicContent_Div.InnerHTML = "Файл не найден"
	           End If
	       Case "TextFile"
	           If CheckFile(oShell.CurrentDirectory & "\MyHTA_files\Test.txt") = True Then
	               sDinamicContent = "<div>Выберите режим отображения содержимого файла:</div>"
	               sDinamicContent = sDinamicContent & "<div class=""NormalLink""
	                 id=""TextFile_Notepad""
	                 onclick=RunApplication(me.id) onmouseover=me.className='NormalLinkMouseOver'
	                 onmouseout=me.className='NormalLink'>- Открыть файл в блокноте</div>"
	               sDinamicContent = sDinamicContent & "<div class=""NormalLink""
	                 id=""TextFile_Form""
	                 onclick=RunApplication(me.id) onmouseover=me.className='NormalLinkMouseOver'
	                 onmouseout=me.className='NormalLink'>- Отобразить здесь</div>"
	               DynamicContent_Div.InnerHTML = sDinamicContent
	           Else
	              DynamicContent_Div.InnerHTML = "Файл не найден"
	           End If
	       Case "TextFile_Form"
	           sDinamicContent = "<div style=""float: left; font-size: 10pt;"">" & _
	             "Текстовый файл: " & _
	             oShell.CurrentDirectory & "\MyHTA_files\Test.txt</div>"
	           sDinamicContent = sDinamicContent & "<div class=""NormalLink""" & _
	             " style=""float: right;"" id=""TextFile_Close""" & _
	             " onclick=RunApplication(me.id)" & _
	             " onmouseover=me.className='NormalLinkMouseOver'" & _
	             " onmouseout=me.className='NormalLink'>Закрыть</div>"
	           sDinamicContent = sDinamicContent & "<div class=""TextFile""" & _
	             " style=""clear: both;""><br />" & _
	             Replace(ReadFile(oShell.CurrentDirectory & _
	             "\MyHTA_files\Test.txt"),vbCrLf,"<br />") & "</div>"
	           DynamicContent_Div.InnerHTML = sDinamicContent
	       Case "TextFile_Notepad"
	           sCommandLine = "Notepad """ & oShell.CurrentDirectory & "\MyHTA_files\Test.txt"""
	           DynamicContent_Div.InnerHTML = "Файл " & oShell.CurrentDirectory & _
	             "\MyHTA_files\Test.txt" & " открыт в блокноте"
	       Case "TextFile_Close"
	           DynamicContent_Div.InnerHTML = "Добро пожаловать"
	       Case "TempDir"
	           sCommandLine = "Explorer " & oShell.ExpandEnvironmentStrings("%Temp%")
	           DynamicContent_Div.InnerHTML = "Папка временных файлов открыта"
	       Case Else
	           sCommandLine =""
	   End Select
	   If Len(sCommandLine) > 0 Then oShell.Run sCommandLine,1,0
	End Sub
	
	Function ReadFile(sFileName)
	   Set oFSO = CreateObject("Scripting.FileSystemObject")
	   Set oInFile = oFSO.OpenTextFile(sFileName, 1, False, 0)
	   sFileContent = oInFile.ReadAll
	   oInFile.Close
	   ReadFile = sFileContent
	End Function
	
	Function CheckFile(sFilePath)
	   Set oFSO = CreateObject("Scripting.FileSystemObject")
	   If oFSO.FileExists(sFilePath) Then
	       CheckFile = True
	   Else
	       CheckFile = false
	   End If
	End Function
	
	Function GetDisplayResolution()
	   Set oWMIService = GetObject("winmgmts:\\.\root\cimv2")
	   Set colItems = oWMIService.ExecQuery("Select * From Win32_DesktopMonitor")
	   For Each oItem In colItems
	       iHorizontal = oItem.ScreenWidth
	       iVertical = oItem.ScreenHeight
	   Exit For
	   Next
	   GetDisplayResolution = iHorizontal & ";" & iVertical
	End Function
	
	Function PingComputer(sComputer)
	   Set oPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery(_
	   "select * from Win32_PingStatus where address = '" & sComputer & "'")
	   For Each oStatus In oPing
	       If IsNull(oStatus.StatusCode) Or oStatus.StatusCode <> 0 Then
	           PingComputer = False
	       Else
	           PingComputer = True
	       End If
	   Next
	End Function
	
	Sub ccSleep(seconds)
	   Set oShell = CreateObject("Wscript.Shell")
	   sCommand = "%COMSPEC% /c ping -n " & 1 + seconds & " 127.0.0.1>nul"
	   oShell.Run sCommand,0,1
	End Sub
Hypertext Applications
Примеры приложений на HTA

В предудущих разделах мы изучили основные принципы создания HTA-приложения и даже создали тестовую форму. Теперь давайте перейдем к конкретным примерам - создадим интерфейс для диска восстановления, который используется в статье Создание диска восстановления, и консоль администратора домена.

Приложение "Интерфейс диска восстановления компьютера"
Hypertext Applications

Данное приложение является интерфейсом для работы с диском восстановления компьютера, оно запускается при загрузке компьютера с DVD восстановления системы и предназначено для выбора команд: восстановить систему, запустить командную строку, инициализировать сеть, запустить другое приложение или перезагрузить компьютер. Архив с примером можно загрузить здесь.

Приложение "Консоль администратора"

Приложение "Консоль администратора" - это сборник часто используемых команд администратора домена или службы поддержки домена. С помощью данной программы можно: управлять компьютером, скорректировать сервисы, узнать информацию о компьютере, узнать информацию о пользователе, разблокировать пользователя или сменить ему пароль.

Hypertext Applications

Данное приложение представяет из себя форму с возможностью выбора требуемой команды, полями ввода имени компьютера и пользователя, кнопки "Выполнить" и информационной строки, где отображается результат выполнения команд. Консоль имеет файл конфигурации "MyHTA.ini", в котором задаются параметры домена. Архив с примером программы можно загрузить здесь.

Виталий Бочкарев
Вложения
myhta_1_0.zip240 bytes
myhta_1_1.zip371 bytes
myhta_1_7.zip203.27 KB