Что нового

GUI и функция с бесконечным циклом

Статус
Закрыто для дальнейших ответов.

FazZzuR

Новичок
Сообщения
24
Репутация
1
В общем. Есть игра. Lineage 2. Делаю программу для удобного управления и запуска нескольких окон.
Для удобства хотел окно игры со стандартного менять на имя персонажа. Что бы в нескольких окнах было проще ориентироваться. Но проблема в том что название окна меняется с помощью _WinAPI и WinSetTitle до первого переключения окна. Выход нашел в бесконечном цикле который работает пока запущена игра и постоянно меняет title. Проблема всплыла когда начал делать GUI для всего этого. Из за того что нажатие на кнопку вызывает функцию в которой есть бесконечный цикл, гуй перестает реагировать на какие либо нажатия. И начинает работать только после того как я закрою игру. А мне надо бы что бы и цикл бесконечный был для каждого запущеного окна отдельный и что бы гуи продолжал работать.
С autoit знаком всего пару дней как. Пока склоняюсь к тому что бы autologin.au3 скомпилировать в exe и при нажатии на кнопку запускать этот скомпилированный скрипт передавая ему парметрами логин, пароль и имя окна.
Выглядит как костыль и хотел по интересоваться у опытных людей, какие еще есть варианты решения такой задачи.
Основное окно
Код:
#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <autologin.au3>

Local $hGUI = GUICreate("L2Windows", 150, 185)
Local $character1 = GUICtrlCreateButton("Nickname1", 10, 20, 130)
Local $character2 = GUICtrlCreateButton("Nickname2", 10, 50, 130)
Local $character3 = GUICtrlCreateButton("Nickname3", 10, 80, 130)
Local $character4 = GUICtrlCreateButton("Nickname4", 10, 110, 130)
Local $character5 = GUICtrlCreateButton("Nickname5", 10, 140, 130)
GUISetState(@SW_SHOW, $hGUI)

Local $iMsg = 0
While 1
    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $character1
            Login("login1", "pass1", "Nickname1")
	    Case $character2
            Login("login2", "pass2", "Nickname2")
	    Case $character3
            Login("login3", "pass3", "Nickname3")
	    Case $character4
            Login("login4", "pass4", "Nickname4")
	    Case $character5
            Login("login5", "pass5", "Nickname5")
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

GUIDelete($hGUI)


autologin.au3
Код:
Func Login($login, $pass, $name)
   Run("C:\Games\Lineage 2\system\l2.exe")
   WinWaitActive("Lineage 2")
   Sleep(2000)
   Send($login)
   Send("{TAB}")
   Send($pass)
   Sleep(1000)
   Send("{ENTER}")
   Sleep(2000)
   Send("{TAB}")
   Sleep(1000)
   Send("{ENTER}")
   Sleep(500)
   Send("{ENTER}")
   Sleep(500)
   Send("{ENTER}")
   Sleep(500)
   Send("{ENTER}")

   $hWnd = WinGetHandle("Lineage 2")
   While (WinGetState($hWnd) <> 0)
	  WinSetTitle ($hWnd, "", $name)
	  Sleep(1)
   WEnd
EndFunc
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
что бы и цикл бесконечный был для каждого запущеного окна отдельный и что бы гуи продолжал работать.
Обычно стараются сделать всё в одном цикле...

Пока склоняюсь к тому что бы autologin.au3 скомпилировать в exe и при нажатии на кнопку запускать этот скомпилированный скрипт передавая ему парметрами логин, пароль и имя окна.
Я так раньше делал...

Как-нибудь так. (не проверял)
Код:
#include <Constants.au3>
#include <GUIConstantsEx.au3>
;~ #include <autologin.au3>

Global $name_glob = "", $c_type = 0
Local $hGUI = GUICreate("L2Windows", 150, 185)
Local $character1 = GUICtrlCreateButton("Nickname1", 10, 20, 130)
Local $character2 = GUICtrlCreateButton("Nickname2", 10, 50, 130)
Local $character3 = GUICtrlCreateButton("Nickname3", 10, 80, 130)
Local $character4 = GUICtrlCreateButton("Nickname4", 10, 110, 130)
Local $character5 = GUICtrlCreateButton("Nickname5", 10, 140, 130)
GUISetState(@SW_SHOW, $hGUI)

Local $iMsg = 0
While 1
	$hWnd = WinGetHandle("Lineage 2")
	If ($c_type == 1) And (WinGetState($hWnd) <> 0) Then
		WinSetTitle ($hWnd, "", $name)
	EndIf
    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $character1
            Login("login1", "pass1", "Nickname1")
        Case $character2
            Login("login2", "pass2", "Nickname2")
        Case $character3
            Login("login3", "pass3", "Nickname3")
        Case $character4
            Login("login4", "pass4", "Nickname4")
        Case $character5
            Login("login5", "pass5", "Nickname5")
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

GUIDelete($hGUI)


Func Login($login, $pass, $name)
	$c_type = 1
	$name_glob = $name
   Run("C:\Games\Lineage 2\system\l2.exe")
   WinWaitActive("Lineage 2")
   Sleep(2000)
   Send($login)
   Send("{TAB}")
   Send($pass)
   Sleep(1000)
   Send("{ENTER}")
   Sleep(2000)
   Send("{TAB}")
   Sleep(1000)
   Send("{ENTER}")
   Sleep(500)
   Send("{ENTER}")
   Sleep(500)
   Send("{ENTER}")
   Sleep(500)
   Send("{ENTER}")
EndFunc
 
Автор
F

FazZzuR

Новичок
Сообщения
24
Репутация
1
alex33, не работает абсолютно. Титл окна не меняется, данные в форму не в вводит и что самое главное - после закрытия окна игры, меню все так же не работает. В моем варианте функционала малость больше было ;D
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
FazZzuR
Можно из функции возвращать дескриптор запущенного окна и в главном цикле изменять заголовки. Примерно так (проверял на блокноте)
Код:
#include <Constants.au3>
#include <GUIConstantsEx.au3>

Global $hGUI = GUICreate("L2Windows", 150, 185)
Global $character1 = GUICtrlCreateButton("Nickname1", 10, 20, 130)
Global $character2 = GUICtrlCreateButton("Nickname2", 10, 50, 130)
Global $character3 = GUICtrlCreateButton("Nickname3", 10, 80, 130)
Global $character4 = GUICtrlCreateButton("Nickname4", 10, 110, 130)
Global $character5 = GUICtrlCreateButton("Nickname5", 10, 140, 130)
GUISetState(@SW_SHOW, $hGUI)

Global $iMsg = 0, $hWnd1 = -1, $hWnd2 = -2, $hWnd3 = -3, $hWnd4 = -4, $hWnd5 = -5
While 1
    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $character1
            $hWnd1 = Login("login1", "pass1", "Nickname1")
        Case $character2
            $hWnd2 = Login("login2", "pass2", "Nickname2")
        Case $character3
            $hWnd3 = Login("login3", "pass3", "Nickname3")
        Case $character4
            $hWnd4 = Login("login4", "pass4", "Nickname4")
        Case $character5
            $hWnd5 = Login("login5", "pass5", "Nickname5")
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
    WinSetTitle($hWnd1, "", "Nickname1")
    WinSetTitle($hWnd2, "", "Nickname2")
    WinSetTitle($hWnd3, "", "Nickname3")
    WinSetTitle($hWnd4, "", "Nickname4")
    WinSetTitle($hWnd5, "", "Nickname5")
WEnd

GUIDelete($hGUI)

Func Login($login, $pass, $name)
   Run("C:\Games\Lineage 2\system\l2.exe")
   Local $hWnd = WinWaitActive("Lineage 2")
   Sleep(2000)
   Send($login)
   Send("{TAB}")
   Send($pass)
   Sleep(1000)
   Send("{ENTER}")
   Sleep(2000)
   Send("{TAB}")
   Sleep(1000)
   Send("{ENTER}")
   Sleep(500)
   Send("{ENTER}")
   Sleep(500)
   Send("{ENTER}")
   Sleep(500)
   Send("{ENTER}")
   Return $hWnd
EndFunc
 
A

Alofa

Гость
Ну как-то так:
Код:
#include <GUIConstantsEx.au3>

Global $aiElement[5][5] = [['login1', 'pass1', 'Nickname1', '', ''], _
						['login2', 'pass2', 'Nickname2', '', ''], _
						['login3', 'pass3', 'Nickname3', '', ''], _
						['login4', 'pass4', 'Nickname4', '', ''], _
						['login5', 'pass5', 'Nickname5', '', '']]

$hGUI = GUICreate('L2Windows', 150, 185)
$iC = 20
For $i = 0 To 4
	$aiElement[$i][3] = GUICtrlCreateButton($aiElement[$i][2] & ' [Отключен]', 10, $iC, 130)
	$iC += 30
Next
GUISetState()

While 1
	$iMsg = GUIGetMsg()
	Switch $iMsg
		Case $aiElement[0][3] To $aiElement[4][3]
			$iNum = $iMsg - 3
			Login($aiElement[$iNum][0], $aiElement[$iNum][1], $aiElement[$iNum][2], $iNum)
		Case $GUI_EVENT_CLOSE
			ExitLoop
	EndSwitch
	
	For $i = 0 To 4
		If $aiElement[$i][4] Then
			If WinGetState($aiElement[$i][4]) Then
				If WinGetTitle($aiElement[$i][4]) <> $aiElement[$i][2] Then WinSetTitle($aiElement[$i][4], '', $aiElement[$i][2])
			Else
				$aiElement[$i][4] = ''
				GUICtrlSetData($aiElement[$i][3], $aiElement[$i][2] & ' [Отключен]')
				GUICtrlSetState($aiElement[$i][3], $GUI_ENABLE)
			EndIf
		EndIf
	Next
WEnd

GUIDelete($hGUI)

Func Login($login, $pass, $name, $iN)
	Run('C:\Games\Lineage 2\system\l2.exe')
	$hWnd = WinWaitActive('Lineage 2', '', 4)
    If Not $hWnd Then
        MsgBox(4096, 'Сообщение', 'Нужное окно не найдено' & @LF & 'Вы задали НЕправильный критерий поиска!')
        Return
    EndIf

	SendKeepActive($hWnd)
	Sleep(2000) ;		|
	Send($login) ;		|
	Send('{TAB}') ;		|
	Send($pass) ;		|
	Sleep(1000) ;		|
	Send('{ENTER}') ;	|
	Sleep(2000) ;		|
	Send('{TAB}') ;		| => Учтите, что здесь скрипт в течении 7,5 секунд не будет откликаться
	Sleep(1000) ;		|
	Send('{ENTER}') ;	|
	Sleep(500) ;		|
	Send('{ENTER}') ;	|
	Sleep(500) ;		|
	Send('{ENTER}') ;	|
	Sleep(500) ;		|
	Send('{ENTER}') ;	|
	SendKeepActive('')

	WinSetTitle($hWnd, '', $name)
	GUICtrlSetData($iN + 3, $name & ' <Работает>')
	GUICtrlSetState($iN + 3, $GUI_DISABLE)
	$aiElement[$iN][4] = $hWnd
EndFunc   ;==>Login
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Предупреждение За нарушение правил форума (пункт Б.5):
Имя темы должно нести смысловую нагрузку (отражать суть вопроса/проблемы)
Правильно сформулированное название темы привлекает больше внимания, и шансы получить конкретный ответ увеличиваются.


Данные правила могут пополняться локальными правилами раздела.
Как правильно называть темы

"GUI и функция с бесконечным циклом" - это неприемлемое название темы, переименуйте тему иначе она будет закрыта, а вам возможно будет выдан бан на несколько дней.

С уважением, ваш Модератор.
 
Автор
F

FazZzuR

Новичок
Сообщения
24
Репутация
1
InnI, Благодарю. Звучит очень разумно. Раз ж в гуи крутится вечный цикл, можно в него запихнуть функционал постоянного изменения названия окна.
Правда я весь день размышляя пришел к выводу что возможно запуск отдельного exe для каждого окна не такая уж плохая идея. Гуи будет просто центром управления и за каждым окном будет закреплен независимый процесс бота. Я тут вспомнил что именно так и работает Honorbuddy, бот для WoW. Да и многие другие боты которые я пробовал работали по принципу - 1 окно - 1 копия бота.
Но еще раз спасибо, единственный реально дельный совет в этой теме.

Alofa,
Во первых не работает вообще. Ничего не вводит. Во вторых Гуи остается висеть и не откликаться даже после закрытия процесса игры.
Но человек выше уже подсказал мне что можно просто перекинуть код из вечного цикла в функции, в вечный цикл GUI.

Belfigor, Ну у меня проблема с тем что в моей программе нужен вечный цикл и проблема с тем что GUI перестает реагировать из-за работы функции с вечным циклом. Правила я читал и был уверен что название темы более чем отражает суть моей проблемы. Ваше сообщение если честно заставило меня удивиться. Как по вашему надо было назвать тему?


Добавлено:
Сообщение автоматически объединено:

Новый вопрос возник. Спрошу тут что бы темы не плодить. Решил я что бот будет из двух модулей. Менеджер и сам бот. Менеджер содержит всякие кнопки для запуска которые передают боту название функции которое требуется вызвать и параметры. Для каждого окна запускается своя версия бота, который работает до момента закрытия окна за которым он был закреплен. Проблема в том что если использовать Run() Каждый раз для вызова какой либо функции - будет плодиться новый процесс. Как можно сделать не запуск нового процесса, а вызов функций из уже запущенного?
 
A

Alofa

Гость
OffTopic:

FazZzuR сказал(а):
... Правила я читал ...
Ну тогда вы должны были видеть там следующее:
сказал(а):
13. Не следует писать в тему, где были выданы предупреждения автору темы, особенно если это критические предупреждения (пункты Б.5, В.4, и другие пункты, которые требуют немедленного исправления).
Подумайте, если абстрагироваться от всяких циклов и скриптов, какую задачу вы хотите решить?

Но пока все есть, как есть, то я вам не помогу в решении этого:
FazZzuR сказал(а):
... Ничего не вводит. Во вторых Гуи остается висеть и не откликаться даже после закрытия процесса игры.
 
Автор
F

FazZzuR

Новичок
Сообщения
24
Репутация
1
Lineage 2. Смена названия окна

Alofa сказал(а):
Ну тогда вы должны были видеть там следующее:
сказал(а):
13. Не следует писать в тему, где были выданы предупреждения автору темы, особенно если это критические предупреждения (пункты Б.5, В.4, и другие пункты, которые требуют немедленного исправления).
Подумайте, если абстрагироваться от всяких циклов и скриптов, какую задачу вы хотите решить?
Задача в целом - автоматизация всякой рутины в игре ла2. Но тему то я создал только ради одного вопроса - ГУИ который не откликается. Название темы должно отражать суть проблемы, что бы было ясно о чем будет в ней, этого то я и попытался добиться. Поскольку название типо - Lineage 2. Смена названия окна - противоречит правилу в котором говориться о том что из темы должна быть понятна суть проблемы. Уверен что большинство зашло в тему что бы рассказать мне про WinSetTitle с таким названием.
Заголовок темы необходимо составить так, чтобы он как можно точнее отражал суть темы.
Но пока все есть, как есть, то я вам не помогу в решении этого:
Спасибо за внимание, но я уже выше написал что человек мне помог идей. Код мне не нужен, его я сам напишу.
Но раз уж так название не угодило, сменю на то которое говорит о решаемой задаче, но абсолютно не содержит информации о проблеме.
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
FazZzuR
Правила я читал и был уверен что название темы более чем отражает суть моей проблемы.
Эти правила для раздела с общими вопросами. А глобальный модератор, увидев в тексте название игры, перенёс тему в раздел ботов. Здесь уже локальный модератор придумал свои правила: http://autoit-script.ru/index.php?topic=6125.0, согласно которым в названии темы нужно указать в квадратных скобках (это важно!) название игры и что вы дальше напишите никого уже не волнует.

Спрошу тут что бы темы не плодить.
А за это вы получите предупреждение о наличии нескольких вопросов в одной теме. Поэтому ответ на вопрос оформляю, как offtop.

OffTopic:
вызов функций из уже запущенного
Ответ #26


Как по вашему надо было назвать тему?
И не спорьте с модераторами - получите бан.
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
OffTopic:
Alofa
[box]Данные правила являются общими для всего форума и обязательны для выполнения, как участниками, так и администрацией форума. Если в разделе установлены внутренние правила, то они дополняют данные правила форума.[/box] Я имел в виду, что в разделе по общим вопросам нет внутренних правил.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
FazZzuR [?]
Новый вопрос возник. Спрошу тут что бы темы не плодить.

Предупреждение За нарушение общих правил (пункт В.4):
Не лепите несколько вопросов разной тематики в один пост. По типу "Ребят, а ещё такой вопрос...". Каждый вопрос в свою тему.


С уважением, ваш Глобальный модератор.
 

vovsla

Осваивающий
Сообщения
607
Репутация
36
Давно хотел отписаться, но все время забывал...
Лет 10 назад написал скрипт для автоматического ввода логина и пароля для L2 С4. Не знаю будет ли работать сейчас.
Для указания данных для логина необходимо создать файл !AutoPassword.ini
В файле указываем
Код:
[Имя персонажа]
Login=логин
Password=пароль


Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <GUIListBox.au3>
#include <WindowsConstants.au3>
#Include <Array.au3>

Opt("GUIOnEventMode", 1)
Opt("WinTitleMatchMode", 3)

If WinExists('AutoLogin') Then
MsgBox(64, 'AutoLogin', 'Программа уже запущена')
Exit
EndIf


$Form1 = GUICreate("AutoLogin", 181, 177, @DesktopWidth-190, @DesktopHeight-250)
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close")
$List1 = GUICtrlCreateList("", 0, 0, 177, 175)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")

$Nick=IniReadSectionNames('!AutoPassword.ini')
For $NickNum=1 To $Nick[0]
GUICtrlSetData($List1, $Nick[$NickNum])
GUICtrlSetOnEvent(-1, "List1Click")
Next



While 1
Sleep(100)
WEnd



Func List1Click()


EndFunc



Func List_DoubleClick()
    $NickName=GUICtrlRead($List1)
	$Login=IniRead('!AutoPassword.ini', $NickName, 'Login', '')
	$Pass=IniRead('!AutoPassword.ini', $NickName, 'Password', '')

	If $Login='' Or $Pass='' Then
		MsgBox(16, 'AutoLogin', 'Остутсвует логин или пароль')
		Return 0
	ElseIf Not FileExists('System\l2.exe') Then
		MsgBox(16, 'AutoLogin', 'Не найден файл "System\l2.exe"')
		Return 0
	Else
		$WinArr1=WinList("Lineage II")
		Run('System\l2.exe')
	EndIf

ToolTip($NickName, @DesktopWidth/2-StringLen($NickName), @DesktopHeight/2-20, 'Запуск Lineage II', 1, 2)


WinWaitActive("Lineage II")
ToolTip('')
Sleep(1000)
;~ WinMove("Lineage II", "", 30, 60)



Do
$WinArr2=WinList("Lineage II")
Until $WinArr2[0][0]>$WinArr1[0][0]

If $WinArr1[0][0]>0 Then
For $Num1=1 To $WinArr2[0][0]
For $Num2=1 To $WinArr1[0][0]
If $WinArr1[$Num2][1]=$WinArr2[$Num1][1] Then ExitLoop
If $Num2=$WinArr1[0][0] Then ExitLoop 2
Next
Next
Else
$Num1=1
EndIf

$ret=DllCall("user32.dll", "long", "LoadKeyboardLayout", "str", "00000409", "int", 0)
DllCall("user32.dll", "ptr", "SendMessage", "hwnd", $WinArr2[$Num1][1], "int", "0x50", "int", 1, "int", $ret[0])

WinWaitActive($WinArr2[$Num1][1])
ControlSend($WinArr2[$Num1][1], "", "", $Login)

WinWaitActive($WinArr2[$Num1][1])
ControlSend($WinArr2[$Num1][1], "", "", "{TAB}")

WinWaitActive($WinArr2[$Num1][1])
ControlSend($WinArr2[$Num1][1], "", "", $Pass)


EndFunc



Func MY_WM_COMMAND($hWnd, $msg, $wParam, $lParam)
    Local $nNotifyCode = BitShift($wParam, 16)
    Local $nID = BitAND($wParam, 0xFFFF)
    Local $hCtrl = $lParam
    Local Const $LBN_ERRSPACE = (-2);
    Local Const $LBN_SELCHANGE = 1;
    Local Const $LBN_DBLCLK = 2;
    Local Const $LBN_SELCANCEL = 3;
    Local Const $LBN_SETFOCUS = 4;
    Local Const $LBN_KILLFOCUS = 5;

    Switch $nID
        Case $List1
            Switch $nNotifyCode
                Case $LBN_DBLCLK
                    List_DoubleClick()
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc



Func Form1Close()
Exit
EndFunc


Какие у Вас хроники?
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Тема закрыта ввиду игнорирования предупреждений
 
Статус
Закрыто для дальнейших ответов.
Верх