Что нового

отлов событий из дочернего окна

running-frag

why me?
Сообщения
441
Репутация
60
В общем всё пашет, но как всегда есть но. Что то меня не радует реализация главного цикла, а именно начиная с
Код:
Case $hAction[1] = $hGUI_settings
			Select
				Case WinGetTitle ($hGUI_settings) == "some2"


Идея такая, я хочу что бы обьявляя переменные (под типом Global в _GUI_SettingsWindowCreate ()) у меня не кричало в главном цикле на те переменные которы не обьявлены. Как лучше это реализовать? Так же подправьте кто увидел косяки.

Код:
#cs ----------------------------------------------------------------------------
	AutoIt Version: 3.3.6.1
	script.GUI
#ce ----------------------------------------------------------------------------

#include <WindowsConstants.au3>			; $WS_POPUPWINDOW | $WS_EX_TOOLWINDOW
#include <GUIConstantsEx.au3>			; $GUI_EVENT_CLOSE
#include <StaticConstants.au3>			; $SS_CENTER | $SS_CENTERIMAGE
#include <Array.au3>

Global $hAction
Global $hGUI = GUICreate ("jaguar", 		50, 	75, 	10, 	10, 	$WS_POPUPWINDOW, 	$WS_EX_TOOLWINDOW)
Global $hGUI_settings

Local $hMainMenu = 	GUICtrlCreateLabel	("Main", 4, 5, 40, 15, BitOR ($SS_CENTER, $SS_CENTERIMAGE), $GUI_WS_EX_PARENTDRAG)
					GUICtrlSetBkColor	(-1, 0xffffff)

Local $hM1Menu = 	GUICtrlCreateButton	("m1", 4, 30, 40, 15)
Local $hM2Menu = 	GUICtrlCreateButton	("m2", 4, 55, 40, 15)
					GUISetState (@SW_SHOW, $hGui)



Func _GUI_SettingsWindowCreate ($_winName)
	$hGUI_settings = GUICreate ($_winName, 	100, 	100, 	60, 	0, 	$WS_POPUPWINDOW, BitOR ($WS_EX_TOOLWINDOW, $WS_EX_MDICHILD), $hGUI)
	
	Select
		Case $_winName == "some1"
			GUICtrlCreateLabel ("text", 10, 10, 30, 10)
			Global $hGUI_settingsApply = GUICtrlCreateButton ("edit char", 10,30,50,30)
			
		Case $_winName == "some2"
			GUICtrlCreateLabel ("some2", 10, 10, 30, 10)
			
			Global $hGUI_settingsApply = GUICtrlCreateButton ("apply", 10,30,50,30)
		EndSelect
		
	GUISetState (@SW_SHOW, $hGUI_settings)
	
EndFunc

Func _GUI_SettingsWindowClear ()
	If $hGUI_settings Then
		GUIDelete ($hGUI_settings)
	Else
		ConsoleWrite ("gui is False"&@CR)
	EndIf
	
EndFunc

While True
	$hAction = GUIGetMsg (1)
	
	If Not $hAction[0] Then ContinueLoop
	
	Select
		Case $hAction[1] = $hGUI And $hAction[0] = $GUI_EVENT_CLOSE
			ExitLoop
					
		Case $hAction[1] = $hGUI And $hAction[0] = $hM1Menu
			_GUI_SettingsWindowClear ()
			_GUI_SettingsWindowCreate ("some1")
				
		Case $hAction[1] = $hGUI And $hAction[0] = $hM2Menu
			_GUI_SettingsWindowClear ()
			_GUI_SettingsWindowCreate ("some2")
			
		Case $hAction[1] = $hGUI_settings
			Select
				Case WinGetTitle ($hGUI_settings) == "some2"
					If $hAction[0] = $hGUI_settingsApply Then MsgBox (0,0, "some text")
				Case WinGetTitle ($hGUI_settings) == "some1"
					If $hAction[0] = $hGUI_settingsApply Then MsgBox (0,0, "editing character")
				EndSelect
		
		EndSelect
	
WEnd


Можно ли это как то реализовать более красиво, (ну хотя бы без WinGetTitle()), т.е. может какое то самоопределение какое окно сейчас используется .... В общем буду рад любым подсказкам на счёт кода выше.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Код:
#cs ----------------------------------------------------------------------------
	AutoIt Version: 3.3.6.1
	script.GUI
#ce ----------------------------------------------------------------------------

#include <WindowsConstants.au3>         ; $WS_POPUPWINDOW | $WS_EX_TOOLWINDOW
#include <GUIConstantsEx.au3>           ; $GUI_EVENT_CLOSE
#include <StaticConstants.au3>          ; $SS_CENTER | $SS_CENTERIMAGE

Global $hAction
Global $hGUI = GUICreate("jaguar", 50, 75, 10, 10, $WS_POPUPWINDOW, $WS_EX_TOOLWINDOW)
Global $hGUI_settings, $hGUI_settingsApply=1, $TrWin=0

Local $hMainMenu = GUICtrlCreateLabel("Main", 4, 5, 40, 15, BitOR($SS_CENTER, $SS_CENTERIMAGE), $GUI_WS_EX_PARENTDRAG)
GUICtrlSetBkColor(-1, 0xffffff)

Local $hM1Menu = GUICtrlCreateButton("m1", 4, 30, 40, 15)
Local $hM2Menu = GUICtrlCreateButton("m2", 4, 55, 40, 15)
GUISetState()

Func _GUI_SettingsWindowCreate()
	$hGUI_settings = GUICreate('', 100, 100, 60, 0, $WS_POPUPWINDOW, BitOR($WS_EX_TOOLWINDOW, $WS_EX_MDICHILD), $hGUI)

	Switch $TrWin
		Case 0
			GUICtrlCreateLabel("text", 10, 10, 30, 10)
			$hGUI_settingsApply = GUICtrlCreateButton("edit char", 10, 30, 50, 30)
			WinSetTitle($hGUI_settings, '', 'some1')

		Case 1
			GUICtrlCreateLabel("some2", 10, 10, 30, 10)

			$hGUI_settingsApply = GUICtrlCreateButton("apply", 10, 30, 50, 30)
			WinSetTitle($hGUI_settings, '', 'some2')
	EndSwitch

	GUISetState(@SW_SHOW, $hGUI_settings)

EndFunc

Func _GUI_SettingsWindowClear()
	If $hGUI_settings Then
		GUIDelete($hGUI_settings)
	Else
		ConsoleWrite("gui is False" & @CR)
	EndIf

EndFunc

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE ; и где он будет работать при отключении системного меню и заголовка
			ExitLoop

		Case $hM1Menu
			_GUI_SettingsWindowClear()
			$TrWin=0
			_GUI_SettingsWindowCreate()

		Case $hM2Menu
			_GUI_SettingsWindowClear()
			$TrWin=1
			_GUI_SettingsWindowCreate()

		Case $hGUI_settingsApply
			Switch $TrWin
				Case 0
					MsgBox(0, 0, "some text")
				Case 1
					MsgBox(0, 0, "editing character")
			EndSwitch
	EndSwitch
WEnd
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
не подходит, а если в каком то "окне" у нас не обьявляется кнопка $hGUI_settingsApply ? мы сходу получим крэш и ссылку на неё с var not definied
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
running-frag
а если в каком то "окне" у нас не обьявляется кнопка $hGUI_settingsApply
Надо более точную формулировку, почему она не определяется/не декларируется? Любая переменная созданная в функции без объявления - локальная и конечно будет выдавать error. Поэтому её надо объявить глобально ("если" зачернуть). Глобальные переменные объявляются не внутри функции, а в начале скрипта, если их будет сотня, думаю скрипт выдержит, у него нет ограничений на количество переменных, специально узнавал это для функции _ArrayUnique с использованием уникальной переменной в одном экземпляре при генерации сотни тысяч переменных.
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
running-frag [?]
Идея такая, я хочу что бы обьявляя переменные (под типом Global в _GUI_SettingsWindowCreate ()) у меня не кричало в главном цикле на те переменные которы не обьявлены. Как лучше это реализовать? Так же подправьте кто увидел косяки.



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

AZJIO [?]
Любая переменная созданная в функции без объявления - локальная и конечно будет выдавать error.
Обрати внимание где у меня обьявляетя $hGUI_settingsApply.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
running-frag
Идея такая, я хочу что бы обьявляя переменные (под типом Global в _GUI_SettingsWindowCreate ()) у меня не кричало в главном цикле на те переменные которы не обьявлены. Как лучше это реализовать? Так же подправьте кто увидел косяки.
Переменные объявленные под типом Global надо объявлять в начале скрипта, если имена переменных будут неизвестны, то перед их использованием вызывается проверка IsDeclared и если выдаёт "не объявлена", то объявить через Assign. Другая идея - объявить массив, в котором будут хранится все идентификаторы функции, и кричать не будет. Кстати, у меня ничего не кричало, поэтому я не понимаю суть вопроса, чисто попытка.

Обрати внимание где у меня обьявляетя $hGUI_settingsApply.
Если я скрипт правил, наверно я видел, где переменная - в функции и объявлена глобально, о чём я написал выше, так что не понимаю как ещё надо обратить на неё внимания.

Если так дальше решать задачу, я пас.
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
ок для наглядности немного поменяем скрипт
в начале добавляем
Код:
Opt ('MustDeclareVars',		1)

и в _GUI_SettingsWindowCreate () меняем именя переменных (в каждом случае своя переменная, добавлена цифра в конце 1 и 2)
Код:
Select
		Case $_winName == "characters"
			GUICtrlCreateLabel ("characters", 10, 10, 30, 10)
			Global $hGUI_settingsApply1 = GUICtrlCreateButton ("edit char", 10,30,50,30)
			
		Case $_winName == "drones"
			GUICtrlCreateLabel ("drones", 10, 10, 30, 10)
			
			Global $hGUI_settingsApply2 = GUICtrlCreateButton ("apply", 10,30,50,30)
		EndSelect

соответсвенно в главном цикле у нас будет
Код:
Case $hAction[1] = $hGUI_settings
			Switch (WinGetTitle ($hGUI_settings))
				Case "characters"
					If $hAction[0] = $hGUI_settingsApply1 Then MsgBox (0,0, "some text")
				Case "drones"
					If $hAction[0] = $hGUI_settingsApply2 Then MsgBox (0,0, "editing character")
				EndSwitch
		
		EndSelect


если писать "прямым текстом" без проверок с какого окна то тогда у нас будет орать на одну из двух переменных (т.к. case не сработает - переменная не обьявится, и вот именно эту "ошибку" мы хотим избежать проверяя "из какого окна сработал эвент")

пример выше ничего нового - простейший флаг такой же как сейчас и используется, разница только в том что я через WinGetTitle "понимаю" какое это окно, а у тебя это через флаг True\False

есть ещё мысли?



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

Плюс к этом не забываем что не факт что окон не будет (дочерних) больше чем два (то я для примера мин. два написал, а если их будет 10)

Плюс описывать каждую глобалу не пойдёт потому что их может быть много, очень много, и заборы делать в начале скрипта как то не по хозяйски. :-X


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

AZJIO [?]
Если я скрипт правил, наверно я видел, где переменная - в функции и объявлена глобально, о чём я написал выше, так что не понимаю как ещё надо обратить на неё внимания.
Тогда обьясни почему с опцией MustDeclareVars функция не кричит что переменная не обьявлена? При том что мы обьявляем её один раз, глобальной и из под функцией. Не орёт - значит ошибок нет? Логично? Или я ошибаюсь? :(
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
пример выше ничего нового - простейший флаг такой же как сейчас и используется, разница только в том что я через WinGetTitle "понимаю" какое это окно, а у тебя это через флаг True\False
Не через True\False, а через 0, 1 и т.д. хоть до миллиона, если такое количество окон позволить Windows.
Есть критерий идентификации окна, какой бы он ни был он должен быть если требуется идентификация. О чём тогда спор? Избавится от него можно только избавившись от критерия идентификации. Если избавлятся нельзя, то он будет. Осталось выяснить какой. WinGetTitle не устраивает, значит я ввёл наипростейший триггер, который не требует затрат по скорости, можешь проще? Попробуй... при условии что он должен быть в любом случае из заявленного ТЗ.

Плюс к этом не забываем что не факт что окон не будет (дочерних) больше чем два (то я для примера мин. два написал, а если их будет 10)
Это решили, хоть миллион.

Плюс описывать каждую глобалу не пойдёт потому что их может быть много, очень много, и заборы делать в начале скрипта как то не по хозяйски.
Варианты сокращений я уже говорил - массив идентификаторов. Издержки на скрипт, если что-то требуется, то оно должно быть. Иначе, если не так, то получится откомпилировали пустой файл а он создаёт GUI и выполняет что-то, это не логично. Создать #include-файл с именем "имя_программы_Func.au3 и в него переместить то, что режет глаз.

Я не увидел какую то повторяемость, которую можно было бы переделать в цикл. Если переменные имеют уникальные имена, то их нужно и создавать уникально в начале скрипта. Либо если переменные создаются подчинясь какому то правилу, то это нужно автоматизировать, но указать это правило в ТЗ.

Тогда обьясни почему с опцией MustDeclareVars функция не кричит что переменная не обьявлена?
Так переменная же объявлена. MustDeclareVars кричит, когда переменная используется, но при этом не была объявлена. А в скрипте она используется уже после создания окна и конечно же уже объявлено.

Не орёт - значит ошибок нет? Логично? Или я ошибаюсь?
Не знаю, у каждого свои критерии оценки. Для меня может и нет ошибки, если программа работает нормально. А для специалистов с офсайта это, как переводит Google, дерьмокод. Залог будущих ошибок, которые заставят изменить отношение.
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
да а в автоите по другому и не получится (ну я про дерьмо код) или чем мы тут в топике занимаемся? как по мне сглаживаем "дерьмо код" на что то читабельное


тут он "вписан в компилятор" уж больно всё уродливо выглядит, да и пишется так же. но опять же, никто не говорил что проще\сложнее, но выглядит это всё дело уродливо это 101% (личное имхо)


закрываем тему, буду уходить от дочерних окон, по старинке на одном GUI "порисуем"
 
Верх