Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] Запоминать последовательность нажатия определенных клавиш (http://forum.oszone.net/showthread.php?t=252392)

McLotos 26-01-2013 16:29 2075503

Запоминать последовательность нажатия определенных клавиш
 
Доброго времени суток. Подскажите. как можно сделать чтобы AutoIT отслеживал последовательность некоторых клавиш.
Поясню детально:
Есть программа для тестирования написанная на AutoIT (как будто нельзя было её на delphi написать =( )
Программа выводит вопрос и несколько вариантов ответа, казалось бы сиди и отвечай, но она блокирует мышь и почти всю клавиатуру оставляя в рабочем состоянии только 4 клавиши - цифры от 1 до 4
Я сам код не видел, потому-что у меня задание написать под эту прогу функцию, которая бы просто запоминала в какой последовательности пользователь нажимал эти клавиши
Я пробовал делать через _IsPressed
Т.е. в цикле вертится select с 4ми вариантами и если какой-то вариант появился то он записывается в файл
Но AutoIT выдал несколько интересных сюрпризов:
1. Записывалась только первая нажатая кнопка, а дальше ничего больше не писалось, хотя функция продолжала работать
2. Запоминалась первая нажатая кнопка и дублировалась столько раз, сколько кнопок было нажато.
3. Записывалась каждая кнопка но вводилась в файл несколько раз подряд - если бы хотя бы количество повторений было одинаковое можно было бы отфильтровать, но оно всегда разное.
Помогите разобраться.

LehaMechanic 26-01-2013 17:02 2075527

Цитата:

Цитата McLotos
Я пробовал делать через _IsPressed »

Может быть в этом затык:

http://www.autoitscript.com/autoit3/..._IsPressed.htm (по-английски)
http://autoit-script.ru/autoit3_docs..._ispressed.htm (по-русски)
Цитата:

If calling this function repeatedly, you should open 'user32.dll' and pass the handle.
Если функция вызывается повторно, следует открыть 'user32.dll' и передать указатель.
Там же и пример, как использовать.

Creat0R 26-01-2013 20:06 2075614

Попахивает Keylogger'ом, для отслежки ввода паролей...

Цитата:

Цитата McLotos
Я сам код не видел, потому-что у меня задание написать под эту прогу функцию »

Это не причина чтобы не смотреть на код :). Я даже большее скажу, это как раз таки причина чтобы таки да посмотреть на код.

McLotos 26-01-2013 22:58 2075772

Creat0R, спокойнее, всё очень просто, есть готовый тестер, у которого куча заморочек, именно поэтому мне и не показывают весь код целиком, чтобы я не смог обойти их блокировку клавиатуры и подсказать студентам как параллельно с тестером запускать блокнот с ответами. Так что вполне понятно почему этот препод усиленно старается не показывать мне код. =)

Creat0R 27-01-2013 02:44 2075857

Цитата:

Цитата McLotos
вполне понятно почему этот препод усиленно старается не показывать мне код »

Видимо не очень ознакомлённый с AutoIt препод, если думает что его код нельзя получить, ладно, это так...

Цитата:

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

Код:

#include "IsPressedEx.au3"

Global $sLog_File = @ScriptDir & '\Answers.log'

HotKeySet('{ESC}', '_Exit')

While 1
    $vRet = _IsPressedEx("1|2|3|4")

    If $vRet Then
        $vRet = __KeyGetType($vRet, 0)

        MsgBox(64, 'Отслеживание ответов', 'Нажата клавиша: ' & $vRet)

        If FileGetSize($sLog_File) > 0 Then
            $vRet = ',' & $vRet
        EndIf

        $hFile = FileOpen($sLog_File, 1)
        FileWrite($hFile, $vRet)
        FileClose($hFile)
    EndIf

    Sleep(10)
WEnd

Func _Exit()
    Exit
EndFunc

Нужн подключить библиотеку _IsPressedEx.au3

Цитата:

Цитата McLotos
Я пробовал делать через _IsPressed »

Можно увидеть скрипт?

McLotos 28-01-2013 08:17 2076612

Если убрать msgbox, то Ваш вариант тоже записывает каждое нажатие несколько раз.
А там немного другая система, справой стороны ведётся лог вопрос-ответ и статистика правильных ответов
Как сделать чтобы без MsgBox всё корректно работало?
Я сейчас на работе, а скрипт на домашнем компе, в общем логика там была примерно такая
если нажата 31
открыть DLL
открыть файл
записать туда А
закрыть файл
закрыть DLL
и так на каждую из 8и клавиш, потому-что как выяснилось, например 1 и Numpad1 имеют разные коды

Iska 28-01-2013 12:07 2076721

McLotos, прислушайтесь к совету:
Цитата:

Цитата Creat0R
Видимо не очень ознакомлённый с AutoIt препод, если думает что его код нельзя получить »

и выложите скрипт.

McLotos 28-01-2013 12:40 2076742

Код:

#include <Misc.au3>
#include <File.au3>
While 1
    If _IsPressed("31",DllOpen("user32.dll")) Then
          If FileExists (@ScriptDir & '\' & $username & '.' $datetime & '.test.log') Then
                  FileOpen(@ScriptDir & '\' & $username & '.' $datetime & '.test.log',1)
          Else
                  _FileCreate(@ScriptDir & '\' & $username & '.' $datetime & '.test.log')
          EndIf         
                  FileWrite(@ScriptDir & '\' & $username & '.' $datetime & '.test.log', "A")
                  FileClose(@ScriptDir & '\' & $username & '.' $datetime & '.test.log')
                  DllClose("user32.dll")
                  ; и так далее т.е. 31, 32, 33, 34б 61, 62, 63 ,64
    Sleep(20)
WEnd

Я вот например сейчас запустил эту часть кода, ввёл тупо 12341234 подряд
и он мне в файл записал
ABCCCDDDAAABBCCCCDDD
может так в самом autoit стоит какое-то ограничение, или он просто не успевает стирать из памяти букву и вводит её повторно?
Может тогда логичнее делать через массив, а после завершения (кнопка Посчитать) уже весь массив выдавать пользователю и записывать в файл? Тогда получается что эта штука, которая справа выводит номер вопроса-вариант ответа она работать не будет =(

Creat0R 28-01-2013 14:42 2076851

Цитата:

Цитата McLotos
Если убрать msgbox, то Ваш вариант тоже записывает каждое нажатие несколько раз. »

Исправленный вариант:

Код:

#include "IsPressedEx.au3"

Global $sLog_File = @ScriptDir & '\Answers.log'

HotKeySet('{ESC}', '_Exit')

While 1
    $vRet = _IsPressedEx("1|2|3|4|{Numpad1}|{Numpad2}|{Numpad3}|{Numpad4}")

    If $vRet Then
        ;Это для ожидания отжатия клавиши
        While _IsPressed($vRet)
            Sleep(10)
        WEnd

        $vRet = __KeyGetType($vRet, 0)

        ;Эта строка удаляет Numpad если нажата цифра на правой части клавиатуры, если нужно записывать вместе с Numpad, ту следует убрать строку ниже
        $vRet = StringReplace($vRet, 'Numpad', '')

        If FileGetSize($sLog_File) > 0 Then
            $vRet = ',' & $vRet
        EndIf

        $hFile = FileOpen($sLog_File, 1)
        FileWrite($hFile, $vRet)
        FileClose($hFile)
    EndIf

    Sleep(10)
WEnd

Func _Exit()
    Exit
EndFunc

Цитата:

Цитата McLotos
Код »

Неправильное использование функции, DllOpen не нужно помещать в параметр, её нужно вызвать заранее и передавать переменную, а FileOpen тоже неверно используется, см. справку к функциям.

McLotos 28-01-2013 15:48 2076923

Цитата:

Цитата Creat0R
Неправильное использование функции, DllOpen не нужно помещать в параметр, её нужно вызвать заранее и передавать переменную, а FileOpen тоже неверно используется, см. справку к функциям. »

Вроде делал как в примерах в AutoIT справочнике, странно.
Блин, спасибо, как всегда выручил!

Creat0R 28-01-2013 15:49 2076925

Цитата:

Цитата McLotos
Вроде делал как в примерах в AutoIT справочнике »

Я бы хотел посмотреть на эти примеры из справки.

Цитата:

Цитата McLotos
спасибо »

Если тема решена, то её следует пометить как таковую.


Время: 03:26.

Время: 03:26.
© OSzone.net 2001-