Zorder окон, Reorder по возможности не мешающий системе

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Zorder окон, Reorder по возможности не мешающий системе

Сообщение Avtopic » 20.06.2007 (Ср) 15:16

Здравствуйте!

задача такая, имеется некая бухгалтерская программа, ThreadID2, окно Prog_Form_hWnd.
и моя программа, ThreadID1, окно MyForm_hWnd

Над Бухгалтерской программой постоянно должно висеть мое окно маленького размера MyForm , причем обязательно в положении HWND_TOPMOST, но если рабочий паток не мой ThreadID1, и не программы ThreadID2, то не должно быть вмешательства в систему (в Zorder).



нет сабклассинга, нет хуков (вернее сабклассинг только на моем окне MyForm_hWnd).

решаю так, сидит таймер, интервал 100мс, а в обработке следующий код:
Код: Выделить всё
   CurrentThreadID = GetWindowThreadProcessId(GetForegroundWindow, ByVal 0&)
   
    If CurrentThreadID = ThreadID1 Then     '"myForm"

        If GetWindow(Prog_Form_hWnd, GW_HWNDPREV) <> MyForm_hWnd Then
            SetWindowPos Prog_Form_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
            SetWindowPos MyForm_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
        End If

    ElseIf CurrentThreadID = ThreadID2 Then     '"prog Form"

        If GetWindow(Prog_Form_hWnd, GW_HWNDPREV) <> MyForm_hWnd Then
            SetWindowPos MyForm_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
        End If

    Else
'   “случай, когда постороннее окно активировали, по идее  MyForm_hWnd должен потерять TOPMOST свойство”
'   “проблемное место”
        SetWindowPos MyForm_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_NOMOVE Or SWP_NOSIZE

    End If

кроме этого
в WindowProc моего окна в сообщении WA_INACTIVE сидит
Код: Выделить всё
SetWindowPos MyForm_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE



Проблема в “проблемном месте”, (когда активировали чужое окно, процесс которого не наш и не бухг. программы),

1. если до этого активное было MyForm, все работает нормально, так как WindowProc WA_INACTIVE успевает перевести состояние топмость в HWND_NOTOPMOST и “чужое” окно оказывается сверху, как и положено в Windows для Foreground окна.

2. но если до этого активное было окно бухг. программы, то увы, в “проблемном месте”, MyForm опять сверху над “чужим” окном, хотя со свойством HWND_NOTOPMOST. Она приобретает это свойство только после того как “чужое” окно отрисовалось на второй позиции.

может, предложите решение. Хук окна бухгалтерской программы исключается.
Последний раз редактировалось Avtopic 20.06.2007 (Ср) 16:22, всего редактировалось 1 раз.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 20.06.2007 (Ср) 16:20

Вариант решения: забыть про HWND_TOPMOST и сделать своё окно top-level owned по сравнению с окном, над которым оно должно зависать.
Изображение

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 20.06.2007 (Ср) 17:30

Я и не представлял, что окна разных процессов можно так связать.
Сколько я кода перепробовал...
Спасибо, tyomitch, большое!

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 23.06.2007 (Сб) 18:42

столкнулся с такой проблемой,

Запущено три отдельных MIDI приложение.
Мае окно, которое зависает сверху, становится, как вы посоветовали top-level owned по отношению с окном из этих трех, который форегроунд (опять таки, проверяется по таймеру). т.е. переключается с одного на другую.
делаю примерно так:
Код: Выделить всё
    If GetWindowLong(MyForm_hWnd, GWL_HWNDPARENT) <> New_Owner Then
        Call SetWindowLong(MyForm_hWnd, GWL_HWNDPARENT, 0)
        Call SetWindowPos(Hform, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE)
        Call SetWindowLong(Hform, GWL_HWNDPARENT, New_Owner)
    End If 


Все происходит как и хотелось, но после нескольких переключении, перестаю реагировать иконки на панели задач. Их нажатие не вызывает активацию соответствующего MIDI приложения. Подумал дело в бухгалтерской программе, но, оказалось, так происходит на всех MIDI приложениях, и не происходит на обычных.

SetWindowLong(..., GWL_HWNDPARENT, ...) в частых случаях используют как раз для воздействия на иконки на панели задач, и что происходит в моем случае неправильного не могу понять.
Можете еще помочь? :)

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 23.06.2007 (Сб) 21:10

MIDI -- это такой музыкальный интерфейс.
А владельца задают функцией SetParent.
Изображение

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 24.06.2007 (Вс) 13:18

tyomitch писал(а):MIDI -- это такой музыкальный интерфейс.
MDI

tyomitch писал(а):А владельца задают функцией SetParent.
:shock:
я не хочу, чтобы SetParent, и “проглатывалась” я хочу, чтобы окно появлялось на переднем плане, но координаты не ограничивались владельцем.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 24.06.2007 (Вс) 13:49

Если парент, то будет по-любому "проглатываться" и ограничиваться. По-другому не бывает.

А если нужно чтобы не ограничивалось, не "проглатывалось" но висело сверху, это Owner.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 24.06.2007 (Вс) 13:55

Фишка в том, что они почти всегда мультиплексированы.
Например, GetParent для недочерних окон возвращает владельца.
Изображение

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 24.06.2007 (Вс) 13:57

Хакер писал(а):Если парент, то будет по-любому "проглатываться" и ограничиваться. По-другому не бывает.

А если нужно чтобы не ограничивалось, не "проглатывалось" но висело сверху, это Owner.


Я тоже об этом, но Owner разве не так устанавливается?
Код: Выделить всё
SetWindowLong(MyForm_hWnd, GWL_HWNDPARENT...
нет?

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 24.06.2007 (Вс) 15:21

Avtopic писал(а): но после нескольких переключении, перестаю реагировать иконки на панели задач. Их нажатие не вызывает активацию соответствующего MDI приложения
гуглом нашел еще две подобные темы, где у авторов такие же проблемы с иконками в тескбаре. они пишут, что иконки активируют соответствующие приложения только правым кликом. Проверил, у меня тоже реагирует только на правый клик.
К сожалению, там нет ответа.

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 25.06.2007 (Пн) 12:37

отказался от Owner/Owned варианта. Идея заманчивая, но имеет не устраивающие особенности.

Сделал все посредством прямого манипулирования окнами SetWindowPos, HWND_TOPMOST и т.д.

Осталось единственная проблема, никак не смог пройти, может, посоветуете:
как определить что окно последнее рабочее окно по отношению к десктопу.

Т.е. под окном (не только под RECT-ом окна, а в “слое”) по отношению к десктопу нет другого окна?

Спасибо!

Cytron
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 266
Зарегистрирован: 15.02.2007 (Чт) 21:09

Сообщение Cytron » 03.07.2007 (Вт) 19:39

кстати по теме, как поместить окно в самый низ ( В САМЫЙ НИЗ, под иконками рабочего стола) и сделать так, чтобы оно было неактивируемое. Оно развернуто на весь экран. В итоге получиться, что обои desktopа заменяться на твое окно.
мне именно так надо. и так чтобы explorer в коде не упоминался.
PS. explorer в тот момент запущен вообще не будет

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 03.07.2007 (Вт) 22:32

—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Cytron
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 266
Зарегистрирован: 15.02.2007 (Чт) 21:09

Сообщение Cytron » 04.07.2007 (Ср) 21:17

посмотрел, не то. там используется explorer, а он вырублен в момент запуска программы. :(


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот, SemrushBot, Yandex-бот и гости: 89

    TopList