Что нового

Управление хуком окон и объектов

musicstashall

Знающий
Сообщения
322
Репутация
7
Всем доброго.

Неожиданно столкнулся с проблемой переполнения очереди сообщений от хука. Как решить — не знаю. Хуки используются от очень частых событий, таких как $EVENT_OBJECT_CREATE и иногда, при сильном заполнении, виснет даже рабочий стол. Недопустимо. Мне нужны события только от ряда классов объектов, указанных в переменной $_jData, все прочие не интересуют. Если б можно было как-то пропускать или отменять хуки, не знаю. Подскажите пажалста. Реализовано таким способом:

Код:
#include <WinAPISys.au3>
#include <WinAPISysWin.au3>

OnAutoItExitRegister('OnAutoItExit')

Global $_jData = 'tooltips_class32|ViewControlClass|DropDown|ComboLBox|Net UI Tool Window|Net UI Tool Window Layered'

Global $hEventProc = DllCallbackRegister('WM_SYSHOOK', 'none', 'ptr;dword;hwnd;long;long;dword;dword')
Global $hEventHook = _WinAPI_SetWinEventHook($EVENT_OBJECT_CREATE, $EVENT_OBJECT_SHOW, DllCallbackGetPtr($hEventProc))

While 1
    Sleep(300)
WEnd

Func WM_SYSHOOK($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime)
   Local $iClass = _WinAPI_GetClassName($hWnd)
   ConsoleWrite('+ hWnd: ' & $hWnd & ', Class: ' & $iClass & @CR)
   If StringInStr($_jData, $iClass) Then
	  ; выполняем действие

	EndIf
EndFunc


Func OnAutoItExit()
    _WinAPI_UnhookWinEvent($hEventHook)
    DllCallbackFree($hEventProc)
EndFunc
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
именно с этим кодом виснет рабочий стол? через какой время? пользователь что-то делает в это время?
запустил, все работает нормально
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Виснуть начинает, когда события возникают. Например, когда я запускаю FireFox с многими вкладками. Виснет как сам браузер, так и рабочий стол. Такое случается только при работающем скрипте.

Есть еще другая неприятная проблема, связанная с этими хуками, — когда открывается контекстное меню с большим количеством объектов. Такое переполненное всяким хламом контекстное меню. Таким образом получается большая задержка события открывшегося меню ($EVENT_SYSTEM_MENUPOPUPSTART), потому что события $EVENT_OBJECT_CREATE сообщаются в приоритете. Но здесь я решил «конем» — просто получаю хуки от контекстных меню в отдельном скрипте.

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

Этот код из моего приложения BlackWindowManager, ты его пробовал уже. Хуки работают в скрипте Host Event For GUI
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
я хотел уточнить - вот этот код-пример тоже вешает рабочий стол или только в общем коде?


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

что с потреблением памяти и загруженности процессора в момент бага?
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Код в скрипте точно такой же. Точнее, там три вида хуков регистрируются. Один — это простой оконный хук _WinAPI_RegisterShellHookWindow, два других — это _WinAPI_SetWinEventHook. Последние два просто настроены на разные диапазоны событий. Первый из них работает в диапазоне от $EVENT_Min до $EVENT_SYSTEM_DESKTOPSWITCH, второй настроен на самые частые события от $EVENT_OBJECT_CREATE до $EVENT_OBJECT_SHOW, который и представлен в примере этой темы. Проблемы начались как раз тогда, когда я подключил последний.

Да, проверил сейчас, виснет наглухо, пока не перезапустится. При работающем скрипте (x64) открываю свой FireFox и, пока он грузится, играюсь с рабочим столом — открываю контекстные меню или вплывающие подсказки.... После того, как кликнул правой кнопкой мыши, всё зависло.



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

Без скрипта, и браузер загружается в разы быстрее.
Да, заметил сейчас, что это FireFox так торможения вызывает, но скрипт это дело всё сильно усугубляет и затягивает во времени.


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

При старте FireFox занимает 4500 мб памяти из 6000. ЦП до 100 скачет. Скрипт почти не потребляет ни памяти, ни процесса


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

Получается, что баг возникает на пределе, при нехватке памяти. С этим понятно. Но влияние работы скрипта на данную ситуацию мне не нравится.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
у себя один раз такое наблюдал. лиса съел 1,5 гига при открытии пяти вкладок и запущенном коде. потом несколько раз запускал подобного не было. что при работающем коде, что без него лиса ела до 1г200мб при открытии пяти вкладок, потом выравнивалось около 900 мб(прожорливый браузер). Лиса обновляется постоянно. система вынь 10
проц напрягался максимум до 70%(амд 4 ядра), при загрузке содержимого
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
У меня 54 вкладки :laugh:
Ладно, это можно проигнорировать. У меня остается вопрос — как фильтровать хуки, чтобы не нагружать без необходимости скрипт.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Сдается мне, что основной баг(99,9%), дает лиса. Скрипт тут ни при чем, ибо 54 вкладки это перебор. Походу, браузер сам с собой не справляется. Какое железо на компе?
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
ЦП i5
RAM 6000mb

Ну я готов согласиться, что это лиса вызывает, а как тогда быть в случае с событиями контекстных меню $EVENT_SYSTEM_MENUPOPUPSTART? Когда меню захламлено, то получается задержка в секунд 7-9. Задержку вызывают события $EVENT_OBJECT_CREATE. Как разрулить? (И мне кажется, что эти же самые события, совместно с лисой, и тормозят комп.)
 

mihmig

Новичок
Сообщения
4
Репутация
0
Решил воспользоваться Вашим скриптом для отлова создания и закрытия надоедливых всплывающих окон одного ПО.
Подскажите, а как получить заголовок окна? Дело в том что закрывать нужно окна с определённым заголовком, не классом.
В файле WinAPISysInternals.au3 не нашёл функции, которая бы позволила получить заголовок (Title)...
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
Попробуйте получить информацию об окне используя "AutoIt Window Info"
 

mihmig

Новичок
Сообщения
4
Репутация
0
Попробуйте получить информацию об окне используя "AutoIt Window Info"
Эту информацию я получаю, и заголовок требуемого мне окна известен. Но мне нужно получить заголовок создаваемого(или созданного?) окна в оммент срабатывания хука, вот в чём проблема...
 
Верх