Показать полную графическую версию : [Архив - Часть 1.3] AutoIt скрипты
Diamond
Ты как то спрашивал про то, как заставить гуи НЕ отображать системны стиль, так вот я нашел на офф. форуме решение этой задачки...
Это простой скачивальщик (не знаю на сколько он полезен), при его запуске задаётся стиль как в старых/без стильных виндоус.
Вот ссылка (http://www.sendspace.com/file/i0mx12), я немного переделал, так как там не совсем весь гуи был таким стилем, я даже удивился, как окно от FileSelectFolder() приняло старый (не)стиль :) - видимо и всё остальное что будет использованно в гуи будет иметь подобный стиль.
Я не разбирался как оно работает, но видимо там упорно используются Dll'овские штучки :)
amel27
Тоже на офф. форуме нашел функцию для слежения за бездельем юзера :biggrin: (немного переделал для примера) :
Dim $i_LastActive = _LastActive()
$TimeInit = TimerInit()
While 1
If $i_LastActive <> _LastActive() Then ExitLoop
Sleep(100)
WEnd
MsgBox(64, "Activity Test", "You was not active <" & Round(TimerDiff($TimeInit)/1000, 1) & "> second(s)")
Func _LastActive($v_User32Dll = 'user32.dll')
Local $str_LastInput = DllStructCreate('uint;dword')
DllStructSetData($str_LastInput, 1, DllStructGetSize($str_LastInput))
DllCall($v_User32Dll, 'int', 'GetLastInputInfo', 'ptr', DllStructGetPtr($str_LastInput))
Return DllStructGetData($str_LastInput, 2)
EndFunc
Я давно искал подобное, мне нужно было проверить, была ли нажата какая либо клавиша, или кнопка мышки, и это идеально подходит!
Creat0RПо PID вроде не работаетда не, вроде работает если PID передавать не строкой, а числом
я пытаюсь написать утилитку менеджер процессов в таком случае эффективней выполнять запрос не по отдельным процессам, а сразу по всему списку, вот вариант ProcessList, который кроме PID и Name выводит дополнительно инфу по загрузке CPU:$a = _ProcessList ('')
If IsArray ($a) Then
For $i=0 To $a[0][0]
ConsoleWrite (StringFormat('%4i', $a[$i][0]) & ' : ' & StringFormat('%02i', $a[$i][2]) & ' : ' & $a[$i][1] & @CRLF)
Next
EndIf
Func _ProcessList ($name = '', $ticks = 1000)
Local $arrWork[1][3] = [[0,0,0]], $arrMain[1][3] = [[0,'_Summary',0]]
Local $i, $colItems, $objItem, $objWMIService = ObjGet("winmgmts:\\.\root\CIMV2"), $where = 'WHERE IDProcess>0'
If $name <> '' Then $where &= ' AND Name=' & '"' & $name & '"'
; Считываем необходимые характеристики процессов - попытка №1
$colItems = $objWMIService.ExecQuery ("SELECT IDProcess,PercentProcessorTime,Timestamp_Sys100NS FROM Win32_PerfRawData_PerfProc_Process " & $where, "WQL", 0x30)
For $objItem In $colItems
$arrWork[0][0]+=1
ReDim $arrWork[$arrWork[0][0]+1][3]
$arrWork[$arrWork[0][0]][0]=$objItem.IDProcess
$arrWork[$arrWork[0][0]][1]=$objItem.PercentProcessorTime
$arrWork[$arrWork[0][0]][2]=$objItem.Timestamp_Sys100NS
Next
If $arrWork[0][0]=0 Then Return ''
; Накапливаем статистику...
Sleep ($ticks)
; Считываем необходимые характеристики процессов - попытка №2
$colItems = $objWMIService.ExecQuery ("SELECT IDProcess,PercentProcessorTime,Timestamp_Sys100NS FROM Win32_PerfRawData_PerfProc_Process " & $where, "WQL", 0x30)
For $objItem In $colItems
For $i=1 To $arrWork[0][0]
If $arrWork[$i][0]=$objItem.IDProcess Then
$arrMain[0][0]+=1
ReDim $arrMain[$arrMain[0][0]+1][3]
$arrMain[$arrMain[0][0]][0]=$objItem.IDProcess
$arrMain[$arrMain[0][0]][1]=$objItem.Name
$arrMain[$arrMain[0][0]][2]=Round(100*($arrWork[$i][1]-$objItem.PercentProcessorTime)/($arrWork[$i][2]-$objItem.Timestamp_Sys100NS))
$arrMain[0][2]+=$arrMain[$arrMain[0][0]][2]
EndIf
Next
Next
If $arrMain[0][2]>100 Then $arrMain[0][2]=100
Return $arrMain
EndFunc
Creat0Rна офф. форуме нашел функцию для слежения за бездельем юзера мне свой вариант нравится больше, т.к. позволяет отслеживать не только начало, но и конец бездействия.... кстати можно использовать для хранителей экрана :) #include <Date.au3>
$IdleMinimum = 5000 ; допустимый период неактивности в миллисекундах
While 1
$iIdle = _IdleWaitStart ($IdleMinimum)
ConsoleWrite (_Now () & ' ' & @UserName & ' неактивен уже ' & _TickToTimeString ($iIdle) & @CRLF)
$iIdle = _IdleWaitCommit($IdleMinimum)
ConsoleWrite (_Now () & ' ' & @UserName & ' был неактивен ' & _TickToTimeString ($iIdle) & @CRLF)
Wend
; Ожидание начала бездействия пользователя.
; Возвращает время неактивности (в тиках)
; $idlesec - минимальная длительность ожидаемой неактивности (в тиках)
Func _IdleWaitStart ($idlesec)
Local $aRet, $iSave, $iTick, $LastInputInfo = DllStructCreate ("uint;dword")
DllStructSetData ($LastInputInfo, 1, DllStructGetSize ($LastInputInfo))
DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
Do
Sleep(200)
$iSave= DllStructGetData ($LastInputInfo, 2)
DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
$aRet = DllCall ("kernel32.dll", "long", "GetTickCount")
Until ($aRet[0] - DllStructGetData ($LastInputInfo, 2))> $idlesec
Return $aRet[0] - DllStructGetData ($LastInputInfo, 2)
EndFunc
; Ожидание окончания бездействия пользователя.
; Возвращает время неактивности в (тиках)
; $idlesec - минимальная длительность ожидаемой неактивности в (тиках)
Func _IdleWaitCommit ($idlesec)
Local $iSave, $LastInputInfo = DllStructCreate ("uint;dword")
DllStructSetData ($LastInputInfo, 1, DllStructGetSize ($LastInputInfo))
DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
Do
$iSave = DllStructGetData ($LastInputInfo, 2)
Sleep(200)
DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
Until (DllStructGetData ($LastInputInfo, 2)-$iSave) > $idlesec
Return DllStructGetData ($LastInputInfo, 2)-$iSave
EndFunc
Func _TickToTimeString ($iTicks)
Local $iHours, $iMins, $iSecs, $sText = ''
_TicksToTime ($iTicks, $iHours, $iMins, $iSecs)
If $iHours Then $sText = $iHours & ' часов '
If $iMins Then $sText = $sText & $iMins & ' минут '
If $iSecs Then $sText = $sText & $iSecs & ' секунд'
If $sText = '' Then $sText = 'меньше секунды'
Return $sText
EndFunc
amel27
работает если PID передавать не строкой, а числом
Строкой в смысле String'ом ? я из переменной передаю, но переменная содержит непосредственно цифри (это PID берётся из списка прцессов в ListView)... но как выяснилось, берутся не только цифры(?), я подставил Number($Pid) и всё нормально определяется... мистика... :)
в таком случае эффективней выполнять запрос не по отдельным процессам, а сразу по всему списку
100% согласен, но у меня с этим проблема - у меня уже считывается список в ListView, и при обновлении этого списка, нужно обновлять только колонку с загрузкой ЦП, т.к весь список обновлять слишком долго (для обновления списка в случае отсутствия/добавления процесса, идёт отдельная проверка, где сравнивается список существующих процессов и список процессов в ListView, если найдены различия, то обновляется всё).
мне свой вариант нравится больше
Мне тоже (твой) :) - интересно, можно на его основе, сделать запись статистики? т.е к примеру, указать промежуток слежения за юзером (можно из InputBox() или ещё лучше, GUI нарисовать с отображением графика даты и времени), допустим в течении 24-ёх часов, и накапливать в переменную (а лучше в массив) данные, А) о том сколько юзер был не активен (в течении этого времени, т.е 24-ёх часов), и Б) сколько юзер был активен - данные чтобы возвращались в поноценном формате времени (по необходимости и даты)... я попробовал что-то подбное сделать, но безуспешно... могу выложить мои безнадёжные попытки если нужно (там уже гуик нарисован) :)
Creat0RPID берётся из списка прцессов в ListViewзначит нужно передавать значение переменной, обработанное ф-цией Number()
100% согласен, но у меня с этим проблема - у меня уже считывается список в ListViewИмхо лучше ввести пару рабочих массивов со списками процессов, которые бы поочередно (целиком) обновлялись WMI-запросами, и на основании сравнения этих массивов определять какие GUI-элементы необходимо обновить...
интересно, можно на его основе, сделать запись статистики?не вижу препятствий, например можно вести два массива - с информаций об активности и о бездействии: начало, конец и длительность временного периода... останется только решить в каком виде представлять содержимое массивов#include <Date.au3>
$IdleMinimum = 5000 ; Minimum inactivity in seconds
Dim $arrUserActive[1][3]=[[0,0,0]]
Dim $arrUserInactive[1][3]=[[0,0,0]]
While 1
$arrUserActive[0][0]+=1
ReDim $arrUserActive[$arrUserActive[0][0]+1][3]
$arrUserActive[$arrUserActive[0][0]][0]=_Now ()
$iIdle = _IdleWaitStart ($IdleMinimum)
$arrUserActive[$arrUserActive[0][0]][1]=_Now ()
$arrUserActive[$arrUserActive[0][0]][2]=_TickToTimeString($iIdle)
ConsoleWrite ("Записей активности: " & $arrUserActive[0][0] & @TAB & "Записей нективности: " & $arrUserInactive[0][0] & @CRLF)
$arrUserInactive[0][0]+=1
ReDim $arrUserInactive[$arrUserInactive[0][0]+1][3]
$arrUserInactive[$arrUserInactive[0][0]][0]=_Now ()
$iIdle = _IdleWaitCommit($IdleMinimum)
$arrUserInactive[$arrUserInactive[0][0]][1]=_Now ()
$arrUserInactive[$arrUserInactive[0][0]][2]=_TickToTimeString($iIdle)
ConsoleWrite ("Записей активности: " & $arrUserActive[0][0] & @TAB & "Записей нективности: " & $arrUserInactive[0][0] & @CRLF)
WendЗ.Ы.это только пример - для графического представления потребуется числовое представление интервалов а не текст
amel27
значит нужно передавать значение переменной, обработанное ф-цией Number()
Я так и делаю (уже)...
я подставил Number($Pid) и всё нормально определяется
Имхо лучше ввести пару рабочих массивов со списками процессов, которые бы поочередно (целиком) обновлялись WMI-запросами, и на основании сравнения этих массивов определять какие GUI-элементы необходимо обновить...
Не так то всё просто, ещё нужно сравнивать какой именно элемент в списке соответствует элементу массива, а иногда в списке могут быть (и будут) одинаковые имена процессов, что может вызвать конфиликты... естественно можно сравнивать по PID, но всё же всё это для меня пока ещё смутно... нужно немного поламать голову ;)
не вижу препятствий
Знаю, а вот я вижу... присмотревшись к твоему примеру, у меня началась голова кружится... я понимаю (с трудом) двумерный массив, а трёхмерный массив у меня вызывает желание закрыть побыстрее SciTE :biggrin:
Я пока остановлюсь на простеньком... я сделал типа юмористичесукую напоминалку для бездельника :) - вот код:
HotKeySet("^e", "Quit")
TraySetIcon("shell32.dll", 111)
TraySetToolTip("Laziness Detecter (!)")
$Idle = 0
$MinLaziness = 10
$MaxLaziness = 60
$LazyLimit = Random($MinLaziness, $MaxLaziness, 1)
$TimeStamp = TimerInit()
AdlibEnable("CheckLaziness", 10)
While 1
$Idle = _IdleWaitCommit(0)
TrayTip("", "", 0)
$TimeStamp = TimerInit()
$Idle = 0
WEnd
Func CheckLaziness()
$TimeDiff = Round(TimerDiff($TimeStamp)/1000)
If $TimeDiff > $LazyLimit And $Idle = 0 Then
TrayTip("You are lazy", "You are been lazy for a long time (" & _SecsToTime($TimeDiff, ":") & ")", 5, 1)
$TimeStamp = TimerInit()
$LazyLimit = Random($MinLaziness, $MaxLaziness, 1)
EndIf
If $TimeDiff >= ($LazyLimit/2) Then TrayTip("", "", 0)
EndFunc
Func _SecsToTime($iTicks, $Delim)
If Number($iTicks) >= 0 Then
$iHours = Int($iTicks / 3600)
$iTicks = Mod($iTicks, 3600)
$iMins = Int($iTicks / 60)
$iSecs = Round(Mod($iTicks, 60))
If StringLen($iHours) = 1 Then $iHours = "0" & $iHours
If StringLen($iMins) = 1 Then $iMins = "0" & $iMins
If StringLen($iSecs) = 1 Then $iSecs = "0" & $iSecs
$Time = $iHours & $Delim & $iMins & $Delim & $iSecs
Return $Time
Else
SetError(1)
Return 0
EndIf
EndFunc
Func _IdleWaitCommit($idlesec)
Local $iSave, $LastInputInfo = DllStructCreate ("uint;dword")
DllStructSetData ($LastInputInfo, 1, DllStructGetSize ($LastInputInfo))
DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
Do
$iSave = DllStructGetData ($LastInputInfo, 2)
Sleep(200)
DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
Until (DllStructGetData ($LastInputInfo, 2)-$iSave) > $idlesec
Return DllStructGetData ($LastInputInfo, 2)-$iSave
EndFunc
Func Quit()
Exit
EndFunc
Можно задать минимум и максимум ($MinLaziness = 10 и $MaxLaziness = 60 - в секундах) время в течении которого будет считаться что юзер бкездельник :biggrin:
Будет перебираться случайный промежуток времени, и выскакивать треевская подсказака с напоминанием о том сколько времени пользователь ничего не делал.
Creat0Rтрёхмерный массив у меня вызывает желание закрыть побыстрее SciTE тут кажись только двумерные... ;)
Не так то всё просто, ещё нужно сравнивать какой именно элемент в списке соответствует элементу массива, а иногда в списке могут быть (и будут) одинаковые имена процессов, что может вызвать конфиликты... естественно можно сравнивать по PID, но всё же всё это для меня пока ещё смутно... нужно немного поламать головуможет этот пример поможет:#include <array.au3>
$b = _ProcessList ()
While 1
Sleep (1000)
Dim $a = $b
$b = _ProcessList ()
_CompProcList ($a, $b)
Wend
Func _CompProcList (ByRef $a, ByRef $b)
Local $i
Local $a1[$a[0][0]+1], $a2[$a[0][0]+1], $b1[$b[0][0]+1], $b2[$b[0][0]+1]
If $a[0][0] Then
; индексируем массив $a
For $i=1 To $a[0][0]
$a1[$i]=$a[$i][0] & $a[$i][1] ; PID и имя процесса
$a2[$i]=$a[$i][0] & $a[$i][1] & $a[$i][2] ; PID, имя процесса и ЦП
Next
; индексируем массив $b
For $i=1 To $b[0][0]
$b1[$i]=$b[$i][0] & $b[$i][1] ; PID и имя процесса
$b2[$i]=$b[$i][0] & $b[$i][1] & $b[$i][2] ; PID, имя процесса и ЦП
Next
; Сравниваем новый массив ($b) со старым ($a)
For $i=1 To $b[0][0]
$f1 = _ArraySearch($a1, $b1[$i], 1)
$f2 = _ArraySearch($a2, $b2[$i], 1)
If $f1<0 Then
ConsoleWrite('Новый процесс: ' & StringFormat ('%4.0i',$b[$i][0]) & ' : ' & $b[$i][1] & @CRLF)
ElseIf $f1>0 And $f2<0 Then
ConsoleWrite('Изменилась загрузка ЦП: ' & StringFormat ('%4.0i',$b[$i][0]) & ' : ' & StringFormat ('%02i',$a[$f1][2]) & ' > ' & StringFormat ('%02i',$b[$i][2]) & ' : ' & $b[$i][1] & @CRLF)
EndIf
Next
; Сравниваем старый массив ($a) с новым ($b)
For $i=1 To $a[0][0]
$f1 = _ArraySearch($b1, $a1[$i], 1)
If $f1<0 Then
ConsoleWrite('Исчез процесс: ' & StringFormat ('%4.0i',$a[$i][0]) & ' : ' & $a[$i][1] & @CRLF)
EndIf
Next
EndIf
EndFunc
сделал типа юмористичесукую напоминалку для бездельника забавно, хотя Random имхо лишний... по крайней мере для бездельника :)
amel27
тут кажись только двумерные
Упс.. точно... но тоже путает (особенно подстановка самого массива в элемент этого же массива в каждом месте :wacko: ).
может этот пример поможет:
О! это точно поможет, попробую его адаптировать в утилитку. Спасибо!
забавно, хотя Random имхо лишний... по крайней мере для бездельника
Ну это больше для прикола чем для точного определения безделья... я например брату на компьютер поставлю, и пусть в определённый промежуток времени выскакивает сообщение что он бездельник, и при чём не в один и тот же промежуток, а каждый раз (почти) по разному, чтобы было интереснее :) ...
Кстати, я вот ещё что придумал... заносим в массив (можно из файла) разные сообщения (с разной характеристикой и контекстом), и тоже случайным перебором выводим в TrayTip'е, а также можно занести в массив все файлы из папки мелодии Windows - C:\windows\media (можно даже свою папку с мелодиями указать), и тоже в момент вывода сообщения случайно (в смысле в случайном порядке :) ) их проигрывать...
Ура!!! я это сделал, немного помучался, но всё же сделал!
Вместо использования звуков системы, я использовал её персонажа - старый добрый волшебник “Merlin” :)...
http://bedniy.chat.ru/merlingreet.gif
Если в системе не найден персонаж, то выводится TrayTip. А и ещё, чтобы персонаж ещё и говорил, в системе должен быть установлен голосовой движёк (http://www.google.ru/search?hl=ru&newwindow=1&sa=X&oi=spell&resnum=0&ct=result&cd=1&q=%D0%B3%D0%BE%D0%BB%D0%BE%D1%81%D0%BE%D0%B2%D0%BE%D0%B9+%D0%B4%D0%B2%D0%B8%D0%B6%D0%BE%D0%BA&spell=1).
При простое более 5-ти секунд, иконка трея меняется на неактивного юзера, при активности иконка обратно меняется на что-то вроде юзера в движении (не смог в системе найти более походящей иконки).
Также при простое в переменную $TotalTime накапливается общее время простоя (секунды), а при активности эта переменная сбрасывается на ноль (0)...
Также удалось заносить в массив отдельные заготовки сообщении, если есть файл сообщении (LazyMessages.dat), то с него считываются строки, если его нет, то в скрипте уже заготовлены 10 сообщении (на английском)...
Для выхода из скрипта в любое время, нужно нажать Ctrl E (при английской раскладке).
В общем, на мой взгляд получилось довольно неплохо... правда есть пару моментов, например, как можно проверить закончил ли персонаж читать текст, и соответственно убить его? :) ... вот скрипт:
HotKeySet("^e", "Quit")
TraySetIcon("shell32.dll", 160)
TraySetToolTip("Laziness Detecter (!)")
Dim $MessagesArr[11]
$MessagesArr[0] = 10
$MessagesArr[1] = "You are been lazy for a long time <%n>"
$MessagesArr[2] = "This is enough, start doing something >:( - you are lazy to much (%n)"
$MessagesArr[3] = "Hello!? Any one is home? why you are so lazy so long time? <%n> do somthing!"
$MessagesArr[4] = "Hi! Don't you fill like cow? Laziness is reason number 1 of why people die"
$MessagesArr[5] = "It's been over a <%n> time sense you touch your computer, touch it now!"
$MessagesArr[6] = "I can not wait for you so long (%n), I am going to shutdown myself.... beep.. beeep.. beeeeeep"
$MessagesArr[7] = "Hey man, are you forgot about me? Fine! I want to divorced"
$MessagesArr[8] = "You have no check your email for <%n> time, maybe there something intersteing?"
$MessagesArr[9] = "There is a virus on your computer! (it exists there for a long time <%n>) perform virus checking immediately!"
$MessagesArr[10] = "Hi! What's up dog? Don't pay attention; I am just stupid character that doesn't need attention! >:("
$MessagesFile = "LazyMessages.dat"
If FileExists($MessagesFile) And FileRead($MessagesFile) <> "" Then $MessagesArr = StringSplit(FileRead($MessagesFile), @LF)
$Idle = 0
$TotalTime = 0
$MinLaziness = 10
$MaxLaziness = 60
$LazyLimit = Random($MinLaziness, $MaxLaziness, 1)
$TimeStamp = TimerInit()
AdlibEnable("CheckLaziness", 10)
While 1
$Idle = _IdleWaitCommit(0)
TraySetIcon("shell32.dll", 160)
TrayTip("", "", 0)
$TimeStamp = TimerInit()
$Idle = 0
$TotalTime = 0
WEnd
Func CheckLaziness()
$TimeDiff = Round(TimerDiff($TimeStamp)/1000)
If $TimeDiff > $LazyLimit And $Idle = 0 Then
TraySetIcon("shell32.dll", 111)
$TotalTime += $TimeDiff
$LazyTime = _SecsToTime($TotalTime, ":")
$TextToSay = StringReplace($MessagesArr[Random(1, $MessagesArr[0], 1)], "%n", $LazyTime)
$SleepTime = Round((StringLen($TextToSay)/7)*1000)
If StringLen($TextToSay) < 7 Then $SleepTime = 5000
CharacterMsg($TextToSay, Random(100, @DesktopWidth-100, 1), Random(10, @DesktopHeight-150, 1), $SleepTime)
If @error Then TrayTip("You are lazy", $TextToSay, 5, 1)
$LazyLimit = Random($MinLaziness, $MaxLaziness, 1)
$TimeStamp = TimerInit()
EndIf
If $TimeDiff >= ($LazyLimit/2) Then TrayTip("", "", 0)
If $TimeDiff >= 5 And $LazyLimit > 5 Then TraySetIcon("shell32.dll", 111)
EndFunc
Func _SecsToTime($iTicks, $Delim)
If Number($iTicks) >= 0 Then
$iHours = Int($iTicks / 3600)
$iTicks = Mod($iTicks, 3600)
$iMins = Int($iTicks / 60)
$iSecs = Round(Mod($iTicks, 60))
If StringLen($iHours) = 1 Then $iHours = "0" & $iHours
If StringLen($iMins) = 1 Then $iMins = "0" & $iMins
If StringLen($iSecs) = 1 Then $iSecs = "0" & $iSecs
$Time = $iHours & $Delim & $iMins & $Delim & $iSecs
Return $Time
Else
SetError(1)
Return 0
EndIf
EndFunc
Func _IdleWaitCommit($idlesec)
Local $iSave, $LastInputInfo = DllStructCreate ("uint;dword")
DllStructSetData ($LastInputInfo, 1, DllStructGetSize ($LastInputInfo))
DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
Do
$iSave = DllStructGetData ($LastInputInfo, 2)
Sleep(200)
DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
Until (DllStructGetData ($LastInputInfo, 2)-$iSave) > $idlesec
Return DllStructGetData ($LastInputInfo, 2)-$iSave
EndFunc
Func CharacterMsg($TextToSay, $MovexX=200, $MoveY=200, $Sleep=5000)
$figure = "merlin"
If $TextToSay = "" Then $TextToSay = "Oops! there was an Error!"
$Path = @WindowsDir & "\MSAGENT\CHARS\merlin.acs"
If Not FileExists($Path) Then Return SetError(1)
$AgentControl = ObjCreate("Agent.Control.1")
$SinkObject=ObjEvent($AgentControl, "event_")
If Isobj($AgentControl) Then $AgentControl.Connected = True
$AgentControl.Characters.Load($figure, $Path)
$A = $AgentControl.Characters($figure)
$A.MoveTo($MovexX, $MoveY, 0)
$A.Show
$A.Speak($TextToSay)
$A.Play("Greet")
$A.Play("RestPose")
Sleep($Sleep)
$A.Hide
$A.StopAll
$AgentControl.Characters.Unload($figure)
EndFunc
Func Quit()
Exit
EndFunc
P.S
Скрипт чёрно-белый потому как в разукрашенном виде он занимает более 40-ка тысяч строк.
Sanja Alone
12-03-2007, 17:16
Я тоже игрался с msagent-ом. Мои наблюдения:
Поскольку у различных персонажей разные действия, для обработки этой ситуации мне пришлось влепить Switch. А как бы вызывать действия случайным образом (ес-но имеющиеся у конкретного персонажа).
Даже после Unload-а персонажа, в памяти продолжает висеть процесс AgentSvr.exe, к-рый занимает порядка 25-30Мб ОЗУ - это неприкольно, а убить процесс как-то некрасиво...
Если агент был запущен из бесконечного цикла, то, пока он не будет Unload-ен, основной цикл стоит на паузе. В связи с этим возник вопрос о возможности реализации многопоточных задач посредстом AutoIt в целом.
#include <File.au3>
#include <Misc.au3>
$Path=@WindowsDir&"\MSAGENT\CHARS\"
$figures=_FileListToArray($Path,"*.acs",1)
;демонстрация
_msagent("Привет! Это просто тест")
Func _msagent($msg)
If IsArray($figures) Then
$P = $Path & $figures[Random(1,$figures[0],1)]
$fig = StringMid($P,StringInStr($P,'\',0,-1)+1)
$fig = StringLeft($fig,StringInStr($fig,".acs",0,-1)-1)
If FileExists($P) Then
$AgentControl = ObjCreate("Agent.Control.1")
$SinkObject = ObjEvent($AgentControl, "event_")
If Isobj($AgentControl) Then
$AgentControl.Connected = True
$AgentControl.Characters.Load($fig, $P)
With $AgentControl.Characters($fig)
.Show
Switch StringLower($fig)
Case 'offcat'
.Play("Greeting")
.Play("RestPose")
Case 'dot'
.Play("Greeting")
.Play("RestPose")
Case 'f1'
.Play("Greeting")
.Play("RestPose")
Case 'logo'
.Play("Greeting")
.Play("RestPose")
Case 'rocky'
.Play("Greeting")
.Play("RestPose")
Case 'clippit'
.Play("Congratulate")
.Play("RestPose")
Case 'mnature'
.Play("Congratulate")
.Play("RestPose")
Case 'qmark'
.Play("Welcome")
.Play("RestPose")
Case 'angel'
.Play("Halo")
.Play("Glow")
.Play("Glowoff")
Case 'blonde fem a'
.Play("Blink")
.Play("Wink")
.Play("RestPose")
Case 'candy'
.Play("Blink")
.Play("RestPose")
Case 'max'
.Play("Blink")
.Play("RestPose")
Case 'paige'
.Play("Pointleftreturn")
Case 'reaper'
.Play("Smile")
.Play("RestPose")
Case 'scientist'
.Play("Blackboard")
.Play("Entropy")
.Play("RestPose")
Case 'sharky'
;
Case Else
.Play("Greet")
.Play("RestPose")
EndSwitch
While _KeyPressed()=0
.MoveTo(Random(180,@DesktopWidth-180,1), Random(260,@DesktopHeight-260,1))
.Speak($msg)
WEnd
.Hide
.StopAll
Endwith
$AgentControl.Characters.Unload($fig)
EndIf
EndIf
EndIf
EndFunc
Func _KeyPressed()
Local $j
Local $dll = DllOpen("user32.dll")
For $j = 01 to 20
If _IsPressed($j, $dll) Then
DllClose($dll)
Return 1
EndIf
Next
DllClose($dll)
Return 0
EndFunc
Sanja Alone
Поскольку у различных персонажей разные действия, для обработки этой ситуации мне пришлось влепить Switch. А как бы вызывать действия случайным образом (ес-но имеющиеся у конкретного персонажа).
Можно занести эти действия в массив, и перебирать его по Random (я также в примере сократил немного Switch ;) ) :
With $AgentControl.Characters($fig)
.Show
Switch StringLower($fig)
Case 'offcat', 'dot', 'logo', 'rocky'
$PlayArr = StringSplit("Greeting|RestPose", "|")
.Play($PlayArr[Random(1, $PlayArr[0], 1)])
Case 'clippit', 'mnature'
$PlayArr = StringSplit("Congratulate|RestPose", "|")
.Play($PlayArr[Random(1, $PlayArr[0], 1)])
Case 'qmark'
$PlayArr = StringSplit("Welcome|RestPose", "|")
.Play($PlayArr[Random(1, $PlayArr[0], 1)])
Case 'angel'
$PlayArr = StringSplit("Halo|Glow|Glowoff", "|")
.Play($PlayArr[Random(1, $PlayArr[0], 1)])
Case 'blonde fem a'
$PlayArr = StringSplit("Blink|Wink|RestPose", "|")
.Play($PlayArr[Random(1, $PlayArr[0], 1)])
Case 'candy', 'max'
$PlayArr = StringSplit("Blink|RestPose", "|")
.Play($PlayArr[Random(1, $PlayArr[0], 1)])
Case 'paige'
.Play("Pointleftreturn")
Case 'reaper'
$PlayArr = StringSplit("Smile|RestPose", "|")
.Play($PlayArr[Random(1, $PlayArr[0], 1)])
Case 'scientist'
$PlayArr = StringSplit("Blackboard|Entropy|RestPose", "|")
.Play($PlayArr[Random(1, $PlayArr[0], 1)])
Case 'sharky'
;
Case Else
$PlayArr = StringSplit("Greet|RestPose", "|")
.Play($PlayArr[Random(1, $PlayArr[0], 1)])
EndSwitch
While _KeyPressed()=0
.MoveTo(Random(180,@DesktopWidth-180,1), Random(260,@DesktopHeight-260,1))
.Speak($msg)
WEnd
.Hide
.StopAll
Endwith
И ещё, цикл который удерживает персонажа, вызывает большую загрузку ЦП, я поставил паузу в 10 мc, и загрузки нет :)
-А что, при использовании Switch учитывается регистр букв? (я про StringLower).
Даже после Unload-а персонажа, в памяти продолжает висеть процесс AgentSvr.exe
Странно, у меня он (процесс) выгружается спустя пару секунд после Unload'а.
Если агент был запущен из бесконечного цикла, то, пока он не будет Unload-ен, основной цикл стоит на паузе.
Тоже заметил, поэтому я использовал AdlibEnable() до вызова функции с загрузкой персонажа.
Кстати, в системе есть более одного персонажа, благодаря этой статье (http://webmarketinglist.ru/view_article.html?id=360), я значительно улучшил скрипт - Я написал функцию которая собирает в массив пути к этим персонажам (если они найдены) - _FiguresListToArray(), и затем на основе этих путей, методом случайного перебора (Random естественно), вызывается персонаж...
А также удалось осуществить “убийство” персонажа при любой активности пользователя (это я реализовал на основе наводок твоего примера - спасибо).
У меня такие вопросы:
1. Где можно узнать список действий определённого персонажа? (желательно средствами AutoIt'а выявить список действии для указанного персонажа).
2. Как можно, и можно ли вообще, регулировать скорость произношения речи? (или хотябы скорость печатания букв).
[hr]
Вот новый скрипт - Детектер лени - Я пока не знаю какой из существующих персонажей что умеет делать, поэтому присвоил им всем одинаковые действия (ошибку вроде не выдаёт) - можно было ещё перебирать оффисные персонажи (как и в статье указанно (http://webmarketinglist.ru/view_article.html?id=360)), но я посчитал это лишнее, хватит пока и 4-ёх :).
HotKeySet("^e", "Quit")
TraySetIcon("shell32.dll", 160)
TraySetToolTip("Laziness Detecter (!)")
Dim $MessagesArr[11]
$MessagesArr[0] = 10
$MessagesArr[1] = "You are been lazy for a long time <%n>"
$MessagesArr[2] = "This is enough, start doing something >:( - you are lazy to much (%n)"
$MessagesArr[3] = "Hello!? Any one is home? why you are so lazy so long time? <%n> do somthing!"
$MessagesArr[4] = "Hi! Don't you fill like cow? Laziness is reason number 1 of why people die"
$MessagesArr[5] = "It's been over a <%n> time sense you touch your computer, touch it now!"
$MessagesArr[6] = "I can not wait for you so long (%n), I am going to shutdown myself.... beep.. beeep.. beeeeeep"
$MessagesArr[7] = "Hey man, are you forgot about me? Fine! I want to divorced"
$MessagesArr[8] = "You have no check your email for <%n> time, maybe there something intersteing?"
$MessagesArr[9] = "There is a virus on your computer! (it exists there for a long time <%n>) perform virus checking immediately!"
$MessagesArr[10] = "Hi! What's up dog? Don't pay attention; I am just stupid character that doesn't need attention! >:("
$MessagesFile = "LazyMessages.dat"
If FileExists($MessagesFile) And FileRead($MessagesFile) <> "" Then $MessagesArr = StringSplit(FileRead($MessagesFile), @LF)
$Idle = 0
$TotalTime = 0
$MinLaziness = 10
$MaxLaziness = 60
$LazyLimit = Random($MinLaziness, $MaxLaziness, 1)
$TimeStamp = TimerInit()
AdlibEnable("CheckLaziness", 10)
While 1
$Idle = _IdleWaitCommit(0)
TraySetIcon("shell32.dll", 160)
TrayTip("", "", 0)
$TimeStamp = TimerInit()
$Idle = 0
$TotalTime = 0
WEnd
Func CheckLaziness()
$TimeDiff = Round(TimerDiff($TimeStamp)/1000)
If $TimeDiff > $LazyLimit And $Idle = 0 Then
TraySetIcon("shell32.dll", 111)
$TotalTime += $TimeDiff
$LazyTime = _SecsToTime($TotalTime, ":")
$TextToSay = StringReplace($MessagesArr[Random(1, $MessagesArr[0], 1)], "%n", $LazyTime)
$SleepTime = Round((StringLen($TextToSay)/7)*1000)
If StringLen($TextToSay) < 7 Then $SleepTime = 5000
CharacterMsg($TextToSay, Random(100, @DesktopWidth-100, 1), Random(10, @DesktopHeight-150, 1), $SleepTime)
If @error Then TrayTip("You are lazy", $TextToSay, 5, 1)
$LazyLimit = Random($MinLaziness, $MaxLaziness, 1)
$TimeStamp = TimerInit()
EndIf
If $TimeDiff >= ($LazyLimit/2) Then TrayTip("", "", 0)
If $TimeDiff >= 5 And $LazyLimit > 5 Then TraySetIcon("shell32.dll", 111)
EndFunc
Func _SecsToTime($iTicks, $Delim)
If Number($iTicks) >= 0 Then
$iHours = Int($iTicks / 3600)
$iTicks = Mod($iTicks, 3600)
$iMins = Int($iTicks / 60)
$iSecs = Round(Mod($iTicks, 60))
If StringLen($iHours) = 1 Then $iHours = "0" & $iHours
If StringLen($iMins) = 1 Then $iMins = "0" & $iMins
If StringLen($iSecs) = 1 Then $iSecs = "0" & $iSecs
$Time = $iHours & $Delim & $iMins & $Delim & $iSecs
Return $Time
Else
SetError(1)
Return 0
EndIf
EndFunc
Func _IdleWaitCommit($idlesec, $TimeInit=0, $SleepTime=0)
Local $iSave, $LastInputInfo = DllStructCreate ("uint;dword")
DllStructSetData ($LastInputInfo, 1, DllStructGetSize ($LastInputInfo))
DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
Do
$iSave = DllStructGetData ($LastInputInfo, 2)
Sleep(100)
DllCall ("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr ($LastInputInfo))
If $SleepTime <> 0 And TimerDiff($TimeInit) >= $SleepTime Then ExitLoop
Until (DllStructGetData ($LastInputInfo, 2)-$iSave) > $idlesec
Return DllStructGetData ($LastInputInfo, 2)-$iSave
EndFunc
Func CharacterMsg($TextToSay, $MovexX=200, $MoveY=200, $Sleep=5000)
If $TextToSay = "" Then $TextToSay = "Oops! there was an Error!"
$FiguresArr = _FiguresListToArray()
If Not IsArray($FiguresArr) Then Return SetError(1)
$RandomFigure = Random(1, $FiguresArr[0], 1)
$FigurePath = $FiguresArr[$RandomFigure]
$FigureName = StringTrimRight(StringRegExpReplace($FigurePath, '^.*\\', ''), 4)
If Not FileExists($FigurePath) Then Return SetError(2)
$AgentControl = ObjCreate("Agent.Control.1")
$SinkObject = ObjEvent($AgentControl, "event_")
If Not Isobj($AgentControl) Then Return SetError(3)
$AgentControl.Connected = True
$AgentControl.Characters.Load($FigureName, $FigurePath)
$hCharacter = $AgentControl.Characters($FigureName)
With $hCharacter
.MoveTo($MovexX, $MoveY, 0)
.Show
.Speak($TextToSay)
.Play("Greet")
.Play("RestPose")
$SleepInit = TimerInit()
While TimerDiff($SleepInit) < $Sleep
If _IdleWaitCommit(0, $SleepInit, $Sleep) <> 0 Then ExitLoop
WEnd
.Hide
.StopAll
EndWith
$AgentControl.Characters.Unload($FigureName)
EndFunc
Func _FiguresListToArray()
$FiguresPath1 = @WindowsDir & "\MSAGENT\CHARS\"
$FiguresPath2 = @WindowsDir & "\srchasst\chars\"
If Not FileExists($FiguresPath1) And Not FileExists($FiguresPath2) Then Return SetError(1)
Local $FiguresArr[1]
;If FileExists($FiguresPath1 & "*.acs") Then
Local $FigureFind1 = FileFindFirstFile($FiguresPath1 & "*.acs")
If $FigureFind1 <> -1 Then
While 1
$CurrentFigure = FileFindNextFile($FigureFind1)
If @error Then ExitLoop
ReDim $FiguresArr[UBound($FiguresArr)+1]
$FiguresArr[0] += 1
$FiguresArr[UBound($FiguresArr)-1] = $FiguresPath1 & $CurrentFigure
WEnd
EndIf
FileClose($FigureFind1)
;EndIf
;If FileExists($FiguresPath2 & "*.acs") Then
Local $FigureFind2 = FileFindFirstFile($FiguresPath2 & "*.acs")
If $FigureFind2 <> -1 Then
While 1
$CurrentFigure = FileFindNextFile($FigureFind2)
If @error Then ExitLoop
ReDim $FiguresArr[UBound($FiguresArr)+1]
$FiguresArr[0] += 1
$FiguresArr[UBound($FiguresArr)-1] = $FiguresPath2 & $CurrentFigure
WEnd
EndIf
FileClose($FigureFind2)
;EndIf
Return $FiguresArr
EndFunc
Func Quit()
Exit
EndFunc
Напомню, что в данном примере (где $MinLaziness = 10, а $MaxLaziness = 60), нужно ничего не делать как минимум от 10-ти до 60-ти секунд чтобы увидеть результат этого скрипта ;) .
Sanja Alone
14-03-2007, 16:47
Creat0R
Можно занести эти действия в массив, и перебирать его по RandomЭто не прикольно, гораздо практичнее получать список действий персонажа программно. Вот в чем вопрос... "желательно средствами AutoIt'а выявить список действии для указанного персонажа" :)
А что, при использовании Switch учитывается регистр букв?Только что проверил - не учитывается. Можно StringLower убрать.
Я написал функцию которая собирает в массив пути к этим персонажамУ меня так тоже сделано, причем с учетом персонажей в директориях Офиса, но это уже явный перебор :)
Как можно, и можно ли вообще, регулировать скорость произношения речи?[HKEY_CURRENT_USER\Software\Microsoft\Speech\Voices]
;низкая
"DefaultTTSRate"=dword:FFFFFFF6
;средняя
"DefaultTTSRate"=dword:00000000
;высокая
"DefaultTTSRate"=dword:0000000aНу, и промежуточные значения есть, ес-но. Посмотри regshot-ом.
Sancho111
14-03-2007, 17:29
привет, в общем такая проблемка, нужно чтобы в этом скрипте перед Send ( 'Иванов' )
раскладка менялась на русскую
а перед Send ( 'Ivanov@f57.nalog.ru' ) на англискую
заранее спасибо
; Автоматическое заполнение квитанции
; ========================================
Run ( 'fap2006.exe' )
WinWaitActive ( 'Редактор актов приёма ПО' )
WinWaitActive ( 'Открыть' )
WinWaitActive ( 'Редактор актов приёма ПО', 'Акт приёма' )
Send ( '{Tab}' )
Send ( '9977' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( 'Иванов' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( 'Александр' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( 'Сергеевич' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( '913-08-24' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( 'Ivanov@f57.nalog.ru' )
AutoItSetOption ( "SendKeyDelay", 20 )
Exit
Sanja Alone
14-03-2007, 19:01
Sancho111
FAQ (http://oszone.net/display.php?id=3663) -> Как с помощью AutoIt сменить раскладку клавиатуры -> WinAPI-метод
Sanja Alone
Ты не поверишь, но я на офф. сайте нашел библиотеку для управления персонажами MSAgent (http://www.autoitscript.com/forum/index.php?showtopic=35102&hl=msagent)!
Там есть функция которая возвращает массив всех действии для заданного персонажа, и даже больше, там есть функции позволяющие добавлять/удалять действия в контекстное меню персонажа (по правой кнопке мышки на нём).
В общем я в эйфории! :yahoo:
Ну, и промежуточные значения есть, ес-но. Посмотри regshot-ом.
Спасибо за направление, а что это за regshot? не слышал о нём, и как посмотреть? т.е как получить промежуточные значения? (жалко что нельзя просто цифрами задавать :( )
[hr]
А функция для получения списка действии персонажа вот (довольно проста оказалась) :
Func _MAListCharAnimations( ByRef $oCharacter )
Local $RetVal[1]
$RetVal[0] = 0
If IsObj( $oCharacter ) Then
For $AnimName in $oCharacter.AnimationNames
Redim $RetVal[ Ubound( $RetVal ) + 1 ]
$RetVal[0] = Ubound( $RetVal ) - 1
$RetVal[$RetVal[0]] = $AnimName
Next
EndIf
Return $RetVal
EndFunc
$oCharacter естественно должен передаваться как объект загрузки персонажа.
Sanja Alone
15-03-2007, 11:25
Creat0R
что это за regshot?RegShot (редакция ParaGlider-а) (http://www.paraglidernc.com/plugins/RegShot.cab)
жалко что нельзя просто цифрами задаватьМожно. Представь себе координатную ось с 21 координатой (10 отрицательных, ноль и 10 положительных):
FFFFFFF6 - минимальное значение
FFFFFFF7
...
FFFFFFFF
00000000 - 0 (начало координат)
00000001
...
00000009
0000000a - максимальное значение
Sancho111
15-03-2007, 14:40
; Автоматическое заполнение квитанции
; ========================================
;клавиши (разрешенные клавиши: 1,2,3,4,5,6,7,8,9,0,~,Ё - знак ударения)
$vrtkey='1,2'
;модификаторы клавиш (разрешены: '05' - Ctrl;)
$keymod='05,05'
;коды языков (можете посмотреть в разделе "Appendix" руководства по AutoIt или в вышеприведенном примере)
$lang='0409,0419'
;включаем возможность раздельного переключения языков (англ. - Ctrl+Shift+1; рус. - Ctrl+Shift+2;)
_EnableLangSwitching($vrtkey,$keymod,$lang)
Run ( 'fap2006.exe' )
WinWaitActive ( 'Редактор актов приёма ПО' )
WinWaitActive ( 'Открыть' )
WinWaitActive ( 'Редактор актов приёма ПО', 'Акт приёма' )
Sleep(500)
;переключение на рус.
Send('^+2')
Send ( '{Tab}' )
Send ( '9977' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( 'Иванов' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( 'Александр' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( 'Сергеевич' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
Send ( '913-08-24' )
AutoItSetOption ( "SendKeyDelay", 20 )
Send ( '{Tab}' )
;переключение на англ.
Send('^+1')
Send ( 'Ivanov@f58.nalog.ru' )
AutoItSetOption ( "SendKeyDelay", 20 )
;отключение возможности раздельного переключения языков (удаление из реестра внесенных туда веток)
;в кач-ве аргумента укажите к-во языков, заданное выше в переменной $lang (для данного примера. - 3)
_DisableLangSwitching(3)
Func _EnableLangSwitching($key,$mod,$lng)
$constpart="HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\000001"
$akey=StringSplit($key,',',1)
$amod=StringSplit($mod,',',1)
$alng=StringSplit($lng,',',1)
If UBound($akey,1)=UBound($amod,1) and UBound($akey,1)=UBound($alng,1) Then
For $i=1 To UBound($alng,1)-1
RunWait('REG ADD "' & $constpart & StringFormat('%02s"',$i-1) & ' /v "Virtual Key" /t REG_BINARY /d ' & Hex(Asc($akey[$i]),2) & '000000 /f','',@SW_HIDE)
RunWait('REG ADD "' & $constpart & StringFormat('%02s"',$i-1) & ' /v "Key Modifiers" /t REG_BINARY /d ' & $amod[$i] & 'c00000 /f','',@SW_HIDE)
RunWait('REG ADD "' & $constpart & StringFormat('%02s"',$i-1) & ' /v "Target IME" /t REG_BINARY /d ' & StringRight($alng[$i],2)&StringLeft($alng[$i],2)&StringRight($alng[$i],2)&StringLeft($alng[$i],2) & ' /f','',@SW_HIDE)
Next
SetError(0)
Return(1)
Else
SetError(1)
Return(0)
EndIf
EndFunc
Func _DisableLangSwitching($count)
$constpart="HKEY_CURRENT_USER\Control Panel\Input Method\Hot Keys\000001"
For $i=0 To $count-1
RunWait('REG DELETE "' & $constpart & StringFormat('%02s"',$i) & ' /f','',@SW_HIDE)
Next
EndFunc
Exit
выдает ошибку
$akey=StringSplit($key,',',1)
$akey=^ERROR
Error: Incorect number of parametrs in function call
Sanja Alone
15-03-2007, 23:15
Sancho111
Я же говорил о методе "WinAPI"
Run ( 'fap2006.exe' )
AutoItSetOption ( "SendKeyDelay", 20 )
WinWaitActive ( 'Редактор актов приёма ПО' )
WinWaitActive ( 'Открыть' )
WinWaitActive ( 'Редактор актов приёма ПО', 'Акт приёма' )
$hWnd = WinGetHandle ( 'Редактор актов приёма ПО', 'Акт приёма' )
Send ( '{Tab}' )
Send ( '9977' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
Send ( '{Tab}' )
_SetKeyboardLayout("00000419", $hWnd)
Send ( 'Иванов' )
Send ( '{Tab}' )
Send ( 'Александр' )
Send ( '{Tab}' )
Send ( 'Сергеевич' )
Send ( '{Tab}' )
Send ( '913-08-24' )
Send ( '{Tab}' )
_SetKeyboardLayout("00000409", $hWnd)
Send ( 'Ivanov@f57.nalog.ru' )
Func _SetKeyboardLayout($sLayoutID, $hWnd)
Local $WM_INPUTLANGCHANGEREQUEST = 0x50
Local $ret = DllCall("user32.dll", "long", "LoadKeyboardLayout", "str", $sLayoutID, "int", 0)
DllCall("user32.dll", "ptr", "SendMessage", "hwnd", $hWnd, "int", $WM_INPUTLANGCHANGEREQUEST, "int", 1, "int", $ret[0])
EndFunc
Sancho111
16-03-2007, 10:05
Спасибо за код, но возникла следущая ошибочка
Local $ret = DllCall("user32.dll", "long", "LoadKeyboardLayout", "str", $sLayoutID, "int", 0)
Local $ret =^ERROR
Error Uknown Function name
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.