1 (изменено: dandyd, 2011-03-24 18:08:33)

Тема: HTA: не найден объект Wscript

Добрый день

Скрипт (см. фрагмент кода ниже) в VBS работает (без "Document.writeln MSComm1.Input" конечно).
При переносе в HTA при запуске ругается и требует объект Wscript

Это как-то решается без создания и регистрации COM-сервера?

#%%##%%#Dim MSComm1

Sub Window_Onload 
  Set MSComm = Wscript.CreateObject("MSCommLib.MSComm","MSComm_")
  MSComm.Settings = "115200,N,8,1"
  MSComm.RThreshold = 1
  MSComm.SThreshold = 1
  MSComm.CommPort = 11
  If Not MSComm1.PortOpen Then : MSComm1.PortOpen = True : End If
  While Not MSComm1.PortOpen : Wend
End Sub

Sub MSComm_OnComm
  Select Case MSComm.CommEvent
  Case comEvSend '1 .output
  Case comEvReceive '2 .input
    Document.writeln MSComm1.Input
  End Select
End Sub

2

Re: HTA: не найден объект Wscript

Предлагаю использовать CreateWindow.

3

Re: HTA: не найден объект Wscript

2 dandyd:

dandyd пишет:

Это как-то решается без создания и регистрации COM-сервера?

Решается. Методом вставки в HTML код HTA объекта следующим образом.

<object id=MSComm classid="clsid:F6565773-FA54-45E9-941C-2505E54D5710"></object>

Предвижу Ваши последующие вопросы, поэтому рекомендую посмотреть спецификацию HTML

http://htmlbook.ru/html/object

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

4 (изменено: dandyd, 2011-03-27 08:43:10)

Re: HTA: не найден объект Wscript

JSman пишет:

Предлагаю использовать CreateWindow.

Попробовал, видимо я что-то не так делаю - объект Wscript не находит

ss="" : dq=Chr(34) ' ""
ss=ss+"<script language="+dq+"VBScript"+dq+" type="+dq+"text/vbscript"+dq+">"+vbCrLf
ss=ss+"Sub Window_OnLoad : Set MSComm = Wscript.CreateObject("+dq+"MSCommLib.MSComm"+dq+","+dq+"MSComm_"+dq+") : End Sub"+vbCrLf
ss=ss+"</script><body></body></html>"+vbCrLf
MsgBox(ss) 
set window = CreateWindow(ss,"",0,0,1000,800)
WScript.Sleep 5000

Function CreateWindow(content,features,x,y,width,height)
    On Error Resume Next
    Dim ShellWindows,ShellWindow,CodeForLinking,wshExec,form_id,id,i,document,window
    Set CreateWindow = Nothing
    Set ShellWindows = CreateObject("Shell.Application").Windows: Randomize: id = Clng(Rnd*100000)
    CodeForLinking = "<script>moveTo(-1000,-1000);resizeTo(0,0);</script>" &_
    "<hta:application " & features & " />" & _
    "<object id=" & id & " style='display:none' classid='clsid:8856F961-340A-11D0-A96B-00C04FD705A2' viewastext><param name=RegisterAsBrowser value=1></object>"
    Set wshExec = CreateObject("WScript.Shell").Exec("mshta about:""" & CodeForLinking & """")
    For i=1 to 1000
        For Each ShellWindow in ShellWindows: form_id = Clng(ShellWindow.id)
            if form_id = id Then
                Set document = ShellWindow.container:
                Set window = document.parentWindow
                document.open: window.execScript "var Host": Set window.Host = me
                document.write content: document.close
                if x <= 0 Then x = (window.screen.width - width) / 2
                if y <= 0 Then y = (window.screen.height - height) / 2
                window.execScript "document.onkeydown = function(){if(event.keyCode == 116){return false}};" &_
                "setInterval('var e;try{Host.WScript}catch(e){close()}',100);moveTo(" & x & "," & y & ");resizeTo(" & width & "," & height & ")"
                Set CreateWindow = window
                Exit Function
            End if
        Next
    Next
    wshExec.Terminate()
End Function

5 (изменено: dandyd, 2011-03-27 08:47:39)

Re: HTA: не найден объект Wscript

Xameleon пишет:

2 dandyd:

dandyd пишет:

Это как-то решается без создания и регистрации COM-сервера?

Решается. Методом вставки в HTML код HTA объекта следующим образом.

<object id=MSComm classid="clsid:F6565773-FA54-45E9-941C-2505E54D5710"></object>

Предвижу Ваши последующие вопросы, поэтому рекомендую посмотреть спецификацию HTML

http://htmlbook.ru/html/object

Да уж. Посмотрел. Чего то мне не очень хочется во все это влезать.
Пробовал еще через ScriptCodingInfo.wsc http://script-coding.com/SCI_WSC.html (ScriptCodingInfo.Translator).
Как то странно получается. На отсутствие объекта Wscript вроде не ругается, но тормозит и работает как-то глючно (не всегда), допустим этот же самый простой Wscript.Sleep.

6

Re: HTA: не найден объект Wscript

dandyd,

Трансляция WScript в окно HTA осуществляется автоматически. Этот объект будет доступен после того как будет построено дерево элементов полностью. Доступ к объекту осуществляется так: window.Host.WScript. Host — это ссылка на Global Object среды WSH.

7

Re: HTA: не найден объект Wscript

2 dandyd:

dandyd пишет:

Да уж. Посмотрел. Чего то мне не очень хочется во все это влезать.
Пробовал еще через ScriptCodingInfo.wsc http://script-coding.com/SCI_WSC.html (ScriptCodingInfo.Translator).
Как то странно получается. На отсутствие объекта Wscript вроде не ругается, но тормозит и работает как-то глючно (не всегда), допустим этот же самый простой Wscript.Sleep.

1) Для того чтобы понять почему WSсript в данном случае недоступен, а в другом доступен надо прочитать спецификации HTA и WSH
2) Если все эти мучения ради WScript.Sleep, то вполне возможно обойтись и window.SetTimeout() или window.SetInterval(). А в большинстве случаев - даже и они не нужны. Если вы работаете с событиями.

P.S Если вы не хотите в это "влезать", то тут уж весь наш форум со всеми гуру бессилен Вам помочь. Но если всё же желание понять пересилит нежеление "влезать", то поведайте нам о конечной цели. Возможно решение лежит на поверхности.

P.P.S - На крайний случай есть чат на форуме и ICQ. Чтобы быстрее найти решение.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

8

Re: HTA: не найден объект Wscript

Xameleon пишет:

2 dandyd:

dandyd пишет:

Да уж. Посмотрел. Чего то мне не очень хочется во все это влезать.
Пробовал еще через ScriptCodingInfo.wsc http://script-coding.com/SCI_WSC.html (ScriptCodingInfo.Translator).
Как то странно получается. На отсутствие объекта Wscript вроде не ругается, но тормозит и работает как-то глючно (не всегда), допустим этот же самый простой Wscript.Sleep.

1) Для того чтобы понять почему WSсript в данном случае недоступен, а в другом доступен надо прочитать спецификации HTA и WSH
2) Если все эти мучения ради WScript.Sleep, то вполне возможно обойтись и window.SetTimeout() или window.SetInterval(). А в большинстве случаев - даже и они не нужны. Если вы работаете с событиями.

P.S Если вы не хотите в это "влезать", то тут уж весь наш форум со всеми гуру бессилен Вам помочь. Но если всё же желание понять пересилит нежеление "влезать", то поведайте нам о конечной цели. Возможно решение лежит на поверхности.

P.P.S - На крайний случай есть чат на форуме и ICQ. Чтобы быстрее найти решение.

По поводу "влезать"

<object id=MSComm classid="clsid:F6565773-FA54-45E9-941C-2505E54D5710"></object>

Может по поиску попал не совсем правильные примеры. Там кода столько, это где-то к ассемблеру ближе...
Я Ваш смайлик понял именно именно в этом смысле.

Проблема такая:
Нужен терминал для железки, которая по Virtual USB COM11 общается с компьютером

VBS:

Set MSComm = WScript.CreateObject("MSCommLib.MSComm","MSComm_")

работает, но не могу найти обработки Event клавиатуры (подскажите, если сможете)

HTA: обработка событий клавиатуры делается легко и события по закрытию окна есть

<body OnKeyPress="DoCheckEnterKey" OnBeforeClose="EndWork">

можно порт закрыть и железяке сказать отключиться перед завершением,
но

Set MSComm = WScript.CreateObject("MSCommLib.MSComm","MSComm_")

не работает
А Eventы по COM порту нужны.

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

В VBS не получается с событиями клавиатуры.
В HTA не получается с событиями "MSComm_".

Красивостей не надо, вещь технологическая - получать/декодировать строки из порта, посылать команды контроллеру железки (как с клавиатуры, так и по таймеру и по принятой строке).

Терминалы даже типа ZOC Terminal с RExx (давно любимого)  в макросах событий не поддерживают.

9

Re: HTA: не найден объект Wscript

Хм.... Ответ очень сумбурный и малопонятный. )

Но всё же понял, что Вы никак не можете в HTA события обработать. Что мешает не пойму.


<html>
	<body>
		<object id=MSComm style="display:none;" classid="clsid:F6565773-FA54-45E9-941C-2505E54D5710"></object>
	</body>
	<script language=vbscript>
		Sub MSComm_OnComm()
			MsgBox "!"
		End Sub
			
		Sub document_onkeypress()
			MsgBox window.event.keycode
		End Sub
	</script>
</html>
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

10 (изменено: Rumata, 2011-03-28 20:18:37)

Re: HTA: не найден объект Wscript

dandyd
Ответьте четко на вопрос. Для чего Вам нужен WScript в HTA? Что есть в WScript, чего не хватает в HTA? Я почитал всю переписку, и мне не очевидно из обсуждения, что же окончательно Вам нужно.

( 2 * b ) || ! ( 2 * b )

11 (изменено: mikser, 2011-03-28 20:36:03)

Re: HTA: не найден объект Wscript

OFF: Лично мне в HTA не хватает Sleep'a и возможности обрабатывать события COM объектов.

12

Re: HTA: не найден объект Wscript

По первой части отвечу я, по второй - подожду ответа коллег.

Вы не должны хотеть использовать Sleep  в HTA. Sleep - метод, который замораживает исполнение приложения на заданный промежуток времени. То есть все это время приложение будет "висеть" не отвечая на запросы пользователя. Это плохая практика, так как HTA - это интерактивное приложение. Возможно Вы хотели бы объяснить свое желание использовать этот метод необходимостью "отложить на будущее" выполнение некоторой части кода. Для этих целей Вам следует использовать методы setTimeout/setInterval глобального объекта window.

В теме заявлены оба поддерживаемых языка - VBScript, JScript. Я предпочитаю в HTML/HTA использовать JavaScript, поэтому мои цитаты и примеры будут только на нем.

Синтаксис: window.setTimeout(выражение, интервал)
           window.setTimeout(функция, интервал, арг1?, …, аргN?)
Аргументы: выражение — строковое значение
           функция — имя функции
           арг1, …, аргN — значения аргументов функции
           интервал — числовое значение
Результат: целое значение
Этот метод вызывает разовое выполнение определенного действия, когда истечет интервал, заданный в миллисекундах. Действие задается либо строкой, содержащей выражение JavaScript, либо именем функции с необязательным набором аргументов. Метод возвращает целое значение (идентификатор таймера), которое может быть передано методу clearTimeout для остановки данного таймера, т. е. для отмены выполнения заданного действия. Действие будет выполнено по истечении заданного интервала времени, если до этого не будет вызван метод clearTimeout или закрыто данное окно.


<html>
<head>
<title>Clock</title>
</head>
<body>
<div id="clock"></div><!-- Сюда будут записываться данные -->
<script type="text/javascript">

// функция, которая определяет текущее время (часы:минуты:секунды)
function ticker()
{
	// Высчитываем время
	var now = new Date();
	var h = now.getHours();
	var m = now.getMinutes();
	var s = now.getSeconds();

	// определяем html-элемент для записи и пишем
	var clock = document.getElementById('clock');
	clock.innerHTML = h + ':' + m + ':' + s;

	// устанавливаем таймер, чтобы он сработал через 1 секунду (1000 мсек)
	setTimeout(ticker, 1000);
};

// вызываем таймер
ticker();

</script>
</body>
</html>
( 2 * b ) || ! ( 2 * b )

13 (изменено: Rumata, 2011-03-28 21:21:33)

Re: HTA: не найден объект Wscript

Обработка событий (клавиатура, мышь, пользовательские, DOM) - это большая тема. Способов задания обработчиков событий несколько, поэтому я Вам советую почитать литературу, сам же ограничусь очень краткими описанием и примером.
1. Обработчик события - это функция.
2. Обработчик событий назначается html-'элементу или нескольким элементам.
Попробуйте следующий пример:


<html>
<head>
<script type="text/javascript">

// установить обработчик события - полная загрузка окна и построение дерева html-элементов
// к этому моменту документ загружен и все элементы доступны
window.onload = function()
{

	// установить обработчик события - нажатие клавиш
	// попробуйте нажать любую клавишу - приложение покажет ее скан-код
	document.body.onkeypress = function(e)
	{
		var e = e || event;
		alert(e.keyCode);
	};

};

</script>
</head>
<body>
</body>
</html>
( 2 * b ) || ! ( 2 * b )

14 (изменено: mikser, 2011-03-28 22:33:54)

Re: HTA: не найден объект Wscript

Xameleon А если нужно несколько (заранее не известно сколько, выяснится по ходу исполнения скрипта) экземпляров ActiveX объекта. Как это на html'е будет? Или предложите создавать тег <object...> с помощью DOM или innerHTML ем?

PS По моему ответ на сабжевый вопрос дан в посте номер 9.

15

Re: HTA: не найден объект Wscript

mikser
Что Вы имеете в виду:
1, как имея несколько <object classid=...> каждому установить свой обработчик?
2. как организовать обработчики событий для <object classid=...> количество которых заранее неизвестно?

( 2 * b ) || ! ( 2 * b )

16 (изменено: mikser, 2011-03-28 23:22:40)

Re: HTA: не найден объект Wscript

Второе.

количество которых заранее неизвестно

Но не только их количество  не известно заранее, их вообще нет в виде HTML. Теоритически тег <object можно создать средствами DOM или через средства IE 5+ такие как innerHTML/outerHTML/InsertAdjacentHTML/итд. Как к этой идее отнесется IE уже другой разговор
Объекты рассматриваем  не как цель или данность а как средство для достижения результата.

17

Re: HTA: не найден объект Wscript

Вы правиль сказали, что элементы можно создать как средствами DOM, так и через запись innerHTML родителя элемента. В момент создания Вы вольны указать обработчик данному объекту. Например


function clickEvent(e)
{
    e = e || event;
    alert(e.srcElement.innerHTML);
};

var text = document.createTextNode('Lorem ipsum');
var para = document.createElement('p');
para.attachEvent('onclick', clickEvent);
para.appendChild(text);

document.body.appendChild(para);

Примерно также делает популярный фреймворк jQuery.

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


document.attacheEvent('onclick', function(e)
{
    e = e || event;
    // получить ссылку на элемент
    var src = e.srcElement;
    // идентифицировать элемент (по имени тега и его уникальному id)
    if ( src.tagName == 'p' && src.id == 'myPara' ) {
        ...
        return;
    }
    ...
});
( 2 * b ) || ! ( 2 * b )

18 (изменено: mikser, 2011-03-29 00:05:32)

Re: HTA: не найден объект Wscript

document.attacheEvent

Для ActiveX объектов даже такой способ развешивания обработчиков событий -  не работает.
Для онклика конечно сработает наверно так как это событие документа точнее объекта тега <object ..>

Автору нужно обрабатывать внутренее событие  OnComm его ActiveX объекта - MSCommLib.MSComm 
Вы же рассказываете как обрабатывать внешние события типа онклик и онкейпресс.
Спасибо но это не то.

19

Re: HTA: не найден объект Wscript

О каких ActiveX объектах идет речь? Они поддерживают события?

( 2 * b ) || ! ( 2 * b )

20

Re: HTA: не найден объект Wscript

Вот теперь понятно. До сих пор упоминалось о многих событиях. Поэтому не было очевидно, что подразумеваются некие внутренние события объекта. Тогда почему бы не перечитать ответ №9?

( 2 * b ) || ! ( 2 * b )

21 (изменено: mikser, 2011-03-29 00:15:33)

Re: HTA: не найден объект Wscript

В посте номер 9 дан ответ на вопрос автора.
Все что ниже - флейм и можно смело удалять.

22

Re: HTA: не найден объект Wscript

Да уж... Как говорится - Остапа понесло

( 2 * b ) || ! ( 2 * b )

23

Re: HTA: не найден объект Wscript

2 mikser:

mikser пишет:

Xameleon А если нужно несколько (заранее не известно сколько, выяснится по ходу исполнения скрипта) экземпляров ActiveX объекта. Как это на html'е будет? Или предложите создавать тег <object...> с помощью DOM или innerHTML ем?

PS По моему ответ на сабжевый вопрос дан в посте номер 9.

Да. Предложу

создавать тег <object...> с помощью DOM или innerHTML ем

Либо предложу сделать WSC оболочку. Как я это сделал в мультисокетном веб сервере

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

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

24 (изменено: mikser, 2011-03-29 04:44:08)

Re: HTA: не найден объект Wscript

Xameleon пишет:

Либо предложу сделать WSC оболочку.

Внутри WSC доступен объект WScript?

25

Re: HTA: не найден объект Wscript

Да нет же. WScript доступен ТОЛЬКО в WSH. Пора это запомнить уже. WSC даст возможность повесить на одни и теже события множество объектов.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

26 (изменено: dandyd, 2011-03-29 12:58:49)

Re: HTA: не найден объект Wscript

Xameleon пишет:

Хм.... Ответ очень сумбурный и малопонятный. )

Но всё же понял, что Вы никак не можете в HTA события обработать. Что мешает не пойму.


<html>
	<body>
		<object id=MSComm style="display:none;" classid="clsid:F6565773-FA54-45E9-941C-2505E54D5710"></object>
	</body>
	<script language=vbscript>
		Sub MSComm_OnComm()
			MsgBox "!"
		End Sub
			
		Sub document_onkeypress()
			MsgBox window.event.keycode
		End Sub
	</script>
</html>

Спасибо большое. То что нужно.
Понятно и красиво.
Видимо мне в google поиске по

<object id=MSComm style="display:none;" classid="clsid:F6565773-FA54-45E9-941C-2505E54D5710"></object>

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

27

Re: HTA: не найден объект Wscript

2 dandyd: Зачем в VBS ловить событие нажатия клавиш ? Он (vbs) не имеет графического интерфейса. Куда отсылать нажатые клавиши ? В какое окно ? Или вы хотите ловить глобальные нажатия ? Клавиатурный шпион писать что ли ? Если же просто для ввода данных в скрипт - есть функция InputBox(). Если же хочется консольное приложение с обменом данными в окне, то у интерпретатора CScript есть все нужные средстав для этого - StdIn и StdOut потоки... Опять же - всё хорошо и уместно в определённых условиях. Вашу конечную цель - я пока что не понял.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

28

Re: HTA: не найден объект Wscript

Xameleon пишет:

2 dandyd: Зачем в VBS ловить событие нажатия клавиш ? Он (vbs) не имеет графического интерфейса. Куда отсылать нажатые клавиши ? В какое окно ? Или вы хотите ловить глобальные нажатия ? Клавиатурный шпион писать что ли ? Если же просто для ввода данных в скрипт - есть функция InputBox(). Если же хочется консольное приложение с обменом данными в окне, то у интерпретатора CScript есть все нужные средстав для этого - StdIn и StdOut потоки... Опять же - всё хорошо и уместно в определённых условиях. Вашу конечную цель - я пока что не понял.

Цель - терминал для обмена данными с интерфейсом железки, подключенной к COM порту.
Посылать нажатые клавиши надо в COM порт.
Иногда код клавиши.
Иногда определенную строку символов в зависимости от кода нажатой клавиши.
Иногда определенный символ или строку в зависимости, что выплюнул порт.
StdIn нужно каждый раз заканчивать Enter. InputBox тоже. Неудобно.
В качестве графического интерфейса хватает Wscript.Echo

29

Re: HTA: не найден объект Wscript

Тогда HTA Вам в помощь. ) Там события нажатий клавиш вы можете обработать кодом, который я приводил выше.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

30

Re: HTA: не найден объект Wscript

вот как на HTMLe можно съимитировать консоль

31

Re: HTA: не найден объект Wscript

Xameleon пишет:

Тогда HTA Вам в помощь. ) Там события нажатий клавиш вы можете обработать кодом, который я приводил выше.

Так я и писал, что тот вариант меня крайне устраивает.
А по поводу VBS и клавиатуры, то это чисто с теоретической точки зрения.

32

Re: HTA: не найден объект Wscript

Для VBS - консольный интерфейс можно сделать например так:


Set WshShell = WScript.CreateObject("WScript.Shell")
if Instr(1,WScript.FullName,"WScript.exe",1) > 0 Then
    WshShell.Run "CScript """ & WScript.ScriptFullName & """ //nologo //I", 1
    WScript.Quit
End if

WScript.StdOut.WriteLine "Введите значение переменной a"
Do
    a = WScript.StdIn.ReadLine
    if Not isNumeric(a) Then
        WScript.StdOut.WriteLine "Введено не числовое значение ! Повторите ввод."
    Else
        Exit Do
    End if
Loop

WScript.StdOut.WriteLine "Введите значение переменной b"
Do
    b = WScript.StdIn.ReadLine
    if Not isNumeric(b) Then
        WScript.StdOut.WriteLine "Введено не числовое значение ! Повторите ввод."
    Else
        Exit Do
    End if
Loop
WScript.StdOut.WriteLine "a + b = " & Clng(a) + Clng(b)
WScript.StdOut.WriteLine "Нажмите Enter для завершения программы."
WScript.StdIn.ReadLine
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !