Автор Тема: Как отследить появление окна (IE например)?  (Прочитано 8829 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Ocago [?]

  • Новичок
  • *
  • Сообщений: 35
  • Репутация: 0
    • Награды
Доброго времени суток  :)
Где-то встречал тут тему с использованием оконного хука - но там был пример отслеживания события минимизации окна (любого приложения, в частности и IE)

А как несложными методами организовать отслеживание именно появления нового окна? Если известно только название приложения (ну, или ехе файл, его вызывающий).

Всем спасибо за любые идеи.
« Последнее редактирование: Август 01, 2010, 02:10:10 от Ocago »

Русское сообщество AutoIt

Как отследить появление окна (IE например)?
« Отправлен: Июль 31, 2010, 23:35:44 »

Оффлайн snoitaleR [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 854
  • Репутация: 222
  • Пол: Мужской
    • Награды
Ocago
Если нужно, чтобы скрипт ждал нужное окно, то потребуется функция WinWait()...
Если желательно, чтобы скрипт не приостанавливал работу, то можно использовать в цикле обработки сообщений вызов функции WinExists()...
Также потребуется утилита AU3INFO.EXE для определения характеристик окна, чтобы максимально точно его идентифицировать...
Главное в жизни человека - это отношение...

Оффлайн aranea [?]

  • Новичок
  • *
  • Сообщений: 27
  • Репутация: 4
    • Награды
Re: Как отследить появления окна (IE например)?
« Ответ #2, Отправлен: Август 01, 2010, 00:37:00 »
Цитировать
Если известно только название приложения
Я бы использовал
Код: AutoIt [Выделить]
ProcessWait("iexplore.exe")


Или если постоянно ожидать процесс, то вот пример взятый с форума, чей не помню
Код: AutoIt [Выделить]
Local $iPID
While 1
    $iPID = ProcessExists('iexplore.exe')
    If $iPID Then
        ; код че далать когда процесс появился
        ExitLoop
    EndIf
    Sleep(500)
WEnd


Оффлайн Ocago [?]

  • Новичок
  • *
  • Сообщений: 35

  • Автор темы
  • Репутация: 0
    • Награды
Re: Как отследить появления окна (IE например)?
« Ответ #3, Отправлен: Август 01, 2010, 00:56:04 »
Идея понятна вроде.. спасибо, попробую..

Тут правда нюанс - скажем, уже есть процесс рабочий iexplore.exe - и ожидаются новые (IE под каждое окно свой процесс открывает). Как тут быть?

Видимо там внутри цикла ожидания нужно массив организовывать? Чтобы при появлении каждого нового процесса, идентифицировать окно его по Hаndle и присваивать ему значение (WinSetState($hIEFrame, "", @SW_HIDE)).... как то так?

И этот цикл весь вначале скрипта вставлять?


Не слишком будет заморочено?
Я почему через события и подумал, что можно.. Событие - появление окна нового у этого процесса.
« Последнее редактирование: Август 01, 2010, 01:16:12 от Ocago »

Русское сообщество AutoIt

Re: Как отследить появления окна (IE например)?
« Ответ #3 Отправлен: Август 01, 2010, 00:56:04 »

Оффлайн snoitaleR [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 854
  • Репутация: 222
  • Пол: Мужской
    • Награды
Re: Как отследить появление окна (IE например)?
« Ответ #4, Отправлен: Август 01, 2010, 09:54:22 »
Ocago
Насколько я понял из эксперимента, который провел, IEXPLORE.EXE (версия 6) может создать новое окно без создания нового процесса, поэтому контроль только процессов не эффективен... Понадобится функция WinList() и класс окон IEXPLORE.EXE - IEFrame...

Код: AutoIt [Выделить]

; НАЧАЛО

 #Include <Array.au3>

 $W=WinList("[CLASS:IEFrame]")
 $N=Ubound($W)

 While True
  $W=WinList("[CLASS:IEFrame]")
  If Ubound($W)<>$N Then
   ;Изменилось количество окон
   $N=Ubound($W)
   _ArrayDisplay($W)
  EndIf
 WEnd

; КОНЕЦ

 


Оффлайн madmasles [?]

  • Глобальный модератор
  • *
  • Сообщений: 7790
  • Репутация: 2317
  • Пол: Мужской
  • Награды За модерирование форума
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Как отследить появление окна (IE например)?
« Ответ #5, Отправлен: Август 01, 2010, 11:17:40 »
Ocago
Можно еще так попробовать с проверкой разрешенной ссылки:
Код: AutoIt [Выделить]
#include <IE.au3>

Opt("TrayMenuMode", 1);не реагировать на щелчки мышкой по икноке в трее

HotKeySet("+{ESC}", "_Exit") ;Shift+Esc - выход по горячим клавишам
$sUrl = 'http://autoit-script.ru/' ;задаем адрес для проверки
_IECreate($sUrl) ;открываем в IE $sUrl
While 1 ;запускаем бесконечный цикл
    $aListIE = WinList('[Class:IEFrame]') ;получаем массив окон IE
    If $aListIE[0][0] > 1 Then ;если есть больше одного окна IE
        Dim $aListIE_Ex[1][3] ;создаем расширенный массив окон IE
        For $i = 1 To UBound($aListIE) - 1
            ReDim $aListIE_Ex[UBound($aListIE_Ex) + 1][3]
            $aListIE_Ex[$i][0] = $aListIE[$i][0] ;заголовок окна IE
            $aListIE_Ex[$i ][1] = $aListIE[$i][1] ;хэндл окна IE
            $oIE = _IEAttach($aListIE[$i][1], 'HWND')
            $aListIE_Ex[$i][2] = _IEPropertyGet($oIE, "locationurl") ;адрес окна IE
            If Not StringInStr($aListIE_Ex[$i][2], $sUrl) Then ;если в адресе нет строки $sUrl
                WinClose($aListIE_Ex[$i][1]) ; то закрываем это окно IE
                ;_IEQuit($oIE) ;так тоже можно закрыть
            EndIf
        Next
    EndIf
    Sleep(1000) ;задаем паузу между проверками в 1 секунду
WEnd

Func _Exit()
    Exit
EndFunc   ;==>_Exit


Оффлайн Ocago [?]

  • Новичок
  • *
  • Сообщений: 35

  • Автор темы
  • Репутация: 0
    • Награды
Re: Как отследить появление окна (IE например)?
« Ответ #6, Отправлен: Август 01, 2010, 14:47:05 »
Спасибо за примеры - сейчас буду пробовать  :)
Но, навскидку - везде требуются паузы и постоянное выполнение цикла, что не совсем хорошо видимо.
Пауза даст окну появится, "блымкнуть" хоть на секунду.
А постоянный цикл дополнительно озадачит процессор и память (наверное).

В идеале именно через хук решается вопрос. Вот этот скорее всего HSHELL_WINDOWCREATED.
Хуки-же как раз перехватывают события - и этот перехватит появление нового окна (и этому окну можно сразу установить параметры до его появления на экране). Но как эти хуки использовать? Что-то пока не вкурю.  :-\

Вот нашёл примерчик использования хука, но это отслеживание минимизации окна (любого) HSHELL_GETMINRECT - работает отлично.
Код: AutoIt [Выделить]
#NoTrayIcon
Opt("WinWaitDelay", 0)

;ShellHook notification codes:
Global Const $HSHELL_GETMINRECT = 5

;Hook stuff:
$aMsg = DllCall('user32.dll', 'int', 'RegisterWindowMessage', 'str', "SHELLHOOK")
GUIRegisterMsg($aMsg[0], "HShellWndProc")
GUIRegisterMsg($aMsg[0], "HShellWndProc2")
DllCall('user32.dll', 'int', 'RegisterShellHookWindow', 'hwnd', GUICreate(""))

While 1
    Sleep(1000)
WEnd

Func HShellWndProc($hWnd, $Msg, $wParam, $lParam)
    Switch $wParam
        Case $HSHELL_GETMINRECT
            Local $tSHELLHOOKINFO = DllStructCreate("hwnd hwnd;int left;long top;long right;long bottom", $lParam)
            Local $hWindow = HWnd(DllStructGetData($tSHELLHOOKINFO, "hwnd"))
           
            If BitAND(WinGetState($hWindow), 16) Then
                ToolTip('Minimized window event:' & @CRLF & @CRLF & _
                    'Window Handle: ' & $hWindow & @CRLF & _
                    'Window Title: ' & WinGetTitle($hWindow), _
                    0, 0, "HShellWndProc", 1)
               
                Sleep(5000)
                Exit
            EndIf
    EndSwitch
EndFunc
 


А вот как-бы что-то подобное с HSHELL_WINDOWCREATED сделать - может есть идеи или опыт у кого?
« Последнее редактирование: Август 01, 2010, 14:54:47 от Ocago »

Оффлайн snoitaleR [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 854
  • Репутация: 222
  • Пол: Мужской
    • Награды
Re: Как отследить появление окна (IE например)?
« Ответ #7, Отправлен: Август 01, 2010, 15:10:57 »
Примерчик с оффсайта от Yashied...

Русское сообщество AutoIt

Re: Как отследить появление окна (IE например)?
« Ответ #7 Отправлен: Август 01, 2010, 15:10:57 »

Оффлайн Ocago [?]

  • Новичок
  • *
  • Сообщений: 35

  • Автор темы
  • Репутация: 0
    • Награды
Re: Как отследить появление окна (IE например)?
« Ответ #8, Отправлен: Август 01, 2010, 15:19:41 »
спасибо, посмотрю сейчас..

А с циклами - точно не пойдёт, к сожалению - меньше 1 сек задержку нельзя ставить - не определяются параметры окна.. нестабильно работает.. А 1 сек - это окно показывается.
С такой задержкой и без циклов можно..


Добавлено: Август 01, 2010, 15:40:12
Примерчик с оффсайта от Yashied...

Кстати, таки да - это оно  :) Совсем близко.
Перехватывает сразу любое окно и выводит Title
Теперь-бы как-то там сразу умудриться задать параметры этому окну..
так-же через этот хук..  :-\
« Последнее редактирование: Август 01, 2010, 15:40:12 от Ocago, Причина: Объединение сообщений »

Оффлайн snoitaleR [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 854
  • Репутация: 222
  • Пол: Мужской
    • Награды
Re: Как отследить появление окна (IE например)?
« Ответ #9, Отправлен: Август 01, 2010, 15:54:20 »
Ocago
На сколько мне известно, не рекомендуется нагружать функцию обработки событий (сообщений) длительной работой, но установка параметров окна, думаю, достаточно быстрый процесс...

Оффлайн madmasles [?]

  • Глобальный модератор
  • *
  • Сообщений: 7790
  • Репутация: 2317
  • Пол: Мужской
  • Награды За модерирование форума
    • Награды
  • Версия AutoIt: 3.3.x.x
Ocago
Следующий скрипт у меня закрывает любое второе окно IE, при этом памяти кушает чуть больше 5 Мб, процессор не грузит совсем.
Код: AutoIt [Выделить]
Opt("TrayMenuMode", 1)

HotKeySet("+{ESC}", "_Exit") ;Shift+Esc - выход

While 1
    If WinExists('[Class:IEFrame]') Then
        $hHandleIE_First = WinGetHandle('[Class:IEFrame]')
    EndIf
    While 1
        If WinExists('[Class:IEFrame]') Then
            $hHandleIE_Next = WinGetHandle('[Class:IEFrame]')
            If $hHandleIE_Next <> $hHandleIE_First Then WinClose($hHandleIE_Next)
        Else
            ExitLoop
        EndIf
        Sleep(5)
    WEnd
    Sleep(5)
WEnd

Func _Exit()
    Exit
EndFunc   ;==>_Exit


Оффлайн Ocago [?]

  • Новичок
  • *
  • Сообщений: 35

  • Автор темы
  • Репутация: 0
    • Награды
Ocago
Следующий скрипт у меня закрывает любое второе окно IE, при этом памяти кушает чуть больше 5 Мб, процессор не грузит совсем.

ДА, действительно - Отслеживает и прикрывает второе окно. Небольшая нестабильность есть, если вторая старница открывается жабой (кликом по ссылке c обработкой window.open) - пишет ошибку жабы иногда.
Ну, и главный недостаток остался пока - окно "блымкает" (на долю секунды видно его).
А так в целом довольно универсальный вариант, спасибо  :) Я чуть подкорректировал под свои нужды  (окно в HIDE переходит, а не закрывается):
Код: AutoIt [Выделить]
Opt("TrayMenuMode", 1)

HotKeySet("+{ESC}", "_Exit") ;Shift+Esc - выход

While 1
    If WinExists('[Class:IEFrame]') Then
        $hHandleIE_First = WinGetHandle('[Class:IEFrame]')
    EndIf
    While 1
        If WinExists('[Class:IEFrame]') Then
            $hHandleIE_Next = WinGetHandle('[Class:IEFrame]')
            If $hHandleIE_Next <> $hHandleIE_First Then

            WinSetState($hHandleIE_Next, "", @SW_HIDE)

        Else
        ExitLoop
        EndIf
        Sleep(5)
    WEnd
    Sleep(5)
WEnd

Func _Exit()
    Exit
EndFunc   ;==>_Exit




Добавлено: Август 01, 2010, 17:23:04
А вот, кстати альтернатива, работающая через хук (спасибо snoitaleR за наводку):
Код: AutoIt [Выделить]
#Include <WinAPIEx.au3>

Opt('MustDeclareVars', 1)

Global $hForm

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

While 1
    Sleep(100)
WEnd

Func _ShellHookProc($hWnd, $iMsg, $wParam, $lParam)
    Switch $hWnd
        Case $hForm
            Switch $wParam
                Case $HSHELL_WINDOWCREATED
                   
                    WinSetState(WinGetTitle($lParam), "", @SW_HIDE)
                   
                    Local $Title = WinGetTitle($lParam)
                                        If IsString($Title) Then
                        ConsoleWrite('Activated: ' & $Title & @CR)
                    EndIf
                   
                   
            EndSwitch
    EndSwitch
EndFunc   ;==>_ShellHookProc

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


Не совсем ещё тут всё понятно, но WinSetState(WinGetTitle($lParam), "", @SW_HIDE) - отрабатывает очень быстро и любое окно, любой программы.
Всё равно "блымкает", конечно, но уж очень быстро.

Теперь-бы разобраться что тут поубирать лишнего и корректно закрывать после выполнения основной процедуры.  :wacko:

И может где-то тут указать можно ещё раньше параметры окна?
Если кто прокомментирует тут строки хотя-бы - огромное спасибо  :)
« Последнее редактирование: Август 01, 2010, 17:30:15 от Ocago, Причина: Объединение сообщений »

Русское сообщество AutoIt

Re: Как отследить появление окна (IE например)?
« Ответ #11 Отправлен: Август 01, 2010, 17:13:38 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
2 Ответов
3141 Просмотров
Последний ответ Февраль 24, 2010, 20:48:21
от Guezt Gutsy
7 Ответов
4391 Просмотров
Последний ответ Июль 16, 2010, 18:34:17
от tech-gs
4 Ответов
4107 Просмотров
Последний ответ Январь 07, 2011, 23:33:02
от CreatoR
5 Ответов
5164 Просмотров
Последний ответ Март 14, 2011, 17:28:27
от JayD
5 Ответов
4402 Просмотров
Последний ответ Февраль 29, 2012, 23:13:07
от madmasles
0 Ответов
1802 Просмотров
Последний ответ Февраль 29, 2012, 23:11:58
от madmasles
6 Ответов
1851 Просмотров
Последний ответ Июль 03, 2015, 11:25:12
от madmasles
4 Ответов
1781 Просмотров
Последний ответ Июль 30, 2015, 21:13:32
от Ksaan
1 Ответов
687 Просмотров
Последний ответ Июнь 23, 2017, 07:28:52
от pvnn
1 Ответов
392 Просмотров
Последний ответ Октябрь 12, 2018, 13:19:39
от hedji