Что нового

Не блокировать родительское окно при вызове дочерних

gora

Знающий
Сообщения
315
Репутация
19
Имеется родительское окно с тремя кнопками для вызова дочерних окон и множеством других элементов управления.
Дочерние окна имеют только текст и кнопку Отмена.
Дочерние окна ни как не должны привязываться к родительскому (перемещаться вместе с ним, быть внутри его и т.п.).
Нужно:
1 При нажатии первой кнопки в родительском окне вызвать первое дочернее окно.
2 Не закрывая первого дочернего окна нужно иметь возможность нажатием второй кнопки вызвать второе дочернее окно.
3 Аналогично с третьим.
4 Отображение всех дочерних окон производится одной функцией, различается только передаваемый в нее текст.
5 Нажатие кнопки Отмена в любом дочернем окне должно закрывать только это дочернее окно.
6 Остальные элементы управления в родительском окне должны продолжать работать при открытых дочерних.
7 Закрытие или перезапуск родительского окна не должны закрывать дочерние окна.

Возможно ли это реализовать?
Спасибо
 

agikon

Знающий
Сообщения
789
Репутация
17
код можно в студию этих дочерних окон?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
gora,
Можно так попробовать (не оптимально).
Код:
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Global $aGUI_Child[4][2] = [[3]]

$hMainGui = GUICreate('Test', 300, 160)
$nButton = GUICtrlCreateButton('Button', 100, 20, 100, 30)
$nButton_1 = GUICtrlCreateButton('First', 15, 100, 80, 30)
$nButton_2 = GUICtrlCreateButton('Second', 110, 100, 80, 30)
$nButton_3 = GUICtrlCreateButton('Third', 205, 100, 80, 30)

GUISetState()

While 1
	$aMsg = GUIGetMsg(1)
	Switch $aMsg[1]
		Case 0
			ContinueLoop
		Case $hMainGui
			Switch $aMsg[0]
				Case $GUI_EVENT_CLOSE
					GUIDelete($hMainGui)
				Case $nButton
					MsgBox(64, 'Info', 'Button', 0, $hMainGui)
				Case $nButton_1
					_Child_GUI_Create($aGUI_Child, 1)
					GUICtrlSetState($nButton_1, $GUI_DISABLE)
				Case $nButton_2
					_Child_GUI_Create($aGUI_Child, 2)
					GUICtrlSetState($nButton_2, $GUI_DISABLE)
				Case $nButton_3
					_Child_GUI_Create($aGUI_Child, 3)
					GUICtrlSetState($nButton_3, $GUI_DISABLE)
			EndSwitch
		Case $aGUI_Child[1][0]
			Switch $aMsg[0]
				Case $GUI_EVENT_CLOSE, $aGUI_Child[1][1]
					GUIDelete($aGUI_Child[1][0])
					$aGUI_Child[1][1] = 0
					$aGUI_Child[1][0] = 0
					GUICtrlSetState($nButton_1, $GUI_ENABLE)
			EndSwitch
		Case $aGUI_Child[2][0]
			Switch $aMsg[0]
				Case $GUI_EVENT_CLOSE, $aGUI_Child[2][1]
					GUIDelete($aGUI_Child[2][0])
					$aGUI_Child[2][1] = 0
					$aGUI_Child[2][0] = 0
					GUICtrlSetState($nButton_2, $GUI_ENABLE)
			EndSwitch
		Case $aGUI_Child[3][0]
			Switch $aMsg[0]
				Case $GUI_EVENT_CLOSE, $aGUI_Child[3][1]
					GUIDelete($aGUI_Child[3][0])
					$aGUI_Child[3][1] = 0
					$aGUI_Child[3][0] = 0
					GUICtrlSetState($nButton_3, $GUI_ENABLE)
			EndSwitch
	EndSwitch
WEnd

Func _Child_GUI_Create(ByRef $a_GUI, $i_Index)
	Local $a_Text[4][2] = [[3],[100, 'Text First Window'],[350, 'Text Second Window'], _
			[600, 'Text Third Window']]
	$a_GUI[$i_Index][0] = GUICreate('Child ' & $i_Index, 200, 100, $a_Text[$i_Index][0], 50, -1, $WS_EX_TOPMOST)
	$a_GUI[$i_Index][1] = GUICtrlCreateButton('Отмена', 50, 60, 100, 30)
	GUICtrlCreateLabel($a_Text[$i_Index][1], 10, 10, 180, 40, $SS_CENTER)
	GUISetState(@SW_SHOW, $a_GUI[$i_Index][0])
EndFunc   ;==>_Child_GUI_Create
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
agikon [?]
код можно в студию этих дочерних окон?
Он большой и специфический. Я не думаю, что Вам захочется в нем разбираться.
madmasles
Спасибо, попробую разобраться.
Одно сразу настораживает, текст у меня не может располагаться в функции дочернего окна, он туда передается. Функция вызывается в скрипте многократно с большим числом разных параметров и сами параметры всегда разные
Код:
_Window($Title,$Text,$TextButton,$Icon=2,$Focus=1,$Pass=0,$pozX=-1,$pozY=-1,$timer=0)
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
gora [?]
Одно сразу настораживает, текст у меня не может располагаться в функции дочернего окна, он туда передается. Функция вызывается в скрипте многократно с большим числом разных параметров и сами параметры всегда разные
Я же не знаю специфики Ваших дочерних окон. Уберите текст из функции и передавайте его параметром, это же пример. Если параметров много, то их, ИМХО, можно в массив затолкать и передавать в функцию массив.
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
madmasles
С передачей параметров я попробую сам разобраться. Первый тест меня расстроил. При закрытии основного окна скрипт должен продолжить свою работу. В Вашем примере окно просто удаляется и скрипт продолжает висеть в цикле. Если я при этом выйду из основного цикла, для продолжения работы скрипта, то дочерние окна кнопками я уже не смогу закрыть?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
gora,
Может, как-то так?
Код:
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Array.au3>

HotKeySet('^1', '_GUI');Ctrl + 1 - окно
HotKeySet('+{Esc}', '_Exit');Shift + Esc - выход

While 1
	ToolTip(StringFormat('%s\n%02d:%02d:%02d', 'Основной цикл.', @HOUR, @MIN, @SEC), 0, 0)
	Sleep(100)
WEnd

Func _GUI()
	Local $iCountGui = 1, $aGUI_Child[1][3] = [[0]], $aButton[4][2] = [[3],['First'],['Second'],['Third']]
	ToolTip('') ;для примера :)
	;тут сами определите, какие переменные у Вас будут Local, а какие Global
	$hMainGui = GUICreate('Test', 300, 160)
	$nButton = GUICtrlCreateButton('Button', 100, 20, 100, 30)
	For $i = 1 To $aButton[0][0]
		$aButton[$i][1] = GUICtrlCreateButton($aButton[$i][0], 15 + ($i - 1) * 95, 100, 80, 30)
	Next
	GUISetState()
	While 1
		$aMsg = GUIGetMsg(1)
		Switch $aMsg[1]
			Case $hMainGui
				Switch $aMsg[0]
					Case $GUI_EVENT_CLOSE
						GUIDelete($hMainGui)
						$iCountGui -= 1
					Case $nButton
						MsgBox(64, 'Info', 'Button', 0, $hMainGui)
						_ArrayDisplay($aGUI_Child)
					Case $aButton[1][1] To $aButton[$aButton[0][0]][1]
						For $i = 1 To $aButton[0][0]
							If $aMsg[0] = $aButton[$i][1] Then
								_Child_GUI_Create($aGUI_Child, $i, $aButton[$i][1])
								$iCountGui += 1
								ExitLoop
							EndIf
						Next
				EndSwitch
			Case Else
				If Not $aGUI_Child[0][0] Then ContinueLoop
				Switch $aMsg[0]
					Case $GUI_EVENT_CLOSE, $aGUI_Child[1][1] To $aGUI_Child[$aGUI_Child[0][0]][1]
						GUIDelete($aMsg[1])
						$iCountGui -= 1
						For $i = 1 To $aGUI_Child[0][0]
							If $aMsg[1] = $aGUI_Child[$i][0] Then
								GUICtrlSetState($aGUI_Child[$i][2], $GUI_ENABLE)
								_ArrayDelete($aGUI_Child, $i)
								$aGUI_Child[0][0] -= 1
								ExitLoop
							EndIf
						Next
				EndSwitch
		EndSwitch
		If Not $iCountGui Then ExitLoop
	WEnd
EndFunc   ;==>_GUI

Func _Child_GUI_Create(ByRef $a_GUI, $i_Index, $i_ID_Button)
	Local $a_Text[4][2] = [[3],[100, 'Text First Window'],[350, 'Text Second Window'], _
			[600, 'Text Third Window']]
	$a_GUI[0][0] += 1
	ReDim $a_GUI[$a_GUI[0][0] + 1][3]
	GUICtrlSetState($i_ID_Button, $GUI_DISABLE)
	$a_GUI[$a_GUI[0][0]][2] = $i_ID_Button
	$a_GUI[$a_GUI[0][0]][0] = GUICreate('Child ' & $i_Index, 200, 100, $a_Text[$i_Index][0], 50, -1, $WS_EX_TOPMOST)
	$a_GUI[$a_GUI[0][0]][1] = GUICtrlCreateButton('Отмена', 50, 60, 100, 30)
	GUICtrlCreateLabel($a_Text[$i_Index][1], 10, 10, 180, 40, $SS_CENTER)
	GUISetState(@SW_SHOW, $a_GUI[$a_GUI[0][0]][0])
EndFunc   ;==>_Child_GUI_Create

Func _Exit()
	Exit
EndFunc   ;==>_Exit
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
madmasles
Скорее всего требуется режим GUIOnEventMode, дабы функция вызова окон не останавливала цикл.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
AZJIO [?]
Скорее всего требуется режим GUIOnEventMode
Это gora должен сам решить, какой режим использовать. Я же не знаю, что скрипт в итоге должен делать.
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
madmasles [?]
Это gora должен сам решить, какой режим использовать.
Должен, если б он еще знал КАК!? :(

Поискав по форуму написал как мне это видится.
Код:
#include <GUIConstantsEx.au3>

Global $nChildGUI_Close_Bttn1 = -1, $hChild_GUI1 = -1
Global $nChildGUI_Close_Bttn2 = -1, $hChild_GUI2 = -1
Global $nChildGUI_Close_Bttn3 = -1, $hChild_GUI3 = -1
Global $hMain_GUI

_Main()
; Вот здесь дочерние окна должны еще быть, если они были открыты, и они должны реагировать на кнопки Отмена и "событие закрытия". Как ???
MsgBox(64, 'Основной цикл', 'Выход из Родительского окна' & @LF & 'Цикл продолжается...')
Exit

Func _Main()
$hMain_GUI = GUICreate("Родительское окно", 250, 60)
$nChild_Button1 = GUICtrlCreateButton("Child1", 10, 20, 65, 25)
$nChild_Button2 = GUICtrlCreateButton("Child2", 90, 20, 65, 25)
$nChild_Button3 = GUICtrlCreateButton("Child3", 170, 20, 65, 25)
GUISetState(@SW_SHOW, $hMain_GUI)

While 1
	;Обработка событий в расширенном режиме
	$aMsg = GUIGetMsg(1)
	Switch $aMsg[0]
		Case $GUI_EVENT_CLOSE
			;Проверяем если "событие закрытия" поступило из родительского GUI, то закрываем его и выходим из функции
			If $aMsg[1] = $hMain_GUI Then ExitLoop
			;Если "событие закрытия" поступило с дочернего GUI, то закрываем его
			If $aMsg[1] = $hChild_GUI1 Then $hChild_GUI1 = _Exit1($hChild_GUI1)
			If $aMsg[1] = $hChild_GUI2 Then $hChild_GUI2 = _Exit1($hChild_GUI2)
			If $aMsg[1] = $hChild_GUI3 Then $hChild_GUI3 = _Exit1($hChild_GUI3)
		Case $nChild_Button1
			;Создаем дочерний GUI при нажатий на кнопку "Child1", если его нет
			If $hChild_GUI1 = -1 Then $hChild_GUI1 = _ChildGUI_Create('Заголовок 1', 'Текст 1', "Отмена", 1, '', '', 5, 5, '', $hMain_GUI, 1)
		Case $nChild_Button2
			;Создаем дочерний GUI при нажатий на кнопку "Child2", если его нет
			If $hChild_GUI2 = -1 Then $hChild_GUI2 = _ChildGUI_Create('Заголовок 2', 'Текст 2', "Отмена", 1, '', '', 255, 5, '', $hMain_GUI, 2)
		Case $nChild_Button3
			;Создаем дочерний GUI при нажатий на кнопку "Child3", если его нет
			If $hChild_GUI3 = -1 Then $hChild_GUI3 = _ChildGUI_Create('Заголовок 3', 'Текст 3', "Отмена", 1, '', '', 505, 5, '', $hMain_GUI, 3)
		Case $nChildGUI_Close_Bttn1
			MsgBox(64, 'Дочернее окно', "Нажата кнопка 'Отмена' в дочернем окне 1", 3)
			$hChild_GUI1 = _Exit1($hChild_GUI1)
		Case $nChildGUI_Close_Bttn2
			MsgBox(64, 'Дочернее окно', "Нажата кнопка 'Отмена' в дочернем окне 2", 3)
			$hChild_GUI2 = _Exit1($hChild_GUI2)
		Case $nChildGUI_Close_Bttn3
			MsgBox(64, 'Дочернее окно', "Нажата кнопка 'Отмена' в дочернем окне 3", 3)
			$hChild_GUI3 = _Exit1($hChild_GUI3)
	EndSwitch
WEnd
GUIDelete($hMain_GUI)
EndFunc ;==> _Main()

Func _Exit1($w1)
	GUIDelete($w1)
	Return -1
EndFunc

;Func _Window($Title,$Text,$TextButton,$Icon=2,$Focus=1,$Pass=0,$pozX=-1,$pozY=-1,$timer=0)
Func _ChildGUI_Create($Title,$Text,$TextButton,$Icon,$Focus,$Pass,$pozX,$pozY,$timer,$hParent,$N)
	Local $hChild_GUI
	;Создаём элементы тут
	$hChild_GUI = GUICreate($Title, 200, 80, $pozX, $pozY, -1, -1, $hParent)
	GUICtrlCreateLabel($Text, 50, 10)
	If $N = 1 Then $nChildGUI_Close_Bttn1 = GUICtrlCreateButton($TextButton, 65, 45, 65, 25)
	If $N = 2 Then $nChildGUI_Close_Bttn2 = GUICtrlCreateButton($TextButton, 65, 45, 65, 25)
	If $N = 3 Then $nChildGUI_Close_Bttn3 = GUICtrlCreateButton($TextButton, 65, 45, 65, 25)
	GUISetState(@SW_SHOW, $hChild_GUI)
	Return $hChild_GUI
EndFunc
Нерешенный вопрос в комментарии в скрипте.
 
Верх