Что нового

"Склеиваем" два окна при перемещении

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Данный пример показывает, как можно "приклеить" одно окно к другому при перемещении одного из них. Код писался на Windows XP, для Windows Vista/7 его нужно немного "откалибровать"...

Код:
#Include <GUIConstantsEx.au3>
#Include <WindowsConstants.au3>

$hOpt = 0

$hForm = GUICreate('MyGUI', 400, 400, 600, 100, BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU))
$Button = GUICtrlCreateButton('Options', 165, 366, 70, 23)
GUIRegisterMsg($WM_ACTIVATE, 'WM_ACTIVATE')
GUIRegisterMsg($WM_MOVE, 'WM_MOVE')
GUISetState()

While 1
	$Msg = GUIGetMsg(1)
	Switch $Msg[0]
		Case -3
			Switch $Msg[1]
				Case $hForm
					Exit
				Case $hOpt
					GUICtrlSetState($Button, $GUI_ENABLE)
					GUIDelete($hOpt)
					$hOpt = 0
			EndSwitch
		Case $Button
			If Not $hOpt Then
				$Pos = WinGetPos($hForm)
				$hOpt = GUICreate('Options', 400, 100, $Pos[0], $Pos[1] + 436, BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU))
				GUISetState(@SW_SHOWNOACTIVATE, $hOpt)
				GUICtrlSetState($Button, $GUI_DISABLE)
			EndIf
	EndSwitch
WEnd

Func WM_ACTIVATE($hWnd, $iMsg, $wParam, $lParam)
	Switch BitAND($wParam, 0xFFFF)
		Case 1, 2
			Switch $hWnd
				Case 0

				Case $hForm
					If $hOpt Then
						WinSetOnTop($hOpt, '', 1)
						WinSetOnTop($hOpt, '', 0)
					EndIf
				Case $hOpt
					WinSetOnTop($hForm, '', 1)
					WinSetOnTop($hForm, '', 0)
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_ACTIVATE

Func WM_MOVE($hWnd, $iMsg, $wParam, $lParam)
	$X = BitAND($lParam, 0xFFFF)
	If $X > 0x7FFF Then
		$X -= 0x10000
	EndIf
	$Y = BitShift($lParam, 16)
	If $Y > 0x7FFF Then
		$Y -= 0x10000
	EndIf
	Switch $hWnd
		Case 0

		Case $hForm
			If $hOpt Then
				WinMove($hOpt, '', $X - 3, $Y + 407)
			EndIf
		Case $hOpt
			WinMove($hForm, '', $X - 3, $Y - 465)
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_MOVE
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
А для чего все эти проверки с «If $X > 0x7FFF Then»?

Вот так вроде тоже самое:

Код:
#Include <GUIConstantsEx.au3>
#Include <WindowsConstants.au3>

Global $hOpt = 0

$hForm = GUICreate('MyGUI', 400, 400, 600, 100, BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU))
$Button = GUICtrlCreateButton('Options', 165, 366, 70, 23)
GUIRegisterMsg($WM_ACTIVATE, 'WM_ACTIVATE')
GUIRegisterMsg($WM_MOVE, 'WM_MOVE')
GUISetState()

While 1
    $Msg = GUIGetMsg(1)
    Switch $Msg[0]
        Case -3
            Switch $Msg[1]
                Case $hForm
                    Exit
                Case $hOpt
                    GUICtrlSetState($Button, $GUI_ENABLE)
                    GUIDelete($hOpt)
            EndSwitch
        Case $Button
            If BitAND(WinGetState($hOpt), 2) <> 2 Then
                $Pos = WinGetPos($hForm)
                $hOpt = GUICreate('Options', $Pos[2], 100, $Pos[0], $Pos[1] + $Pos[3] + 7, BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU))
                GUISetState(@SW_SHOWNOACTIVATE, $hOpt)
                GUICtrlSetState($Button, $GUI_DISABLE)
            EndIf
    EndSwitch
WEnd

Func WM_ACTIVATE($hWnd, $iMsg, $wParam, $lParam)
    Switch BitAND($wParam, 0xFFFF)
        Case 1, 2
            Switch $hWnd
                Case $hForm
                    If BitAND(WinGetState($hOpt), 2) = 2 Then
                        WinSetOnTop($hOpt, '', 1)
                        WinSetOnTop($hOpt, '', 0)
                    EndIf
                Case $hOpt
                    WinSetOnTop($hForm, '', 1)
                    WinSetOnTop($hForm, '', 0)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func WM_MOVE($hWndGUI)
	Local $aParentPos = WinGetPos($hForm), $aChildPos = WinGetPos($hOpt)
	
	If $hWndGUI = $hForm Then
		WinMove($hOpt, "", $aParentPos[0], $aParentPos[1] + $aParentPos[3] + 7)
	ElseIf $hWndGUI = $hOpt Then
		WinMove($hForm, "", $aChildPos[0], $aChildPos[1] - $aParentPos[3] - 7)
	EndIf
EndFunc
 
Верх