Что нового

Окно поверх определённого окна

  • Автор темы VitAl2013
  • Дата начала
V

VitAl2013

Гость
А как сделать чтоб только поверх определённого окна?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
VitAl2013
а что значит поверх определенного окна?
если активно определенное окно (назовем его А) то требуемое (назовем его Б)должно быть поверх всех, а если не активно, то нет? если так, то могу предложить - проверять состояние окна А на активность, если активно то делать WinSetOnTop() окну Б, если же неактивно, то убирать WinSetOnTop() для Б
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
VitAl2013
У меня так получилось:
Код:
While 1
	If WinExists("Title 1") Then
		WinActivate("Title 2")
	EndIf
	Sleep(100)
WEnd

Окно "Title 2" уже существует.
 
Автор
V

VitAl2013

Гость
Kaster
То есть этот процесс должен постоянно монтировить комп на наличие окна А? Две параллельные функции? Нетли более изящного решения, вроде стиля, чтоб один раз указал выше какого окна находиться и всё? Может можно встроить своё окно (Б) в окно А? Или заменить стсус элемент окна программы на своё на время работы программы, такое возможно?

madmasles
Это значит постоянно переключать фокус на окно 2 пока есть окно 1. Это вообще рушит логику моей программы, получается Статус бар постоянно активен (а мне это не надо).

ЗЫ Это я стсус бар свой пытаюсь правильно пристроить.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
VitAl2013
а что в этом такого? на компе постоянно что-нибудь да мониторится. тут как с GUI. есть два метода реагирования на события. первое - постоянный мониторинг и при обнаружении чего-либо - определенные действия. либо никакого мониторинга, но само событие посылает сигналы при определенных действиях. если хочешь через второе - то тут надо копать в сторону WM_... сигналов. в них я не силен. почитай справку на эту тему. но в постоянном мониторинге я не вижу ничего плохого. если поставить пауза хотя бы в 100 мс, то никакого перегруза ресурсов не будет и в помине, если ты об этом беспокоишься.
 
Автор
V

VitAl2013

Гость
У меня вот так получилось:
Код:
If WinActive("А") Then
 WinSetOnTop("Б", "", 1)
EndIf
	
If WinActive("А")=0 Then
 WinSetOnTop("Б", "", 0)
EndIf


А вариант:
Код:
Switch WinActive("А")
		Case 1
			WinSetOnTop("Б", "", 1)
			
		Case 0
			WinSetOnTop("Б", "", 0)
	EndSwitch

работает некорректно. Както с задержкой по клику, несмотря на то что case система работает быстрее if.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Вот более изящный способ:

Код:
#Include <WinAPIEx.au3>

Opt('WinTitleMatchMode', 3)

Run('calc.exe')
If WinWaitActive('Calculator', '', 5) Then
	$hParent = WinGetHandle('Calculator')
Else
	Exit
EndIf

OnAutoItExitRegister('OnAutoItExit')

$hForm = GUICreate('')
GUIRegisterMsg(_WinAPI_RegisterWindowMessage('SHELLHOOK'), '_ShellHookProc')
_WinAPI_RegisterShellHookWindow($hForm)

Run('notepad.exe')

While 1
	Sleep(1000)
WEnd

Func _ShellHookProc($hWnd, $iMsg, $wParam, $lParam)
	Switch $hWnd
		Case $hForm
			Switch $wParam
				Case $HSHELL_WINDOWACTIVATED
					If WinGetTitle($lParam) = 'Untitled - Notepad' Then
						WinSetOnTop($hParent, '', 1)
					Else
						WinSetOnTop($hParent, '', 0)
					EndIf
			EndSwitch
	EndSwitch
EndFunc   ;==>_ShellHookProc

Func OnAutoItExit()
	_WinAPI_DeregisterShellHookWindow($hForm)
EndFunc   ;==>OnAutoItExit



Добавлено:
Сообщение автоматически объединено:

Но если это окно, созданное с помощью GUICreate(), то лучше использовать WM_ACTIVATE сообщение.
 
Автор
V

VitAl2013

Гость
Ругается:
...: ==> Duplicate function name.:
Func OnAutoItExit()
Что я не учёл при переносе-адаптации?
Это:
Код:
OnAutoItExitRegister('OnAutoItExit')

я внёс. И попробовал по разному.

Получается что калькулятор это папа записнушки? А наоборот как-то нельзя, точнее чтоб они были никто друг другу? Статус окно - дитё главного окна. Тоесть есть окно В которому Б приходится дочерним. Хотя с этими родственными связями я ещё не определился - могу сделать так чтоб это просто были 2 разные формы. Меня смущает что в моём случии окно А является дочерним к окну Б. Может я не так понял?... (спустя время) Я понял как избавиться от этого:
Код:
WinSetOnTop($hParent, '', 1)
заменить на:
Код:
WinSetOnTop("Б", '', 1)
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
OffTopic:
VitAl2013 [?]
...несмотря на то что case система работает быстрее if.
Эту тему уже обсуждали! Конструкция If ... Then ... EndIf лидирует по скорости выполнения среди других аналогичных! :smile:
Я все конструкции протестировал, по примеру Yashied `а, увы, факт есть факт!
 
Автор
V

VitAl2013

Гость
Что я не учёл при переносе-адаптации?
Я ещё использую вот такие инклюды, там эта функция есть?
Код:
#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <Process.au3>
#include <BlockInputEx.au3>
#Include <WinAPIEx.au3>
#include <GUIListView.au3>
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Значит у тебя AutoIt 3.3.0.0 или более ранний. Просто закомментируй эту строчку:

Код:
;OnAutoItExitRegister('OnAutoItExit')




Добавлено:
Сообщение автоматически объединено:

VitAl2013 сказал(а):
Это вообще рушит логику моей программы, получается Статус бар постоянно активен (а мне это не надо). Это я стсус бар свой пытаюсь правильно пристроить.
Опиши более подробно свою задачу, а то мы тебе сейчас такого насоветуем...

:smile:
 
Автор
V

VitAl2013

Гость
У меня есть autoit прогамма с окном В которая управляет не autoit (совсем не autoit, там проблемы с интерфейсом из Линукса, но это др. история) прогаммой с окном А выводя всё что она делает в статус окно Б Мне надо какимто образом закрепить статус окно Б за окном А так, чтобы оно действовало точно также как обычный статус бар окна А. Пример: выпрыгнуло окно "Сохранить как" - оно идёт поверх Б. Активировалось окно А, и Б тоже видно. По сути и получается что статус окно Б должно быть всегда поверх окна А и только него. Всё остальное должно возникать сверху.
 

edyapd

Осваивающий
Сообщения
380
Репутация
30
VitAl2013 сказал(а):
У меня есть autoit прогамма с окном В которая управляет не autoit (совсем не autoit, там проблемы с интерфейсом из Линукса, но это др. история) прогаммой с окном А выводя всё что она делает в статус окно Б Мне надо какимто образом закрепить статус окно за окном А так чтобы оно действовало точно также как обычный статус бар окна А. Тоесть выпрыгнуло окно "Сохранить как" - оно идёт поверх Б. Активировалось окно А, и Б тоже видно. По сути и получается что статус окноБ должно быть всегда поверх окна А и только него. Всё остальное должно возникать сверху.
Не знаю на сколько я тебя правильно понял, но из того что понял :smile:
Привяжи координаты окна Б к координатам окна А (где то на форуме было про пристыковку окон, я думаю там можно переделать и для наложения). Потом после активации окна А активируй окно Б. Оно у тебя и получится поверх А. Сорри если что то не так понял.
 
Автор
V

VitAl2013

Гость
Потом после активации окна А активируй окно Б.
А мне надо чтоб окно А было активно, я туда Send делаю потом. Еслиже будет окно Б, то послыка уйдёт не туда. ControlSend делать не могу так как уже писал выш интерфейс родом из Линукса. Там ничего не работает толком. Максимум габариты элементов могу вычислить. Указатели меняются даже если просто открыть ещё одно такоеже окно с программой. У обоих окон указательи (handle) изменятся. Только простой Send работает.
 

edyapd

Осваивающий
Сообщения
380
Репутация
30
То есть надо чтобы было активным окно А, но при этом окно Б было поверх него? :-X
Честно говоря я даже не уверен что такое может быть.
 
Автор
V

VitAl2013

Гость
Угу и только поверх него.

На счёт того что такого не может быть. Видеокарта как-то понимает какое окно за каким находится (А ещё она понимает какой элемент перекрывает какой, даже одного окна). И наверняка есть списочек, кто за кем. И както этот список изменяется. Может можно както в него врубиться? И наверняка даже в видеокарту лезть не понадобится. Список должен быть где-то на уровне ОС. Следовательно всякими WinAPI можно до него добраться. Ибо... ну както оно должно быть полюбому. :smile:

Мне кажется это хорошая такая темка для маленького такого UDF от гуру для негуру и себя.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Код:
#Include <Constants.au3>
#Include <GUIConstantsEx.au3>
#Include <WinAPIEx.au3>
#Include <WindowsConstants.au3>

Opt('OnExitFunc', '_AutoItExit')
Opt('WinTitleMatchMode', 3)
Opt('WinWaitDelay', 0)

$hForm = GUICreate('MyGUI', 400, 200)
GUISetState()

GUIRegisterMsg(_WinAPI_RegisterWindowMessage('SHELLHOOK'), '_ShellHookProc')
_WinAPI_RegisterShellHookWindow($hForm)

Run('notepad.exe')

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func _ShellHookProc($hWnd, $iMsg, $wParam, $lParam)

	Local $ExStyle

	Switch $hWnd
		Case $hForm
			Switch $wParam
				Case $HSHELL_WINDOWACTIVATED
					If BitAND(WinGetState('Untitled - Notepad'), 8) Then
						WinSetOnTop($hForm, '', 1)
					Else
						WinSetOnTop($hForm, '', 0)
						$ExStyle = _WinAPI_GetWindowLong($lParam, $GWL_EXSTYLE)
						WinSetOnTop($lParam, '', 1)
						If Not BitAND($ExStyle, $WS_EX_TOPMOST) Then
							WinSetOnTop($lParam, '', 0)
						EndIf
					EndIf
			EndSwitch
	EndSwitch
EndFunc   ;==>_ShellHookProc

Func _AutoItExit()
	_WinAPI_DeregisterShellHookWindow($hForm)
EndFunc   ;==>_AutoItExit



Добавлено:
Сообщение автоматически объединено:

VitAl2013 сказал(а):
Видеокарта как-то понимает какое окно за каким находится (А ещё она понимает какой элемент перекрывает какой, даже одного окна)...
Видеокарта тут вообще непричем.
 

edyapd

Осваивающий
Сообщения
380
Репутация
30
Единственный пример который я знаю: Диспетчер задач висит поверх окон даже тогда когда он не активен. Но есть одно но: Так как требуются МаусКлик и Сенд то все инпуты должны быть открыты. Иначе при маусклик по координатам где находится диспетчер задач его окно становится активным.
Я думаю, что гуру смогут подсказать какие свойства должны быть у окна чтобы оно даже в неактивном состоянии было поверх активного окна.

Пока набирал сообщение появился пример :smile:
 
Автор
V

VitAl2013

Гость
Yashied
Почи то что надо. Точнее так, задача поставленная в начале топика решена. Но у меня проблема вот где: вызываем пример, помещаем какое-либо окно так чтобы оно накладывалось (частично, чтоб эффект увидеть) на MyGUI, затем сворачиваем NotePad. MyGUI стоит на месте. Хотелось бы чтоб MyGUI делало тоже самое - сернулось, спряталось. Какбудто это часть Notepad. Может както добавить хук на сворачивание Notepad, чтоб тоже становилось на время активным. Когда просто сворачиваешь NotePad то MyGUI кудато девается (подозреваю что тоже сворачивается).
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
VitAl2013
OffTopic:
Я просто пытаюсь понять ход мыслей в написанной теме.
В общем ван нужно чтобы ваш статус бар (окно), был полный дубль окна основного скрипта, кроме содержимого конечно? Как двойник повторял все действия ведущего окна?
 
Верх