Что нового

Окна, Диалоги Перемещение окон одновременно

smsgeorge

Новичок
Сообщения
63
Репутация
0
Здравствуйте у меня имеется 2 окна. Как реализовать перемещение обоих, если переместилось одно. Перемещение должно происходить одновременно и не когда отпустишь левую кнопку мыши. У меня получилось сделать перемещение, когда отпустишь левую кнопку мыши и одно из окон переместилось, а надо сделать, чтобы сразу перемещение происходило.
Пример: Я зажал левую кнопку мыши на втором, окне и перемещаю его, перемещается первое также(сразу), нажал на первом окне, перемещаю мышку, перемещается и второе, как будто это одно единое окно.
Код:
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <FontConstants.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <Constants.au3>
#include <Array.au3>
#Include <GUIEdit.au3>
#Include <WinAPIEx.au3>
#include <Misc.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#NoTrayIcon
Opt("GUIOnEventMode", 1)  ; Включает режим OnEvent


TrayCreateItem("Выход")
TrayItemSetOnEvent(-1, "_Exit")
;;;;;;;;;;;;;;;;;;;
Global $Razmer_okna_GL=650
$mainwindow = GUICreate("Привет мир", $Razmer_okna_GL, 50,0, 0, ($GUI_SS_DEFAULT_GUI - $WS_CAPTION), $WS_EX_TOPMOST+$WS_EX_CONTROLPARENT)
GUISetState(@SW_SHOW)
;;;;;;;;;;;;;;;;;;;
$mainwindow_2 = GUICreate("Привет мир", $Razmer_okna_GL, 50,0, 100, ($GUI_SS_DEFAULT_GUI - $WS_CAPTION), ($WS_EX_TOPMOST+$WS_EX_CONTROLPARENT))
GUISetState(@SW_SHOW)
;;;;;;;;;;;;;;;;;;;
Opt("TrayMenuMode", 1 + 2) ; Не отображать в трее пункты меню по умолчанию (Script Paused/Exit) и не отмечать галочками при выборе.
Opt("TrayOnEventMode", 1) ; Включает режим TrayOnEventMode.
TraySetState(1) ; Показывает меню трея
;;;;;;;;;;;;;;;;;;;

While 1
  Sleep(100)  ; Цикл ожидания
WEnd

Func _Exit()
    Exit
EndFunc
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
как будто это одно единое окно
Я бы так и создал единое окно, и проделал бы в нём дыру...

Код:
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <FontConstants.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <Constants.au3>
#include <Array.au3>
#Include <GUIEdit.au3>
#Include <WinAPIEx.au3>
#include <Misc.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#NoTrayIcon

Opt("GUIOnEventMode", 1)  ; Включает режим OnEvent
TrayCreateItem("Выход")
TrayItemSetOnEvent(-1, "_Exit")
;;;;;;;;;;;;;;;;;;;
Global $Razmer_okna_GL = 650

$hGUI = GUICreate("Привет мир", $Razmer_okna_GL, 150, 0, 0, BitXOR($GUI_SS_DEFAULT_GUI, $WS_CAPTION), BitOR($WS_EX_TOPMOST, $WS_EX_CONTROLPARENT))
_GUICreateHole($hGUI, 0, 50, $Razmer_okna_GL, 50)

GUISetState(@SW_SHOW)
;;;;;;;;;;;;;;;;;;;
Opt("TrayMenuMode", 1 + 2) ; Не отображать в трее пункты меню по умолчанию (Script Paused/Exit) и не отмечать галочками при выборе.
Opt("TrayOnEventMode", 1) ; Включает режим TrayOnEventMode.
TraySetState(1) ; Показывает меню трея
;;;;;;;;;;;;;;;;;;;

While 1
    Sleep(100)  ; Цикл ожидания
WEnd

Func _Exit()
    Exit
EndFunc

Func _GUICreateHole($hWin, $i_X, $i_Y, $i_SizeW, $i_SizeH)
    Local $aWinPos = WinGetPos($hWin)
    Local $hOuter_Rgn = _WinAPI_CreateRectRgn(0, 0, $aWinPos[2], $aWinPos[3])
    Local $hInner_Rgn = _WinAPI_CreateRectRgn($i_X, $i_Y, $i_X + $i_SizeW, $i_Y + $i_SizeH)
    Local $hCombined_Rgn = _WinAPI_CreateRectRgn(0, 0, 0, 0)
    
    _WinAPI_CombineRgn($hCombined_Rgn, $hOuter_Rgn, $hInner_Rgn, $RGN_DIFF)
    _WinAPI_SetWindowRgn($hWin, $hCombined_Rgn, True)
EndFunc
 
Автор
S

smsgeorge

Новичок
Сообщения
63
Репутация
0
Благодарю за ответ! А если эти полоски как модули, то есть они будут добавляться, убавляться. Как сделать а) чтобы было несколько вырезов так сказать, либо б)опять же, как перемещать сразу несколько окон.
Я попробовал вставить вызов функции 2 раза с разными параметрами, но не получилось.
Код:
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <FontConstants.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <Constants.au3>
#include <Array.au3>
#Include <GUIEdit.au3>
#Include <WinAPIEx.au3>
#include <Misc.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#NoTrayIcon
Opt("GUIOnEventMode", 1)  ; Включает режим OnEvent


TrayCreateItem("Выход")
TrayItemSetOnEvent(-1, "_Exit")
;;;;;;;;;;;;;;;;;;;
Global $Razmer_okna_GL=650
$mainwindow = GUICreate("Привет мир", $Razmer_okna_GL, 50,0, 0, ($GUI_SS_DEFAULT_GUI - $WS_CAPTION), $WS_EX_TOPMOST+$WS_EX_CONTROLPARENT)
GUISetState(@SW_SHOW)
;;;;;;;;;;;;;;;;;;;
$mainwindow_2 = GUICreate("Привет мир", 400, 50,0, 50, ($GUI_SS_DEFAULT_GUI - $WS_CAPTION), ($WS_EX_TOPMOST+$WS_EX_CONTROLPARENT))
GUISetState(@SW_SHOW)
;;;;;;;;;;;;;;;;;;;
$mainwindow_2 = GUICreate("Привет мир", 300, 50,0, 100, ($GUI_SS_DEFAULT_GUI - $WS_CAPTION), ($WS_EX_TOPMOST+$WS_EX_CONTROLPARENT))
GUISetState(@SW_SHOW)
;;;;;;;;;;;;;;;;;;;
$mainwindow = GUICreate("Привет мир", $Razmer_okna_GL, 50,0, 150, ($GUI_SS_DEFAULT_GUI - $WS_CAPTION), $WS_EX_TOPMOST+$WS_EX_CONTROLPARENT)
GUISetState(@SW_SHOW)
;;;;;;;;;;;;;;;;;;;
Opt("TrayMenuMode", 1 + 2) ; Не отображать в трее пункты меню по умолчанию (Script Paused/Exit) и не отмечать галочками при выборе.
Opt("TrayOnEventMode", 1) ; Включает режим TrayOnEventMode.
TraySetState(1) ; Показывает меню трея
;;;;;;;;;;;;;;;;;;;

While 1
  Sleep(100)  ; Цикл ожидания
WEnd

Func _Exit()
    Exit
EndFunc
Снимок.JPG
 

InnI

AutoIT Гуру
Сообщения
4,599
Репутация
1,293
Код:
#include <GUIConstants.au3>
#include <WinAPISysWin.au3>

Global $Razmer_okna_GL=650
Global $Height = 50

$mainwindow = GUICreate("Привет мир", $Razmer_okna_GL, $Height, 0, 0, ($GUI_SS_DEFAULT_GUI - $WS_CAPTION), $WS_EX_TOPMOST+$WS_EX_CONTROLPARENT+$WS_EX_LAYERED)
GUICtrlCreateLabel("", 0, 50, $Razmer_okna_GL, 50)
$Btn = GUICtrlCreateButton("Добавить", 10, 10)
GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
_WinAPI_SetLayeredWindowAttributes($mainwindow, 0x010101)
GUISetState(@SW_SHOW)

Do
  Switch GUIGetMsg()
    Case -3
      Exit
    Case $Btn
      Add()
  EndSwitch
Until 0

Func Add()
  $Height += 100
  WinMove($mainwindow, "", Default, Default, Default, $Height)
  GUICtrlCreateLabel("", 0, $Height - 100, $Razmer_okna_GL, 50)
  GUICtrlSetBkColor(-1, 0x010101)
  GUICtrlSetResizing(-1, $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
EndFunc
 
Автор
S

smsgeorge

Новичок
Сообщения
63
Репутация
0
Благодарю! Единственное, что если потребуется скажем отдельно сдвинуть скажем "2 окно" , То это надо будет перерисовать все элементы, сдвинуть их, потом создать прозрачный лейбл полоску? Сложновато - ведь надо еще организовать якобы перемещение "2окна" с элементами.
Я сделал такой вариант.
1)Главное окно
2)Второе с параметром $WS_EX_MDICHILD
Если перемещать главное,"дочернее тоже перемещается" Но вот как сделать наоборот не знаю. Идея такая - Я двигаю за любое окно перемещаются оба, но иногда надо сдвинуть 2-ое, скажем зажав КОНТРЛ. Потом, как отпущу КОНТРЛ, опять происходит перемещение за любую часть окон.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
А если эти полоски как модули, то есть они будут добавляться, убавляться
Ну в первом сообщений об этом ни слова.
А что делать если допустим 3 таких модуля, перемещаться должны все когда тянут одно?

Тогда как то так:
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#NoTrayIcon

Global $ahGUI[1]
Global $iAdd_Top = 100

Opt('GUIOnEventMode', 1)  ; Включает режим OnEvent
Opt('TrayMenuMode', 1 + 2) ; Не отображать в трее пункты меню по умолчанию (Script Paused/Exit) и не отмечать галочками при выборе.
Opt('TrayOnEventMode', 1) ; Включает режим TrayOnEventMode.
TraySetState(1) ; Показывает меню трея
TrayCreateItem('Выход')
TrayItemSetOnEvent(-1, '_Exit')

$hModule1 = _Module_Add()
$hModule2 = _Module_Add()
$hModule3 = _Module_Add()

_Module_Del($hModule2)

While 1
    Sleep(100)  ; Цикл ожидания
WEnd

Func _Module_Add($sText = '', $iGUI_Width = 650, $iGUI_Height = 50)
    Local $iTop = 0
    
    If $ahGUI[0] > 0 Then
        Local $aWinPos = WinGetPos($ahGUI[$ahGUI[0]])
        $iTop = $aWinPos[1] + $iAdd_Top
    EndIf
    
    $ahGUI[0] += 1
    ReDim $ahGUI[$ahGUI[0] + 1]
    $ahGUI[$ahGUI[0]] = GUICreate($sText, $iGUI_Width, $iGUI_Height, 0, $iTop, _
        BitXOR($GUI_SS_DEFAULT_GUI, $WS_CAPTION), BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST, $WS_EX_CONTROLPARENT))
    
    GUISetState(@SW_SHOW, $ahGUI[$ahGUI[0]])
    
    If $ahGUI[0] = 1 Then
        GUIRegisterMsg($WM_WINDOWPOSCHANGING, 'WM_WINDOWPOSCHANGING')
    EndIf
    
    ;Close on ESC
    GUISetOnEvent($GUI_EVENT_CLOSE, '_Exit', $ahGUI[$ahGUI[0]])
    Return $ahGUI[$ahGUI[0]]
EndFunc

Func _Module_Del($hModule)
    GUIRegisterMsg($WM_WINDOWPOSCHANGING, '')
    Local $aTmp[1]
    
    For $i = 1 To $ahGUI[0]
        If $hModule = $ahGUI[$i] Then
            GUIDelete($hModule)
            
            For $j = $i + 1 To $ahGUI[0]
                $aWinPos = WinGetPos($ahGUI[$j])
                WinMove($ahGUI[$j], '', $aWinPos[0], $aWinPos[1] - $iAdd_Top)
            Next
        Else
            $aTmp[0] += 1
            ReDim $aTmp[$aTmp[0] + 1]
            $aTmp[$aTmp[0]] = $ahGUI[$i]
        EndIf
    Next
    
    $ahGUI = $aTmp
    GUIRegisterMsg($WM_WINDOWPOSCHANGING, 'WM_WINDOWPOSCHANGING')
EndFunc

Func WM_WINDOWPOSCHANGING($hWnd, $Msg, $wParam, $lParam)
    Local $stWinPos = DllStructCreate('uint;uint;int;int;int;int;uint', $lParam)
    Local $iLeft = DllStructGetData($stWinPos, 3)
    Local $iTop = DllStructGetData($stWinPos, 4)
    
    If $iTop = 0 Then
        Return
    EndIf
    
    Local Static $hLast_Wnd = $hWnd
    Local Static $iLast_Top = $iTop
    Local $iT = 0, $aWinPos
    
    If $hLast_Wnd <> $hWnd Then
        $hLast_Wnd = $hWnd
        $iLast_Top = $iTop
    EndIf
    
    Local $fDown = ($iLast_Top < $iTop)
    Local $iDiff = ($fDown ? ($iTop - $iLast_Top) : ($iLast_Top - $iTop))
    
    If $iLast_Top = 0 Then
        $iDiff = 0
    EndIf
    
    For $i = 1 To $ahGUI[0]
        If $ahGUI[$i] = $hWnd Then
            ContinueLoop
        EndIf
        
        $aWinPos = WinGetPos($ahGUI[$i])
        $iT = ($fDown ? ($aWinPos[1] + $iDiff) : ($aWinPos[1] - $iDiff))
        
        WinMove($ahGUI[$i], '', $iLeft, $iT)
    Next
    
    $iLast_Top = $iTop
EndFunc

Func _Exit()
    Exit
EndFunc
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
если потребуется скажем отдельно сдвинуть скажем "2 окно" , То это надо будет перерисовать все элементы
Зачем? оно уже и так работает, хороший вариант предложил @InnI, я сразу и не заметил.
 
Автор
S

smsgeorge

Новичок
Сообщения
63
Репутация
0
Вариант от @InnI хороший, мне очень понравилась эта реализация и понятна! Но иногда приходится сдвигать скажем 2-ое окно, чтобы 1 осталось на месте. (типа если зажать контрл мы можем двигать окна по отдельности, а если не зажимать, то перемещая за любое из окон переместятся все)
Окон может быть много, они как модули добавляются при необходимости.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,669
Репутация
2,463
иногда приходится сдвигать скажем 2-ое окно, чтобы 1 осталось на месте
Вот ещё условие добавилось...
"Так мы с вами кашу не сварим"
если зажать контрл мы можем двигать окна по отдельности, а если не зажимать, то перемещая за любое из окон переместятся все
Тогда мой вариант в изменённом виде:
Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>

Global $ahGUI[1]
Global $iAdd_Top = 100

Opt('GUIOnEventMode', 1)  ; Включает режим OnEvent
Opt('TrayMenuMode', 1 + 2) ; Не отображать в трее пункты меню по умолчанию (Script Paused/Exit) и не отмечать галочками при выборе.
Opt('TrayOnEventMode', 1) ; Включает режим TrayOnEventMode.
TraySetState(1) ; Показывает меню трея
TrayCreateItem('Выход')
TrayItemSetOnEvent(-1, '_Exit')

$hModule1 = _Module_Add()
$hModule2 = _Module_Add()
$hModule3 = _Module_Add()

;_Module_Del($hModule2)

While 1
    Sleep(100)  ; Цикл ожидания
WEnd

Func _Module_Add($sText = '', $iGUI_Width = 650, $iGUI_Height = 50)
    Local $iTop = 0
    
    If $ahGUI[0] > 0 Then
        Local $aWinPos = WinGetPos($ahGUI[$ahGUI[0]])
        $iTop = $aWinPos[1] + $iAdd_Top
    EndIf
    
    $ahGUI[0] += 1
    ReDim $ahGUI[$ahGUI[0] + 1]
    $ahGUI[$ahGUI[0]] = GUICreate($sText, $iGUI_Width, $iGUI_Height, 0, $iTop, _
        BitXOR($GUI_SS_DEFAULT_GUI, $WS_CAPTION), BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST, $WS_EX_CONTROLPARENT))
    
    GUISetState(@SW_SHOW, $ahGUI[$ahGUI[0]])
    
    If $ahGUI[0] = 1 Then
        GUIRegisterMsg($WM_WINDOWPOSCHANGED, 'WM_WINDOWPOSCHANGING')
    EndIf
    
    ;Close on ESC
    GUISetOnEvent($GUI_EVENT_CLOSE, '_Exit', $ahGUI[$ahGUI[0]])
    Return $ahGUI[$ahGUI[0]]
EndFunc

Func _Module_Del($hModule)
    GUIRegisterMsg($WM_WINDOWPOSCHANGING, '')
    Local $aTmp[1]
    
    For $i = 1 To $ahGUI[0]
        If $hModule = $ahGUI[$i] Then
            GUIDelete($hModule)
            
            For $j = $i + 1 To $ahGUI[0]
                $aWinPos = WinGetPos($ahGUI[$j])
                WinMove($ahGUI[$j], '', $aWinPos[0], $aWinPos[1] - $iAdd_Top)
            Next
        Else
            $aTmp[0] += 1
            ReDim $aTmp[$aTmp[0] + 1]
            $aTmp[$aTmp[0]] = $ahGUI[$i]
        EndIf
    Next
    
    $ahGUI = $aTmp
    GUIRegisterMsg($WM_WINDOWPOSCHANGING, 'WM_WINDOWPOSCHANGING')
EndFunc

Func WM_WINDOWPOSCHANGING($hWnd, $Msg, $wParam, $lParam)
    Local $stWinPos = DllStructCreate('uint;uint;int;int;int;int;uint', $lParam)
    Local $iLeft = DllStructGetData($stWinPos, 3)
    Local $iTop = DllStructGetData($stWinPos, 4)
    
    Local Static $hLast_Wnd = $hWnd
    Local Static $iLast_Left = $iLeft
    Local Static $iLast_Top = $iTop
    Local $iL = 0, $iT = 0, $aWinPos
    
    If $iTop = 0 Then
        Return $GUI_RUNDEFMSG
    EndIf
    
    If $hLast_Wnd <> $hWnd Or _IsPressed(11) Then
        $hLast_Wnd = $hWnd
        $iLast_Left = $iLeft
        $iLast_Top = $iTop
        
        If $hLast_Wnd = $hWnd Then
            Return $GUI_RUNDEFMSG
        EndIf
    EndIf
    
    Local $fDown = ($iLast_Top < $iTop)
    Local $fRight = ($iLast_Left < $iLeft)
    Local $iDiff_Left = ($fRight ? ($iLeft - $iLast_Left) : ($iLast_Left - $iLeft))
    Local $iDiff_Top = ($fDown ? ($iTop - $iLast_Top) : ($iLast_Top - $iTop))
    
    If $iLast_Left = 0 Then
        $iDiff_Left = 0
    EndIf
    
    If $iLast_Top = 0 Then
        $iDiff_Top = 0
    EndIf
    
    For $i = 1 To $ahGUI[0]
        If $ahGUI[$i] = $hWnd Then
            ContinueLoop
        EndIf
        
        $aWinPos = WinGetPos($ahGUI[$i])
        
        $iL = ($fRight ? ($aWinPos[0] + $iDiff_Left) : ($aWinPos[0] - $iDiff_Left))
        $iT = ($fDown ? ($aWinPos[1] + $iDiff_Top) : ($aWinPos[1] - $iDiff_Top))
        
        WinMove($ahGUI[$i], '', $iL, $iT)
    Next
    
    $iLast_Left = $iLeft
    $iLast_Top = $iTop
    
    Return $GUI_RUNDEFMSG
EndFunc

Func _Exit()
    Exit
EndFunc


Но тут тоже назревает вопрос - после того как переместили один модуль (зажав Ctrl), далее передвижение всех окон (без Ctrl) должно происходить относительно друг другу, или выравнено по одной линий (как в начале)?
 
Автор
S

smsgeorge

Новичок
Сообщения
63
Репутация
0
Вот этот вариант, что надо! Благодарю! Снимок.JPG
 
Верх