- Сообщения
- 5,379
- Репутация
- 2,724
Функция перемещает одно окно ($hWnd) относительно клиентской области другого окна ($hParent) на расстояние, заданное параметрами $iX и $iY, как это обычно делает Windows при открытии дочерних окон. Может быть полезна а программах, работающих с несколькими окнами.
Код:
$hParent = GUICreate('Parent', 300, 300)
$hForm = GUICreate('Form', 200, 200)
GUISetState(@SW_SHOW, $hParent)
GUISetState(@SW_SHOW, $hForm)
Sleep(1000)
_MoveWindow($hForm, $hParent, 0, 0)
Do
Until GUIGetMsg() = -3
Func _MoveWindow($hWnd, $hParent = 0, $iX = Default, $iY = Default, $iW = -1, $iH = -1, $fClient = 1, $fResize = 0)
Local $Area[4], $Wx[2], $Cx[2], $tRect, $pRect, $Pos, $Ret
$Ret = DllCall('user32.dll', 'long', 'GetWindowLongW', 'hwnd', $hWnd, 'int', -16)
If (@error) Or (BitAND($Ret[0], 0x21000000)) Then
Return 0
EndIf
$Pos = WinGetPos($hWnd)
If @error Then
Return 0
EndIf
If $iW = -1 Then
$iW = $Pos[2]
EndIf
If $iH = -1 Then
$iH = $Pos[3]
EndIf
$tRect = DllStructCreate('int;int;int;int')
$pRect = DllStructGetPtr($tRect)
$Ret = DllCall('dwmapi.dll', 'uint', 'DwmGetWindowAttribute', 'hwnd', $hWnd, 'dword', 9, 'ptr', $pRect, 'dword', 16)
If (Not @error) And (Not $Ret[0]) Then
For $i = 0 To 1
$Wx[$i] = DllStructGetData($tRect, $i + 3) - DllStructGetData($tRect, $i + 1) - $Pos[$i + 2]
Next
Else
For $i = 0 To 1
$Wx[$i] = 0
Next
EndIf
$iW += $Wx[0]
$iH += $Wx[1]
$Ret = DllCall('user32.dll', 'int', 'SystemParametersInfoW', 'uint', 0x0030, 'uint', 0, 'ptr', $pRect, 'uint', 0)
If (@error) Or (Not $Ret[0]) Then
$Area[0] = 0
$Area[1] = 0
$Area[2] = @DesktopWidth
$Area[3] = @DesktopHeight
Else
For $i = 0 To 3
$Area[$i] = DllStructGetData($tRect, $i + 1)
Next
EndIf
Do
If $hParent Then
$Ret = DllCall('user32.dll', 'long', 'GetWindowLongW', 'hwnd', $hParent, 'int', -16)
If @error Then
Return 0
EndIf
If Not BitAND($Ret[0], 0x20000000) Then
If $fClient Then
$Ret = DllCall('user32.dll', 'int', 'GetClientRect', 'hwnd', $hParent, 'ptr', $pRect)
If (@error) Or (Not $Ret[0]) Then
Return 0
EndIf
$Ret = DllCall('user32.dll', 'int', 'ClientToScreen', 'hwnd', $hParent, 'ptr', $pRect)
If (@error) Or (Not $Ret[0]) Then
Return 0
EndIf
If $iX = Default Then
$iX = Int((DllStructGetData($tRect, 3) - $iW) / 2)
EndIf
If $iY = Default Then
$iY = Int((DllStructGetData($tRect, 4) - $iH) / 2)
EndIf
$iX += DllStructGetData($tRect, 1)
$iY += DllStructGetData($tRect, 2)
Else
$Pos = WinGetPos($hParent)
If @error Then
Return 0
EndIf
$Ret = DllCall('dwmapi.dll', 'uint', 'DwmGetWindowAttribute', 'hwnd', $hParent, 'dword', 9, 'ptr', $pRect, 'dword', 16)
If (Not @error) And (Not $Ret[0]) Then
For $i = 0 To 1
$Cx[$i] = DllStructGetData($tRect, $i + 3) - DllStructGetData($tRect, $i + 1) - $Pos[$i + 2]
Next
Else
For $i = 0 To 1
$Cx[$i] = 0
Next
EndIf
If $iX = Default Then
$iX = Int(($Pos[2] + $Cx[0] - $iW) / 2)
EndIf
If $iY = Default Then
$iY = Int(($Pos[3] + $Cx[1] - $iH) / 2)
EndIf
$iX += $Pos[0] - $Cx[0] / 2
$iY += $Pos[1] - $Cx[1] / 2
EndIf
ExitLoop
EndIf
EndIf
If $iX = Default Then
$iX = Int(($Area[2] - $iW) / 2)
EndIf
If $iY = Default Then
$iY = Int(($Area[3] - $iH) / 2)
EndIf
$iX += $Area[0]
$iY += $Area[1]
Until 1
$iX += $Wx[0] / 2
$iY += $Wx[1] / 2
If ($fResize) And ($iW > $Area[2] - $Area[0]) Then
$iW = $Area[2] - $Area[0] - $Wx[0]
EndIf
If ($fResize) And ($iH > $Area[3] - $Area[1]) Then
$iH = $Area[3] - $Area[1] - $Wx[1]
EndIf
If $iX > $Area[2] - $iW Then
$iX = $Area[2] - $iW + $Wx[0] / 2
EndIf
If $iX < $Area[0] Then
$iX = $Area[0] + $Wx[0] / 2
EndIf
If $iY > $Area[3] - $iH Then
$iY = $Area[3] - $iH + $Wx[1] / 2
EndIf
If $iY < $Area[1] Then
$iY = $Area[1] + $Wx[1] / 2
EndIf
If WinMove($hWnd, '', $iX, $iY, $iW - $Wx[0], $iH - $Wx[1]) Then
Return 0
Else
Return 1
EndIf
EndFunc ;==>_MoveWindow