eXeL@B —› Программирование —› Глобальный хук клавиатуры. Как избежать торможения обработки при подвисании? |
Посл.ответ | Сообщение |
|
Создано: 01 февраля 2010 20:45 · Личное сообщение · #1 Здравствуйте! Помогите найти решение проблемы. Суть в следующем: Есть некая программа которая запускает мою dll. По ходу работы программы я должен подсчитывать точное кол-во нажатий на определённую клавишу, например F9. Для этого решил использовать глобальный хук клавиатуры который отлавливает нажатия даже вне окна программы: hook:=SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardProc, HInstance, 0); Всё работает хорошо до тех пор, пока программа не задумывается при определённых действиях на пару секунд. В этот момент ловушка порождённая в dll которую подгружает основная программа – замирает… Я понимаю, что программа не должна жрать столько ресурсов, что всё начинает тормозить, но имеем то, что имеем. Провожу тест, небольшая программа на дельфи при загрузке устанавливает вышеописсаный хук и имеет кнопку которая делает Sleep(5000); Запускаю две копии, жму F9 –нажатия ловят обе. В первой тестовой программе нажимаю кнопку c паузой, она уже не ловит нажатия, вторая ловит. Теперь нажимаю паузу во второй копии – не ловят обе, это естественно, так как самый верхний по уровню обработчик – это обработчик установленный последним и естественно, что подвисая вторая копия не передаёт обработку по цепочке. Конечно, как выход можно делать хук во внешней программе и опрашивать её каким либо способом, либо банально создать поток который будет проверять нажатие через GetAsyncKeyState(vk_F9) каждые N миллисекунд, но прежде хочу спросить, может кто знает более красивое решение подобной ситуации (без написания драйвера )? Внешняя программа – неприлично и гиморно, поток – будет кушать и без того не хватающие ресурсы если проверять будет часто, либо пропустит нажатие если будет проверять реже... |
|
Создано: 01 февраля 2010 21:17 · Личное сообщение · #2 |
|
Создано: 01 февраля 2010 23:16 · Личное сообщение · #3 vptrlx пишет: но, может быть, поможет что-то вроде вызова SetWindowsHookEx из отдельного потока Пытаюсь, не срабатывает, видимо нужно правильно указать один из двух последних параметров функции. Блин, ну в той же длл в отдельном потоке GetAsyncKeyState отлично работает, не пойму почему хук замирает... |
|
Создано: 02 февраля 2010 03:23 · Личное сообщение · #4 ToBad пишет: отдельном потоке GetAsyncKeyState отлично работает Вру, в боевых условиях провалилось и это... Не стопорится совсем, но теряет нажатия... Складывается мнение, что нужно использовать SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardProc, HInstance, 0) в отдельном приложении и взаимодействовать с ним получая результат по мере необходимости. Вот вопрос какой, может быть можно насунуть этот хук другому приложению, тому же експлореру или винлогону, что бы торможения в ЕХЕ который использует длл не тормозили обработчик? Чушь конечно сказал, но очень нужны идеи и советы... |
|
Создано: 02 февраля 2010 04:45 · Личное сообщение · #5 ToBad Тебе нужно ловить нажатия по ф9 в программе, или во всей системе при работе твоей программы? Если нужно считать нажатия клавиш только в окне твоей программы то причем тут вообще хуки виндовс?? Если же нужны все нажатия, в системе, определенной клавиши(даже не в твоем окне) при работе твоей программы, то сделай, к примеру, свой сервис (суть, отдельный процесс) и уже в нем считай нажатия хуками. Если не понятно, то дай краткое описание чего конкретно тебе нужно, а то не совсем улавливаецо |
|
Создано: 02 февраля 2010 06:13 · Личное сообщение · #6 ToBad Шадов доставляет сообщения в контексте вызывающего его потока. Вы должны отдать управление на NtUserGetMessage/GetMessage(), тогда шадов вызывет свой калбэк для доставки сообщения(apfnDispatch[fnHkINLPMSG]), а далее после возврата в шадов из калбэка произойдёт возврат из сервиса. Зависает потомучто поток висит выполняя некоторые действия, это не допустимо. Следует отвести для обработки оконных сообщений отдельный не загруженный поток. |
|
Создано: 02 февраля 2010 06:20 · Личное сообщение · #7 |
|
Создано: 02 февраля 2010 19:50 · Личное сообщение · #8 |
|
Создано: 03 февраля 2010 01:15 · Личное сообщение · #9 |
|
Создано: 03 февраля 2010 02:51 · Личное сообщение · #10 |
|
Создано: 04 февраля 2010 01:40 · Личное сообщение · #11 |
|
Создано: 04 февраля 2010 01:50 · Личное сообщение · #12 |
|
Создано: 04 февраля 2010 02:03 · Личное сообщение · #13 |
|
Создано: 04 февраля 2010 02:15 · Личное сообщение · #14 |
|
Создано: 04 февраля 2010 02:58 · Личное сообщение · #15 |
|
Создано: 04 февраля 2010 19:19 · Поправил: ToBad · Личное сообщение · #16 Простите конечно, вижу что уже напряг всех своим не пониманием, но знаете, бывает так с возрастом, вроде для всех очевидные вещи, а не доходит... n0name пишет: скорее всего вполне достаточно GetMessage() в цикле крутить в отдельном потоке. Clerk пишет: Нужно не в ней вращаться, а в GetMessage(), сказали ведь В смысле так?: Code:
Делал и в длл с хуком которую подгружал, и когда в приложении реализовывал хук, и в отдельном потоке, всё равно тормозится... Реализовал хук в отдельной длл, подгружаю через loadlibrary - работает но тормозится, решил подгрузить другому процессу через InjectDll (библиотека advApiHook от MS-Rem), инжектил к блокноту, хук вообще не работает... хз, что за невезуха... |
eXeL@B —› Программирование —› Глобальный хук клавиатуры. Как избежать торможения обработки при подвисании? |