Не работает Send () и щелчок мышью в окне с Class: SunAwtFrame на третьем уровне

Не используйте тайм-ауты. Это эффективный eval, который является Bad Thing. Он работает, потому что он преобразует currentaudio.id и noteTime в строковые представления самих себя и скрывает его в коде. Это работает только до тех пор, пока эти значения имеют toString() s, которые генерируют буквенный синтаксис JavaScript, который воссоздает значение, которое истинно для Number, но не для других.

setTimeout(playNote(currentaudio.id, noteTime), delay);

- это функция вызов. playNote вызывается немедленно, и возвращаемый результат функции (возможно undefined) передается на setTimeout(), а не на то, что вы хотите.

Как упоминаются другие ответы, вы можете использовать встроенное выражение функции с закрытием ссылки currentaudio и noteTime:

setTimeout(function() {
    playNote(currentaudio.id, noteTime);
}, delay);

Однако, если вы находитесь в цикле, а currentaudio или noteTime каждый раз различаются по циклу, у вас возникла проблема замкнутого контура: в каждый тайм-аут будет указана одна и та же переменная, поэтому при их вызове вы будете получать одинаковое значение каждый раз, значение, которое осталось в переменной, когда цикл был закончен ранее.

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

setTimeout(function() {
    return function(currentaudio, noteTime) {
        playNote(currentaudio.id, noteTime);
    };
}(currentaudio, noteTime), delay);

, но это становится немного теперь уродливо. Лучше Function#bind, что частично применит для вас функцию:

setTimeout(playNote.bind(window, currentaudio.id, noteTime), delay);

(window для установки значения this внутри функции, что является признаком bind() вам здесь не нужно.)

Однако это функция ECMAScript Fifth Edition, которая еще не поддерживается всеми браузерами. Поэтому, если вы хотите использовать его, вам нужно сначала взломать поддержку, например ::

// Make ECMA262-5 Function#bind work on older browsers
//
if (!('bind' in Function.prototype)) {
    Function.prototype.bind= function(owner) {
        var that= this;
        if (arguments.length<=1) {
            return function() {
                return that.apply(owner, arguments);
            };
        } else {
            var args= Array.prototype.slice.call(arguments, 1);
            return function() {
                return that.apply(owner, arguments.length===0? args : args.concat(Array.prototype.slice.call(arguments)));
            };
        }
    };
}
0
задан Artem Kovalev 18 January 2019 в 11:18
поделиться

1 ответ

Чтобы ответить на этот вопрос для вашего класса SunAwtFrame, вопрос слишком неясен. Но у вашего кода есть некоторые проблемы.

  1. _WinWaitActivate() с Sleep(15000) не требуется, поскольку вы можете использовать WinWaitActive($sTitle, $sText, $iTimeout) с тайм-аутом 15 секунд в качестве третьего параметра.
  2. Ваша проблема с остановкой должна состоять в строке 21. Вы не можете добавить новую строку в параметре функции без использования & _ в конце строки. Используйте функцию, подобную _sendKeystrokesSeveralTimes(), чтобы избежать таких длинных значений параметров.
  3. Вы также можете сократить действие MouseMove(), а затем MouseClick(), выполнив MouseClick('left', 268, 363) до целевой позиции мыши.

Вот переработанная версия вашего кода:

#include-once
#include <IE.au3>

Global $sLogin  = InputBox('Security Check', 'Enter your login', '')
Global $sPasswd = InputBox('Security Check', 'Enter your password.', '', '-')
Global $oIE     = _IECreate('https://******************', 0, 0, 1, 1)
Global $oLinks  = _IETagNameGetCollection($oIE, 'input')

Func _clickButtonRun()
    For $oLink In $oLinks
        If String($oLink.type) == 'button' And String($oLink.value) == 'RUN' Then
            _IEAction($oLink, 'click')
            ExitLoop
        EndIf
    Next
EndFunc

Func _sendKeystrokesSeveralTimes($sKey, $iHowOften = 1)
    For $i = 1 To $iHowOften Step 1
        Send($sKey)
        Sleep(200) ; to increase the robustness wait a bit between each input/send
    Next
EndFunc

_clickButtonRun()
_IELoadWait($oIE, 1000)
WinWaitActive('Oracle Fusion Middleware Forms Services', '', 15)
_sendKeystrokesSeveralTimes($sLogin)
_sendKeystrokesSeveralTimes('{TAB}')
_sendKeystrokesSeveralTimes($sPasswd)
_sendKeystrokesSeveralTimes('{TAB}')
_sendKeystrokesSeveralTimes('PROD9')
_sendKeystrokesSeveralTimes('{ENTER}')
WinWaitActive('My Window', '', 5)
_sendKeystrokesSeveralTimes('{TAB}')
_sendKeystrokesSeveralTimes('{DOWN}', 11)
_sendKeystrokesSeveralTimes('{UP}')
_sendKeystrokesSeveralTimes('{RIGHT}')
_sendKeystrokesSeveralTimes('{DOWN}', 4)
_sendKeystrokesSeveralTimes('{RIGHT}')
_sendKeystrokesSeveralTimes('{DOWN}', 2)
_sendKeystrokesSeveralTimes('{RIGHT}')
_sendKeystrokesSeveralTimes('{DOWN}', 5)
_sendKeystrokesSeveralTimes('{RIGHT}')
_sendKeystrokesSeveralTimes('{DOWN}', 4)
_sendKeystrokesSeveralTimes('{ENTER}')
_sendKeystrokesSeveralTimes('03/01/2019')
_sendKeystrokesSeveralTimes('{TAB}', 3)
MouseClick('left', 268, 363)
0
ответ дан user4157124 18 January 2019 в 11:18
поделиться