Что нового

[Элементы GUI] Закрепление всплывающего окна к основному

forbrock

Новичок
Сообщения
43
Репутация
0
Покажите пожалуйста как можно прикрепить открывающееся окно, после нажатия на Button 1 к основному окну (пример как должны располагаться окна на скрине во вложении) из примера:
Код:
#include <GUIConstants.au3>

$GUI = GUICreate("", 220, 140)
$btn_1 = GUICtrlCreateButton("Button 1", 60, 15, 100, 50)
$btn_2 = GUICtrlCreateButton("Button 2", 60, 75, 100, 50)
GUISetState()

Do
   Switch GUIGetMsg()
	  Case $GUI_EVENT_CLOSE
		 Exit
	  Case $btn_1
		 $GUI2 = GUICreate("Button 1", 220, 100)
		 GUICtrlCreateLabel('Button 1 pressed',75,30)
		 $btn_3 = GUICtrlCreateButton('OK',75,50,80,30)
		 GUISetState()
		 Do
			Switch GUIGetMsg()
			   Case $btn_3
				  Exit
			EndSwitch
		 Until 0
	  Case $btn_2
		 $GUI3 = GUICreate("Button 2", 220, 100)
		 GUICtrlCreateLabel('Button 2 pressed',75,30)
		 $btn_4 = GUICtrlCreateButton('OK',75,50,80,30)
		 GUISetState()
		 Do
			Switch GUIGetMsg()
			   Case $btn_4
				  Exit
			EndSwitch
		 Until 0
   EndSwitch
Until 0

P.S. Также хотелось бы узнать как закрыть второстепенное окно и вернуться в основное.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
forbrock [?]
как можно прикрепить открывающееся окно
Код:
#include <GUIConstants.au3>
#include <WindowsConstants.au3>

Global $GUI=0, $GUI2=0, $GUI3=0

$GUI = GUICreate("", 220, 140)
$btn_1 = GUICtrlCreateButton("Button 1", 60, 15, 100, 50)
$btn_2 = GUICtrlCreateButton("Button 2", 60, 75, 100, 50)
GUISetState()

GUIRegisterMsg($WM_MOVE, "WM_MOVE")

Do
   Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
         Exit
      Case $btn_1
         $pos = WinGetPos($GUI)
         $GUI2 = GUICreate("Button 1", 220, 100, $pos[0]+$pos[2], $pos[1])
         GUICtrlCreateLabel('Button 1 pressed',75,30)
         $btn_3 = GUICtrlCreateButton('OK',75,50,80,30)
         GUISetState()
         Do
            Switch GUIGetMsg()
               Case $btn_3
                  Exit
            EndSwitch
         Until 0
      Case $btn_2
         $pos = WinGetPos($GUI)
         $GUI3 = GUICreate("Button 2", 220, 100, $pos[0]+$pos[2], $pos[1])
         GUICtrlCreateLabel('Button 2 pressed',75,30)
         $btn_4 = GUICtrlCreateButton('OK',75,50,80,30)
         GUISetState()
         Do
            Switch GUIGetMsg()
               Case $btn_4
                  Exit
            EndSwitch
         Until 0
   EndSwitch
Until 0

Func WM_MOVE()
  Local $pos = WinGetPos($GUI)
  If WinExists($GUI2) Then WinMove($GUI2, "", $pos[0]+$pos[2], $pos[1])
  If WinExists($GUI3) Then WinMove($GUI3, "", $pos[0]+$pos[2], $pos[1])
EndFunc


как закрыть второстепенное окно
Код:
GUIDelete()
WinClose()
WinKill()
 

madmasles

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

Global $hParent, $hChild, $aPos, $hBtn_1, $hBtn_2, $fChild

$hParent = GUICreate('Parent', 200, 250)
$hBtn_1 = GUICtrlCreateButton('First (Child)', 50, 50, 100, 50)
$hBtn_2 = GUICtrlCreateButton('Second', 50, 150, 100, 50)
$hChild = GUICreate('Child', 200, 100);, -1, -1, -1, -1, $hParent)
$hBtn_3 = GUICtrlCreateButton('Third', 50, 35, 100, 30)
GUISetState(@SW_SHOW, $hParent)
GUIRegisterMsg($WM_MOVE, '_WM_MOVE')

While 1
	$aMsg = GUIGetMsg(1)
	Switch $aMsg[1]
		Case $hParent
			Switch $aMsg[0]
				Case $GUI_EVENT_CLOSE
					Exit
				Case $hBtn_1
					If $fChild Then ContinueLoop
					$aPos = WinGetPos($hParent)
					WinMove($hChild, '', $aPos[0] + $aPos[2] + 10, $aPos[1])
					GUISetState(@SW_SHOW, $hChild)
					$fChild = True
				Case $hBtn_2
					MsgBox(64, 'Info', 'Second', 0, $hParent)
			EndSwitch
		Case $hChild
			Switch $aMsg[0]
				Case $GUI_EVENT_CLOSE
					GUISetState(@SW_HIDE, $hChild)
					$fChild = False
				Case $hBtn_3
					MsgBox(64, 'Info', 'Third', 0, $hChild)
			EndSwitch
	EndSwitch
WEnd

Func _WM_MOVE($hWnd, $Msg, $wParam, $lParam)
	Local $a_PosP, $a_PosC
	If $fChild Then
		Switch $hWnd
			Case $hParent
				$a_PosP = WinGetPos($hParent)
				WinMove($hChild, '', $a_PosP[0] + $a_PosP[2] + 10, $a_PosP[1])
			Case $hChild
				$a_PosC = WinGetPos($hChild)
				$a_PosP = WinGetPos($hParent)
				WinMove($hParent, '', $a_PosC[0] - $a_PosP[2] - 10, $a_PosC[1])
		EndSwitch
	EndIf
	Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_MOVE
 
Автор
F

forbrock

Новичок
Сообщения
43
Репутация
0
Спасибо! Почти разобрался...
Зачем только это:
Код:
GUIRegisterMsg()
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Попробовал пример madmasles переделать используя структуры

Код:
#include <WinAPI.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$FrmBrdW = _WinAPI_GetSystemMetrics(32) * 2
$FrmBrdH = _WinAPI_GetSystemMetrics(4) + _WinAPI_GetSystemMetrics(33) * 2

Global $hParent, $hChild, $aPos, $hBtn_1, $hBtn_2, $fChild

$hParent = GUICreate('Parent', 200, 250)
$stRET_Parent = _WinAPI_GetWindowPlacement($hParent) ; получаем структуру окна
$hBtn_1 = GUICtrlCreateButton('First (Child)', 50, 50, 100, 50)
$hBtn_2 = GUICtrlCreateButton('Second', 50, 150, 100, 50)
$hChild = GUICreate('Child', 200, 100);, -1, -1, -1, -1, $hParent)
$stRET_Child = _WinAPI_GetWindowPlacement($hChild) ; получаем структуру окна
$hBtn_3 = GUICtrlCreateButton('Third', 50, 35, 100, 30)
GUISetState(@SW_SHOW, $hParent)
GUIRegisterMsg($WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED")

While 1
    $aMsg = GUIGetMsg(1)
    Switch $aMsg[1]
        Case $hParent
            Switch $aMsg[0]
                Case $GUI_EVENT_CLOSE
                    Exit
                Case $hBtn_1
                    If $fChild Then ContinueLoop
                    $aPos = WinGetPos($hParent)
                    WinMove($hChild, '', $aPos[0] + $aPos[2], $aPos[1])
                    GUISetState(@SW_SHOW, $hChild)
                    $fChild = True
                Case $hBtn_2
                    MsgBox(64, 'Info', 'Second', 0, $hParent)
            EndSwitch
        Case $hChild
            Switch $aMsg[0]
                Case $GUI_EVENT_CLOSE
                    GUISetState(@SW_HIDE, $hChild)
                    $fChild = False
                Case $hBtn_3
                    MsgBox(64, 'Info', 'Third', 0, $hChild)
            EndSwitch
    EndSwitch
WEnd

Func WM_WINDOWPOSCHANGED($hWnd, $Msg, $wParam, $lParam)
    #forceref $Msg, $wParam
    Local $a_PosP, $a_PosC
    ; получаем координаты сторон окна
    Local $sRect = DllStructCreate("Int[6]", $lParam), _
        $ykazatel = DllStructGetData($sRect, 1, 1), _
        $chislo = DllStructGetData($sRect, 1, 2), _
        $left = DllStructGetData($sRect, 1, 3), _
        $top = DllStructGetData($sRect, 1, 4), _
        $WinSizeX = DllStructGetData($sRect, 1, 5), _
        $WinSizeY = DllStructGetData($sRect, 1, 6)

    If $fChild Then
        Switch $hWnd
            Case $hParent
				DllStructSetData($stRET_Child, "rcNormalPosition", $left + $WinSizeX, 1); левая
				DllStructSetData($stRET_Child, "rcNormalPosition", $top, 2); верхняя
				DllStructSetData($stRET_Child, "rcNormalPosition", $left + $WinSizeX + 200 + $FrmBrdW, 3); правая
				DllStructSetData($stRET_Child, "rcNormalPosition", $top + 100 + $FrmBrdH, 4); нижняя
				_WinAPI_SetWindowPlacement($hChild, DllStructGetPtr($stRET_Child))
            Case $hChild
				$stRET_Parent = _WinAPI_GetWindowPlacement($hParent)
				DllStructSetData($stRET_Parent, "rcNormalPosition", $left - 200, 1); левая
				DllStructSetData($stRET_Parent, "rcNormalPosition", $top, 2); верхняя
				DllStructSetData($stRET_Parent, "rcNormalPosition", $left, 3); правая
				DllStructSetData($stRET_Parent, "rcNormalPosition", $top + 250 + $FrmBrdH, 4); нижняя
				_WinAPI_SetWindowPlacement($hParent, DllStructGetPtr($stRET_Parent))
        EndSwitch
    EndIf

    Return $GUI_RUNDEFMSG
EndFunc
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
AZJIO [?]
используя структуры
Можно тогда так.
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Global $hParent, $hChild, $hBtn_1, $hBtn_2, $fChild, $tParent, $pParent, $tChild, $pChild, _
		$ix = _WinAPI_GetSystemMetrics($SM_CXFRAME) * 2, $iy = _WinAPI_GetSystemMetrics($SM_CYCAPTION) + $ix, _
		$ix1 = _WinAPI_GetSystemMetrics($SM_CXDLGFRAME) * 2, $iWp = 200, $iHp = 250, $iWc = 200, $iHc = 100

$hParent = GUICreate('Parent', $iWp, $iHp)
$hBtn_1 = GUICtrlCreateButton('First (Child)', 50, 50, 100, 50)
$hBtn_2 = GUICtrlCreateButton('Second', 50, 150, 100, 50)
$hChild = GUICreate('Child', $iWc, $iHc)
$hBtn_3 = GUICtrlCreateButton('Third', 50, 35, 100, 30)
GUISetState(@SW_SHOW, $hParent)
GUIRegisterMsg($WM_WINDOWPOSCHANGED, '_WM_WINDOWPOSCHANGED')

While 1
	$aMsg = GUIGetMsg(1)
	Switch $aMsg[1]
		Case $hParent
			Switch $aMsg[0]
				Case $GUI_EVENT_CLOSE
					ExitLoop
				Case $hBtn_1
					If $fChild Then ContinueLoop
					_WinAPI_GetWindowPlacementEx($hParent, $tParent, $pParent)
					_WinAPI_GetWindowPlacementEx($hChild, $tChild, $pChild)
					;'rcNormalPosition':	num 6
					DllStructSetData($tChild, 6, DllStructGetData($tParent, 6, 1) + $iWp + $ix, 1)
					DllStructSetData($tChild, 6, DllStructGetData($tParent, 6, 2), 2)
					DllStructSetData($tChild, 6, DllStructGetData($tParent, 6, 1) + $iWp + $iWc + $ix + $ix1, 3)
					DllStructSetData($tChild, 6, DllStructGetData($tParent, 6, 2) + $iHc + $iy, 4)
					_WinAPI_SetWindowPlacement($hChild, $pChild)
					GUISetState(@SW_SHOW, $hChild)
					$fChild = True
				Case $hBtn_2
					MsgBox(64, 'Info', 'Second', 0, $hParent)
			EndSwitch
		Case $hChild
			Switch $aMsg[0]
				Case $GUI_EVENT_CLOSE
					GUISetState(@SW_HIDE, $hChild)
					$fChild = False
				Case $hBtn_3
					MsgBox(64, 'Info', 'Third', 0, $hChild)
			EndSwitch
	EndSwitch
WEnd
GUIDelete($hChild)
GUIDelete($hParent)
$tParent = 0
$pParent = 0
$tChild = 0
$pChild = 0
Exit

Func _WM_WINDOWPOSCHANGED($h_Wnd, $i_Msg, $i_wParam, $i_lParam)
	If $fChild Then
		Local $t_WINDOWPOS = DllStructCreate($tagWINDOWPOS, $i_lParam), $i_X = DllStructGetData($t_WINDOWPOS, 'X'), _
				$i_Y = DllStructGetData($t_WINDOWPOS, 'Y'), $i_CX = DllStructGetData($t_WINDOWPOS, 'CX');, _
		;$i_CY = DllStructGetData($t_WINDOWPOS, 'CY')
		Switch $h_Wnd
			Case $hParent
				;'rcNormalPosition':	num 6
				DllStructSetData($tChild, 6, $i_X + $i_CX + $ix - $ix1, 1)
				DllStructSetData($tChild, 6, $i_Y, 2)
				DllStructSetData($tChild, 6, $i_X + $iWp + $i_CX + $ix, 3)
				DllStructSetData($tChild, 6, $i_Y + $iHc + $iy, 4)
				_WinAPI_SetWindowPlacement($hChild, $pChild)
				Return 0
			Case $hChild
				DllStructSetData($tParent, 6, $i_X - $iWc - $ix, 1)
				DllStructSetData($tParent, 6, $i_Y, 2)
				DllStructSetData($tParent, 6, $i_X - $iWc + $i_CX - $ix, 3)
				DllStructSetData($tParent, 6, $i_Y + $iHp + $iy - $ix + $ix1, 4)
				_WinAPI_SetWindowPlacement($hParent, $pParent)
				Return 0
		EndSwitch
	EndIf
	Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_WINDOWPOSCHANGED

Func _WinAPI_GetWindowPlacementEx($h_Wnd, ByRef $t_WindowPlacement, ByRef $p_WindowPlacement)

	If Not IsDllStruct($t_WindowPlacement) Then
		$t_WindowPlacement = DllStructCreate($tagWINDOWPLACEMENT)
		DllStructSetData($t_WindowPlacement, "length", DllStructGetSize($t_WindowPlacement))
		$p_WindowPlacement = DllStructGetPtr($t_WindowPlacement)
	EndIf
	Local $a_Res = DllCall("user32.dll", "bool", "GetWindowPlacement", "hwnd", $h_Wnd, "ptr", $p_WindowPlacement)
	If @error Or Not $a_Res[0] Then Return False
	Return True
EndFunc   ;==>_WinAPI_GetWindowPlacementEx
 
Автор
F

forbrock

Новичок
Сообщения
43
Репутация
0
Окно Child закрывается только со второго раза.
 
Верх