Что нового

[Окна, Диалоги] IE: Работа с JavaScript сообщениями

epimetei

Новичок
Сообщения
11
Репутация
1
Есть следующий сценарий: Нужно нажать на кнопку "Создать", после чего появляется JavaScript сообщение с текст-боксом и кнопками ОК и Cancel. Необходимо послать значение в текст-бокс(после появления сообщения курсор уже в боксе) и нажать ОК(Enter). Пробовал
Код:
Send($count)
Send("{ENTER}")

но не работает. Если вручную ввести значение и нажать ОК - цикл выполняется и следующее сообщение всплывает для ввода. Сообщение блокирует дальнейшие действия с IE(нельзя создавать вкладки, клацать по элементам страницы и т.д.) Аналога функции Send() для IE че то не нашел, а может не там искал...
Собственно код(писал по памяти, может где-то очепятки есть):
Код:
#include IE.au3

$oIE = _IECreate (http://test.com)
_IELoadWait ($oIE)

	_IEImgClick ($oIE, "Management", "alt")
	_IELoadWait ($oIE)
	
		$count=1
		
		For 1 to 10
			_IEImgClick ($oIE, "New", "alt")
			;появляется JavaScript message 
			; WinWaitActive("JavaScript Window Name") -?
			; _IELoadWait ("JavaScript Window Name") -?
			Send($count)
			Sleep(1000)
			Send("{ENTER}")
			$count=$count+1
		Next

Помогите пожалуйста!
 
Автор
E

epimetei

Новичок
Сообщения
11
Репутация
1
У IE есть разные сообщения. Некоторые, например при выборе файла для загрузки-скачивания, блокируют дальнейшие действия и их простым способом не поймать, а есть такие, которые не блокируют дальнейшие действия. Проверьте MsgBox`ом, блокирует Ваше сообщение дальнейшую работу или нет.
подскажите пожалуйста как это сделать? вот нашел ваш код.
Код:
$hWind = WinWaitActive("[Class:IEFrame]")
MsgBox(0, "22", $hWind, 3)

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

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,321
epimetei [?]
каждый раз выдает разные значения
Этот код ждет активизации любого окна IE (основного, а не сообщения) и выдает он дескриптор (Handle) окна IE, а они всегда разные. Для сообщений IE этот код бесполезен.
Вставьте в Ваш код сразу после клика по элементу, после которого появляется сообщение
Код:
MsgBox(0, '', 'Yes')
И сообщите о результате (появился MsgBox или нет). И прикрепите скриншот окна сообщения.
 
Автор
E

epimetei

Новичок
Сообщения
11
Репутация
1
Этот код ждет активизации любого окна IE (основного, а не сообщения) и выдает он дескриптор (Handle) окна IE, а они всегда разные. Для сообщений IE этот код бесполезен.
Вставьте в Ваш код сразу после клика по элементу, после которого появляется сообщение
Код: AutoIt [Выделить]
MsgBox(0, '', 'Yes')
И сообщите о результате (появился MsgBox или нет). И прикрепите скриншот окна сообщения.
MsgBox появляется только после закрытия окна- нажатия ОК ил Cancel.
JavaScript сообщение имеет следующий вид:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,321
epimetei,
Попробуйте так.
Код:
#include <IE.au3>
#include <File.au3>

;Ваш код
;...

$sTempFile = _TempFile(@TempDir)
$iPid = _Click_Prompt_IE('Test')
If Not $iPid Then
	MsgBox(16, 'Error', '_Click_Prompt_IE')
EndIf
;_IEImgClick($oIE, "New", "alt");здесь функция, после которой появляется окно
If ProcessExists($iPid) Then
	ProcessClose($iPid)
	Sleep(500)
EndIf
FileDelete($sTempFile)
;Ваш дальнейший код
;...

Func _Click_Prompt_IE($s_Text)
	Local $s_TempFile, $s_Script, $h_File, $i_Pid, $i_Start, $i_TimeOut = 4000 ; 4 sec

	$s_Script = "#NoTrayIcon" & @CRLF & _
			"$hWin = WinWait('[Title:Explorer User Prompt; Class:#32770]', '', 3)" & @CRLF & _
			"If Not $hWin Then Exit" & @CRLF & _
			"ControlSetText($hWin, '', '[CLASS:Edit; INSTANCE:1]', '" & $s_Text & "')" & @CRLF & _ ;у Вас может быть другой
			"Sleep(500)" & @CRLF & _
			"ControlClick($hWin, '', '[CLASS:Button; INSTANCE:1]')" & @CRLF & _;у Вас может быть другой
			"Sleep(500)" & @CRLF & _
			"If WinExists($hWin) Then" & @CRLF & _
			"ToolTip('Ошибка 3', 0, 0)" & @CRLF & _
			"Sleep(5000)" & @CRLF & _
			"EndIf" & @CRLF & _
			"Exit"

	$h_File = FileOpen($sTempFile, 2)
	FileWrite($h_File, $s_Script)
	FileClose($h_File)
	If @Compiled Then
		$i_Pid = Run(@ScriptFullPath & ' /AutoIt3ExecuteScript "' & $sTempFile & '"')
	Else
		$i_Pid = Run(@AutoItExe & ' /AutoIt3ExecuteScript "' & $sTempFile & '"')
	EndIf
	Return $i_Pid
EndFunc   ;==>_Click_Prompt_IE
 
Автор
E

epimetei

Новичок
Сообщения
11
Репутация
1
Огромнейшее спасибо! Все работает как по маслу :beer:
 

BIOS

Жизнь - игра. График - супер, но сюжет - хреновый.
Сообщения
173
Репутация
69
Можно заменить встроенные функции IE promt и alert на собственные и производить интеракцию через них
Таким макаром можно работать в тихую, без доп. окон
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,321
BIOS [?]
Можно заменить встроенные функции IE promt и alert на собственные и производить интеракцию через них
Таким макаром можно работать в тихую, без доп. окон
Пример в студию. :smile:
 

BIOS

Жизнь - игра. График - супер, но сюжет - хреновый.
Сообщения
173
Репутация
69
Garrett [?]
Можно вообще работать через WinHttp.WinHttpRequest.5.1
Да, если сайт редко изменяется (в плане скриптов)

madmasles [?]
Пример в студию.
Да запросто:

Код:
#include <IE.au3>

Global $_IENativeFunctionsHandler_Interation=0

$ie=_IECreate('ya.ru')
_IENativeFunctionsHandler_Initailize($ie) ;Инициализировать при каждом переходе
_IENativeFunctionsHandler_SetPromptAnswer($ie,'288') ;устанавливаем ответ на Prompt-запросы
;Выполняем действие вызывающее Prompt

;Также можно получать содержимое alert-запросов
$sAlertAnsw=_IENativeFunctionsHandler_WaitForAlert($ie,10000)
MsgBox(0,'Alert',$sAlertAnsw)
;и тексты prompt запросов
$aPromptRequest=_IENativeFunctionsHandler_WaitForPrompt($ie,10000)
#include <Array.au3>
_ArrayDisplay($aPromptRequest)

Func _IENativeFunctionsHandler_Initailize(ByRef $oIE)
	$oContainer=$oIE.document.getElementById('NativeFunctionsInteractionContainer')
	if isobj($oContainer) Then Return SetError(1,0,0)
	$oContainer=$oIE.document.getElementById('NativeFunctionsInteractionPromptAnswer')
	if isobj($oContainer) Then Return SetError(2,0,0)

	$oContainer=$oIE.document.createElement("span")
	$oContainer.id='NativeFunctionsInteractionContainer'
	$oContainer.style.display="none"
	$oContainer.innerHTML='o'
	$oIE.document.body.appendChild($oContainer)

	$oContainer=$oIE.document.createElement("span")
	$oContainer.id='NativeFunctionsInteractionPromptAnswer'
	$oContainer.style.display="none"
	$oContainer.innerHTML='false'

	$oIE.document.body.appendChild($oContainer)
	$oIE.document.parentWindow.execScript("window.NativeFunctionsInteractionCounter=0")
	$oIE.document.parentWindow.execScript("window.alert=function(str){document.getElementById('NativeFunctionsInteractionContainer').innerHTML=document.getElementById('NativeFunctionsInteractionContainer').innerHTML+'|a'+String(str).replace('|','').replace(';','');window.NativeFunctionsInteractionCounter++;}")
 	$oIE.document.parentWindow.execScript("window.prompt=function(str,val){document.getElementById('NativeFunctionsInteractionContainer').innerHTML=document.getElementById('NativeFunctionsInteractionContainer').innerHTML+'|p'+String(str).replace('|','').replace(';','')+';'+String(val).replace('|','').replace(';','');window.NativeFunctionsInteractionCounter++;return document.getElementById('NativeFunctionsInteractionPromptAnswer').innerHTML;}")
	$_IENativeFunctionsHandler_Interation=0
	return True
EndFunc

Func _IENativeFunctionsHandler_WaitForAlert(ByRef $oIE,$timeout=10000)
	$oContainer=$oIE.document.getElementById('NativeFunctionsInteractionContainer')
	if Not isobj($oContainer) Then Return SetError(1,0,0)

	$time=TimerInit()

	while timerdiff($time)<$timeout
		$sAllMsg=$oContainer.innerHTML
		$iStart=StringInStr($sAllMsg,'|',0,$_IENativeFunctionsHandler_Interation+1)
		if $iStart Then
			$sType=StringMid($sAllMsg,$iStart+1,1)
			if $sType='a' Then
				ExitLoop
			Else
				$_IENativeFunctionsHandler_Interation+=1
			EndIf
		EndIf
	WEnd
	if Not $iStart Then Return SetError(2,0,0)

	$iEnd=StringInStr($sAllMsg,'|',0,$_IENativeFunctionsHandler_Interation+2)
	$sMsg=StringMid($sAllMsg,$iStart+2,$iEnd)
	if not $iEnd Then $sMsg=StringMid($sAllMsg,$iStart+2)

	$_IENativeFunctionsHandler_Interation+=1
	return $sMsg
EndFunc

Func _IENativeFunctionsHandler_SetPromptAnswer(ByRef $oIE,$sAnswer)
	$oContainer=$oIE.document.getElementById('NativeFunctionsInteractionPromptAnswer')
	if Not isobj($oContainer) Then Return SetError(1,0,0)

	$time=TimerInit()

	$oContainer.innerHTML=$sAnswer
	return True
EndFunc

Func _IENativeFunctionsHandler_WaitForPrompt(ByRef $oIE,$timeout=10000)
	$oContainer=$oIE.document.getElementById('NativeFunctionsInteractionContainer')
	if Not isobj($oContainer) Then Return SetError(1,0,0)

	$time=TimerInit()

	while timerdiff($time)<$timeout
		$sAllMsg=$oContainer.innerHTML
		$iStart=StringInStr($sAllMsg,'|',0,$_IENativeFunctionsHandler_Interation+1)
		if $iStart Then
			$sType=StringMid($sAllMsg,$iStart+1,1)
			if $sType='p' Then
				ExitLoop
			Else
				$_IENativeFunctionsHandler_Interation+=1
			EndIf
		EndIf
	WEnd
	if Not $iStart Then Return SetError(2,0,0)

	$iEnd=StringInStr($sAllMsg,'|',0,$_IENativeFunctionsHandler_Interation+2)
	$sMsg=StringMid($sAllMsg,$iStart+2,$iEnd)
	if not $iEnd Then $sMsg=StringMid($sAllMsg,$iStart+2)

	$aMsg=StringSplit($sMsg,';')
	$_IENativeFunctionsHandler_Interation+=1
	return $aMsg
EndFunc


P.S. Хотел ещё круче завернуть, но IE не обновляет данные об элементах до полного выполнения функции (пытался сделать двухстороннюю своевременную интеракцию через container)
P.P.S. В момент времени ";Выполняем действие вызывающее Prompt" в адресную строку ввести
Код:
javascript:var answ=prompt("Запрос prompt-а","Стандартное значение");alert(answ);void(0);
P.P.P.S. Автор функций - я. Если в этом есть толк - может закинуть в полезняшки?
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
965
BIOS [?]
Не проще воспользоваться
Код:
_IEHeadInsertEventScript()


А что вы скажите на это, как поступите в этом случае?
HTML:
<form name="f1">
<input type="file" name="t1" style="display:none">
<a href="" onclick="document.f1.t1.click(); return false;">Open</a>
</form>
 

BIOS

Жизнь - игра. График - супер, но сюжет - хреновый.
Сообщения
173
Репутация
69
Garrett [?]
Не проще воспользоваться
Хм, а это идея, сделать форму и повесить события на изменение элемента. Ща сварганю


А что вы скажите на это, как поступите в этом случае?
Вуаля, и нет блокировки:
Код:
$oIE.document.parentWindow.execScript("setTimeout(function(){document.f1.t1.click()},1)")
sleep(500)
Send("C:\myfile.txt")
Send('{enter}')
 

BIOS

Жизнь - игра. График - супер, но сюжет - хреновый.
Сообщения
173
Репутация
69
madmasles [?]
А нельзя это дело внедрить с помощью функции _IEHeadInsertEventScript()?
_IEHeadInsertEventScript() предназначена для создания РЕАКЦИИ на событие (аля callback)
В данном случаем нам нужна не реакция а выполнение самого события без задержки
 

MrZLO

Suum cuique
Сообщения
15
Репутация
4
OffTopic:
Разве исскуственные события не отслеживаются?
или я параноик...
 

tyukas

Новичок
Сообщения
5
Репутация
0
Всем доброго времени суток.
Прочитала всю тему, несколько раз. Но никак не удается решить проблему. Всплывающее окно, где необходимо нажать кнопку "Ok", скрипт останавливается, после ручного нажатия на OK/Cancel - возобновляется... Пытаюсь использовать решение, которое помогло выше - ничего не меняется :( Вставляю код, что я делаю не так?
Мой код изначально:
Код:
#include <IE.au3>
WinActivate("[CLASS:IEFrame]")
$oIE = _IEAttach("Система 4i", "Title")
$oEdit = _IEGetObjByName($oIE, "ctl00$ctl00$ctl00$MainContent$LeftContent$UserDataContent$saveButton") 
_IEAction($oEdit, "click") ; после нажатия кнопки сохранить появляется модальное окно
ControlClick('[Title:Сообщение с веб-страницы]', '', '[CLASS:Button; INSTANCE:1]') ; вот тут хотелось бы нажать кнопку Ок :)

Когда запускаю скрипт при открытом модальном окне - он срабатывает...
Сейчас мой код выглядит вот так:
Код:
#include <IE.au3>
#include <File.au3>
WinActivate("[CLASS:IEFrame]")
$oIE = _IEAttach("Система 4i", "Title")
$oEdit = _IEGetObjByName($oIE, "ctl00$ctl00$ctl00$MainContent$LeftContent$UserDataContent$saveButton") 
$sTempFile = _TempFile(@TempDir)
$iPid = _Click_Prompt_IE('Test')
If Not $iPid Then
    MsgBox(16, 'Error', '_Click_Prompt_IE')
EndIf
_IEAction($oEdit, "click")
If ProcessExists($iPid) Then
    ProcessClose($iPid)
    Sleep(500)
EndIf
FileDelete($sTempFile)
ControlClick('[Title:Сообщение с веб-страницы]', '', '[CLASS:Button; INSTANCE:1]')

Func _Click_Prompt_IE($s_Text)
    Local $s_TempFile, $s_Script, $h_File, $i_Pid, $i_Start, $i_TimeOut = 4000 ; 4 sec

    $s_Script = "#NoTrayIcon" & @CRLF & _
            "$hWin = WinWait('[Title:Explorer User Prompt; Class:#32770]', '', 3)" & @CRLF & _
            "If Not $hWin Then Exit" & @CRLF & _
			"ControlClick($hWin, '', '[CLASS:Button; INSTANCE:1]')" & @CRLF & _;у Вас может быть другой
            "Sleep(500)" & @CRLF & _
            "If WinExists($hWin) Then" & @CRLF & _
            "ToolTip('Ошибка 3', 0, 0)" & @CRLF & _
            "Sleep(5000)" & @CRLF & _
            "EndIf" & @CRLF & _
            "Exit"

    $h_File = FileOpen($sTempFile, 2)
    FileWrite($h_File, $s_Script)
    FileClose($h_File)
    If @Compiled Then
        $i_Pid = Run(@ScriptFullPath & ' /AutoIt3ExecuteScript "' & $sTempFile & '"')
    Else
        $i_Pid = Run(@AutoItExe & ' /AutoIt3ExecuteScript "' & $sTempFile & '"')
    EndIf
    Return $i_Pid
EndFunc   ;==>_Click_Prompt_IE


Целый день голову ломаю, буду очень благодарна за помощь.. :stars:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,321
tyukas,
Ссылку дайте и, ИМХО, лучше новую тему создать, т.к. эта тема отмечена решенной.
 
Верх