Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » определение z-порядка для для гуи элемента

Ответить
Настройки темы
определение z-порядка для для гуи элемента

Новый участник


Сообщения: 13
Благодарности: 1


Конфигурация

Профиль | Отправить PM | Цитировать


Существует ли в природе метод, позволяющий для каждого конкретного гуи элемента, узнать его z-порядковый номер? Может быть какие-нибудь апи есть?...Уточню некоторые детали. Если я создаю гуи элемент, то каждый последующий элемент по умолчанию будет находится поверх предыдущего, это в нормальном случае, но если я задействую функцию
Код: Выделить весь код
GUICtrlSetState($ctrl, $GUI_ONTOP)
для этого элемента, то он отправится в самый низ(как ни странно, но в автоите у меня это работает именно так, - вниз а не вверх). И вот в этом случае, хотелось бы иметь возможность настраивать взаимное положение элементов в зависимости от ситуации, а для этого нужно знать, z-порядок для каждого элемента в любой момент времени.

Отправлено: 11:23, 20-02-2023

 

Старожил


Сообщения: 352
Благодарности: 192

Профиль | Отправить PM | Цитировать


Ботяра,
Тут всё немного сложнее, чем кажется на первый взгляд.

Z-order направлен по вымышленной оси от экрана наружу (к пользователю) (z-order).
Дочерние окна (в терминологии WinAPI, кнопки и прочие штуки -- окна определённого класса) при содании добавляются в конец z-order (CreateWindowEx). Т.е. первый элемент -- самый верхний в порядке, второй ниже по иерархии, третий еще ниже и т.д.

Windows по умолчанию так и отрисовывает - сначала самый верхний первый, потом второй, ...
Для правильной отрисовки (с обрезкой перекрывающихся частей окон) требуется присвоить накладывающимся элементам стиль WS_CLIPSIBLINGS (Child Window Update Region, последний абзац).
Альтернативный способ (со своими особенностями) - присвоить родительскому окну расширенный стиль WS_EX_COMPOSITED.

В скрипте-примере:
- получение массива дочерних окон в z-порядке через _WinAPI_GetTopWindow, _WinAPI_GetWindow(.., GW_HWNDNEXT)
- изменение z-order через _WinAPI_SetWindowPos
- быстрая отрисовка при массовом изменении окон (здесь для функции сброса) через _WinAPI_BeginDeferWindowPos, _WinAPI_DeferWindowPos, _WinAPI_EndDeferWindowPos

Пример
Код: Выделить весь код
AutoItSetOption("GUIOnEventMode", 1)

#include <WinAPI.au3>
#include <WinAPISysWin.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>

Main()


Func Main()
    Global $hGUI, $hLabels[5], $idButtons[3][4], $hControls[256]
    Global Enum $MTOP, $MHIGHER, $MLOWER, $MBOTTOM

    $hGUI = GUICreate("Z-order playground", 600, 600)
    GUISetOnEvent($GUI_EVENT_CLOSE, "EV_Exit")

    GUICreateControls()

    While 1
        Sleep(100)
    WEnd
EndFunc


Func GUICreateControls()
    Local $GW, $GH, $tRECT, $top

    $tRECT = _WinAPI_GetClientRect($hGUI)
    $GW = DllStructGetData($tRECT, "Right")
    $GH = DllStructGetData($tRECT, "Bottom")

    $hLabels[0] = GUICtrlCreateLabel_My(0, 10, 10, 230, 55, 0xFFAAAA)
    $hLabels[1] = GUICtrlCreateLabel_My(1, 35, 40, 190, 70, 0xAAFFAA)
    $hLabels[2] = GUICtrlCreateLabel_My(2, 60, 45, 150, 90, 0xAAAAFF)

    $hLabels[3] = GUICtrlCreateLabel_My(3, 10,       140, $GW/2-20, $GH-150, 0xFFFFFF)
    $hLabels[4] = GUICtrlCreateLabel_My(4, 10+$GW/2, 140, $GW/2-20, $GH-150, 0xFFFFFF)

    For $i = 0 To 2
        $top = 10+$i*30
        $idButtons[$i][0] = GUICtrlCreateButton("top",    250,      $top, 60, 24)
        GUICtrlSetOnEvent(-1, "EV_ChangeZOrder")
        $idButtons[$i][1] = GUICtrlCreateButton("higher", 250+65*1, $top, 60, 24)
        GUICtrlSetOnEvent(-1, "EV_ChangeZOrder")
        $idButtons[$i][2] = GUICtrlCreateButton("lower",  250+65*2, $top, 60, 24)
        GUICtrlSetOnEvent(-1, "EV_ChangeZOrder")
        $idButtons[$i][3] = GUICtrlCreateButton("bottom", 250+65*3, $top, 60, 24)
        GUICtrlSetOnEvent(-1, "EV_ChangeZOrder")
    Next

    GUICtrlCreateButton("RESET", $GW-70, 10, 60, 24)
    GUICtrlSetOnEvent(-1, "GUIResetControls")

    $hControls = GUIGetChildsList($hGUI)

    UpdateWindowInfo()
    UpdateWindowInfo2()

    GUISetState(@SW_SHOW)
EndFunc


Func GUIResetControls()
    Static Local $swp_flags = BitOr($SWP_NOMOVE, $SWP_NOSIZE)
    Local $HDWP

    $HDWP = _WinAPI_BeginDeferWindowPos(UBound($hControls))
    $HDWP = _WinAPI_DeferWindowPos($HDWP, $hControls[0], $HWND_TOP, 0,0,0,0, $swp_flags)
    For $i = 1 To UBound($hControls) - 1
        $HDWP = _WinAPI_DeferWindowPos($HDWP, $hControls[$i], $hControls[$i-1], 0,0,0,0, $swp_flags)
    Next
    _WinAPI_EndDeferWindowPos($HDWP)

    UpdateWindowInfo()
    UpdateWindowInfo2()
EndFunc


Func GUICtrlCreateLabel_My($idx = "@", $x = 0, $y = 0, $w = 0, $h = 0, $bkcolor = $GUI_BKCOLOR_DEFAULT)
    Local $id = GUICtrlCreateLabel("", $x, $y, $w, $h, $WS_CLIPSIBLINGS)
    Local $hwnd = GUICtrlGetHandle($id)
    Local $text = StringFormat("[%i] 0x%08X", $idx, $hwnd) & @crlf
    _WinAPI_SetWindowText($hwnd, $text & $text & $text & $text & $text)
    GUICtrlSetBkColor(-1, $bkcolor)
    GUICtrlSetFont(-1, 9, 400, 0, "Consolas")
    Return $hwnd
EndFunc


Func GUIGetChildsList($parent)
    Local $count = 0, $array[256]

    $array[0] = _WinAPI_GetTopWindow($hGUI)
    While True
        $count += 1
        $array[$count] = _WinAPI_GetWindow($array[$count-1], $GW_HWNDNEXT)
        If $array[$count] = 0 Then ExitLoop
    WEnd

    ReDim $array[$count]

    Return $array
EndFunc


Func FindInArray($value, $array)
    For $i = 0 To UBound($array) - 1
        if $value = $array[$i] Then Return $i
    Next

    Return -1
EndFunc


Func UpdateWindowInfo()
    Local $text, $sfmt = "%-12s = 0x%08X\n"

    $text  = StringFormat("[3] 0x%08X", $hLabels[3]) & @crlf & @crlf
    $text &= StringFormat($sfmt, "hGUI",    $hGUI)
    $text &= StringFormat($sfmt, "parent c",  _WinAPI_GetParent($hLabels[1]))
    $text &= StringFormat($sfmt, "top",       _WinAPI_GetTopWindow($hGUI))
    $text &= StringFormat($sfmt, "first c",   _WinAPI_GetWindow($hLabels[1], $GW_HWNDFIRST))
    $text &= StringFormat($sfmt, "last",      _WinAPI_GetWindow(_WinAPI_GetTopWindow($hGUI), $GW_HWNDLAST))
    $text &= StringFormat($sfmt, "last c",    _WinAPI_GetWindow($hLabels[1], $GW_HWNDLAST))
    $text &= StringFormat($sfmt, "next c(1)", _WinAPI_GetWindow($hLabels[1], $GW_HWNDNEXT))

    _WinAPI_SetWindowText($hLabels[3], $text)
EndFunc


Func UpdateWindowInfo2()
    Local $ctl = GUIGetChildsList($hGUI)
    Local $text = StringFormat("[4] 0x%08X\n\n%s\n", $hLabels[4],"Z-order:")

    For $i = 0 To UBound($ctl) - 1
        $text &= $ctl[$i] _
               & (FindInArray($ctl[$i], $hLabels)>=0 ? (" :: " & FindInArray($ctl[$i], $hLabels)) : "" ) _
               & ($i = 0 ? " :: first" : "" ) _
               & @crlf
    Next

    _WinAPI_SetWindowText($hLabels[4], $text)
EndFunc


Func GUIControlChangeZOrder($hwnd, $action)
    Static Local $swp_flags = BitOr($SWP_NOMOVE, $SWP_NOSIZE)

    Switch $action
        Case $MTOP
            _WinAPI_SetWindowPos($hwnd, $HWND_TOP, 0,0,0,0, $swp_flags)

        Case $MHIGHER
            If $hwnd <> _WinAPI_GetTopWindow($hGUI) Then
                _WinAPI_SetWindowPos(_WinAPI_GetWindow($hwnd, $GW_HWNDPREV), $hwnd, 0,0,0,0, $swp_flags)
            EndIf

        Case $MLOWER
            If $hwnd <> _WinAPI_GetWindow($hwnd, $GW_HWNDLAST) Then
                _WinAPI_SetWindowPos($hwnd, _WinAPI_GetWindow($hwnd, $GW_HWNDNEXT), 0,0,0,0, $swp_flags)
            EndIf

        Case $MBOTTOM
            _WinAPI_SetWindowPos($hwnd, $HWND_BOTTOM, 0,0,0,0, $swp_flags)

    EndSwitch

    UpdateWindowInfo()
    UpdateWindowInfo2()
EndFunc


Func EV_ChangeZOrder()
    For $ctl = 0 To 2
        For $action = 0 To 3
            If $idButtons[$ctl][$action] = @GUI_CtrlId Then ExitLoop 2
        Next
    Next

    GUIControlChangeZOrder($hLabels[$ctl], $action)
EndFunc


Func EV_Exit()
    GUIDelete($hGUI)
    Exit
EndFunc
Это сообщение посчитали полезным следующие участники:

Отправлено: 21:48, 21-02-2023 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 13
Благодарности: 1

Профиль | Отправить PM | Цитировать


Цитата iglezz:
В скрипте-примере:
- получение массива дочерних окон в z-порядке через _WinAPI_GetTopWindow, _WinAPI_GetWindow(.., GW_HWNDNEXT)
- изменение z-order через _WinAPI_SetWindowPos
- быстрая отрисовка при массовом изменении окон (здесь для функции сброса) через _WinAPI_BeginDeferWindowPos, _WinAPI_DeferWindowPos, _WinAPI_EndDeferWindowPos »
Спасибо! Это то, что надо. Все работает!

Отправлено: 10:48, 22-02-2023 | #3



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » определение z-порядка для для гуи элемента

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Разное - Подскажите твик для Cortana на отключение для этого элемента —> hokg Microsoft Windows 10 2 03-08-2016 12:17
Ошибка "для элемента или информационного пакета не выбран драйвер" barvik@vk Microsoft Windows 7 2 24-03-2013 10:47
Разное - Составление процедуры для определения минимального элемента матрицы Boney Программирование и базы данных 1 27-05-2008 22:39
замена значения элемента массива другим значением элемента.. MXM Вебмастеру 1 20-05-2004 06:50
определение диска для CD-ROMa marussia Microsoft Windows 95/98/Me (архив) 2 05-05-2002 23:44




 
Переход