Форум программистов, компьютерный форум, киберфорум
Delphi: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.74/19: Рейтинг темы: голосов - 19, средняя оценка - 4.74
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 10

Глобальный Хук на клавиатуру и MessageDlg

05.02.2013, 21:24. Показов 3805. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте Уважаемые Знатоки! Недавно возникла задача отлавливать нажатые клавиши на клавиатуре во всей Винде, определить скорость, если скорость выше n то проверять на ключевые слова и если всё устраивает то вывести Месседж диалог на экран с набранным текстом... От использывания Хуков с .dll принципиально отказался и накалякал данную функцию:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
function HookProc(Code: integer; WParam: word; LParam: Longint): Longint; stdcall;
var
msg: PEVENTMSG;
s, a: string;
begin
if Code >= 0 then begin
   result := 0;
   msg := Pointer(LParam);
   with Form1 do begin
     if msg.message = WM_KEYUP then         // WM_KEYUP для предотвращения залипания клавиш
     begin
       s:= GetStrbyKey(PEVENTMSG(lParam)^); // Преобразование нажатых клавиш в нормальный вид
       label8.Caption:= s;
       Label4.Caption:= Inttostr(Skorost());
       if Skorost() >= 50 then
       begin
         memo1.Text:=memo1.Text + s;
         if Length(memo1.Text) >= 10 then
         begin
          Application.Restore;
           a:= memo1.Text;
           label1.Caption:= a;
           MessageDlg(a, mtInformation, [mbOk], 0); // <== ВОТ ТУТ ЧТО-ТО НЕ ТО!
           memo1.Clear;
         end;
       end else
       begin
         memo1.Clear;
         memo1.Text:= s;
       end;
     end;
   end; //with
end else
   result := CallNextHookEx(HookHandle, code, WParam, LParam);
end;
Так вот, определение скорости, ключевых слов и длину это не проблема, и всё вроде-бы нормально пока код не доходит до строки с
Code
1
MessageDlg(a, mtInformation, [mbOk], 0);
вот тогда начинаются зависание приложения где в последний раз набирался текст или всей системы в целом... Можно-ли как нибудь исправить данную функцию так чтобы Виндовс безболезненно выдавала Диалоги?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
05.02.2013, 21:24
Ответы с готовыми решениями:

Глобальный хук на клавиатуру и мышь без dll
Все пытаюсь определить время простоя системы, ни один из вариантов не работате на 64 битной системе, НО удалось поставить хуки на мышь и...

Глобальный хук на клавиатуру
unit HookForm; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,...

Глобальный хук на определённую клавиатуру
Пишу сюда, из-за отчаяния. Честно просидел в гугле 3 дня, но не нашел нужного решения. Задача: Есть считыватель карточек (rfid...

14
Пишу на Delphi...иногда
 Аватар для cotseec
1423 / 1278 / 286
Регистрация: 03.12.2012
Сообщений: 3,914
Записей в блоге: 5
05.02.2013, 21:40
Цитата Сообщение от msanorin Посмотреть сообщение
Delphi
1
MessageDlg(a, mtInformation, [mbOk], 0);
останавливает поток приложения, который вызвал этот диалог, до реакции пользователя на диалог. вариантов несколько, не очень замечательных:
отдать вывод диалогов отдельному потоку - что есть не очень хорошо, даже очень нехорошо (вывод какого-либо мессаджа в потоке при неправильной синхронизации может караться....)
отдать вывод мессаджа какому-либо приложению, которое по какому-либо сообщению выводит месадж

только зачем вам выводить диалог из хука? в сети полно примеров, когда все пишется в файл и парсится на предмет интересующей информации.
1
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
05.02.2013, 21:41
Цитата Сообщение от msanorin Посмотреть сообщение
От использывания Хуков с .dll принципиально отказался и накалякал
.. не понимая при этом в принципе что "накалякал".
0
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 10
06.02.2013, 08:40  [ТС]
Цитата Сообщение от cotseec Посмотреть сообщение
только зачем вам выводить диалог из хука? в сети полно примеров, когда все пишется в файл и парсится на предмет интересующей информации.
Спасибо за быстрый ответ, думаю всё таки использовать библиотеки и с них потом ловить и обрабатывать сообщения... только как потом обрабатывать глобально событие WM_KEYUP для определения скорости понятия не имею ((

Цитата Сообщение от mss Посмотреть сообщение
.. не понимая при этом в принципе что "накалякал".
надеюсь программы писать у Вас получается не хуже чем тролить... Удачи Вам!
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
06.02.2013, 11:40
Цитата Сообщение от msanorin Посмотреть сообщение
программы писать у Вас получается не хуже
По сей день меня это не огорчало)

Ты вдумайся в то что ты сказал:

Цитата Сообщение от msanorin Посмотреть сообщение
От использывания Хуков с .dll принципиально отказался
Это говорит о том что ты устанавливаешь именно хук WH_KEYBOARD_LL, ибо любой иной (за исключением WH_MOUSE_LL) требует его организации не иначе как в dll.

Раз ты ставишь низкоуровневый хук, то он будет реагировать на любые клавиатурные события безотносительно контекста, в котором они происходят.
То есть :

1. при старте диалога MessageDlg эти события точно так же будут возбуждаться, приводя при этом к вызову твоего колбэка

2. В колбеке "дело доходит" до MessageDlg, при этом goto п.1

И получается старая песня про "У попа была собака.." - бесконечный замкнутый рекурсивный цикл, рано или поздно приводящий минимум к переполнению стека и краху процесса.

Вот собственно это ты и "накалякал".
1
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 10
06.02.2013, 12:44  [ТС]
Цитата Сообщение от mss Посмотреть сообщение
Вот собственно это ты и "накалякал".
не подскажете а как еще можно отлавливать событие WM_KEYUP для последующей "безболезненной" обработки?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
06.02.2013, 12:53
Да вот прямо так и отлавливать)
А "безболезненность" обработки - это уже алгоритмически регулироваться должно тобой.
Что мешает взводить какой-либо флаг перед вызовом диалога и сбрасывать его по закрытитию этого диалога, и перед вызовом диалога проверять состояние флага для принятия решения о возможности вызова диалога ?
0
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 10
06.02.2013, 14:11  [ТС]
Цитата Сообщение от mss Посмотреть сообщение
Что мешает взводить какой-либо флаг перед вызовом диалога и сбрасывать его по закрытитию этого диалога, и перед вызовом диалога проверять состояние флага для принятия решения о возможности вызова диалога ?
значит кроме строки с диалогом (MessageDlg) в функции что выше почти всё правильно? А можно пример или по подробней на счет флагов?

Добавлено через 16 минут
перевел диалог на Таймер с Интервалом =1, если в хуке условия совпадают таймер включается, в обработчике таймера таймер выключается, выполняется диалог и другие процедуры... вроде всё отлично работает!
Только у меня возник еще один вопрос: ЭТО НЕ ИЗВРАТ? Вы как профессионалы тоже иногда так делаете?????
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
06.02.2013, 14:32
Цитата Сообщение от msanorin Посмотреть сообщение
по подробней на счет флагов
Что не понятно ?
0
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 10
06.02.2013, 15:20  [ТС]
Цитата Сообщение от mss Посмотреть сообщение
Что не понятно ?
почти всё, с флагами не работал (
а на счёт таймера это правильно? или и тут есть подводные камни?
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
06.02.2013, 15:42
Цитата Сообщение от msanorin Посмотреть сообщение
с флагами не работал
Флаг - это попросту переменная булева типа.

Цитата Сообщение от msanorin Посмотреть сообщение
на счёт таймера это правильно?
А без таймера скорость чего-либо (неважно чего) измерить невозможно в принципе.
0
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 10
06.02.2013, 15:57  [ТС]
Цитата Сообщение от mss Посмотреть сообщение
Флаг - это попросту переменная булева типа.
дошло ))

Цитата Сообщение от mss Посмотреть сообщение
А без таймера скорость чего-либо (неважно чего) измерить невозможно в принципе.
теперь значит будет 2 таймера в приложении)))
Спасибо!
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
06.02.2013, 16:00
Цитата Сообщение от msanorin Посмотреть сообщение
будет 2 таймера
Всегда можно обойтись одним.
0
0 / 0 / 0
Регистрация: 03.11.2012
Сообщений: 10
11.02.2013, 10:43  [ТС]
Все таки решился использовать dll для хука, только пожалуйста помогите разобраться в данном коде, не могу его переделать чтоб хук реагировал только при отпускании клавиши:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function KeyHookFunc(Code, VirtualKey, KeyStroke: integer): LRESULT; stdcall;
var
  msgl: PEVENTMSG;
begin
  Result:=0;
  if Code=HC_NOREMOVE then Exit;
  Result:=CallNextHookEx(hK,Code,VirtualKey,KeyStroke);
  if Code<0 then Exit;
  if (Code=HC_ACTION) then
  begin
    msgl := Pointer(KeyStroke);     // Без этих двух строчек функция работает
    if msgl.message = WM_KEYUP then // идеальною, но надо чтоб хук реагировал только
    begin                           // на отпускание клавиш. П О М О Г И Т Е !
      if((KeyStroke and (1 shl 30))<>0) then
      if not IsWindow(hA) then
      begin
        hM:=OpenFileMapping(FILE_MAP_WRITE,False,'MyHookMap');
        Hr:=MapViewOfFile(hM,FILE_MAP_WRITE,0,0,0);
        if Hr<>nil then
          hA:=Hr.AppHnd;
      end;
      if ((KeyStroke and (1 shl 30))<>0) then
      begin
        SendMessage(hA, WM_USER+2008, VirtualKey ,  KeyStroke {GetFocus});
      end;
    end;
  end;
end;
Добавлено через 15 часов 27 минут
Всем спасибо! Разобрался! Условие
Delphi
1
if (KeyStroke and $80000000 <> 0) then
и есть ответ на мой вопрос!
0
844 / 739 / 342
Регистрация: 22.09.2012
Сообщений: 5,034
06.04.2013, 16:17
Я так понял этот Хук ни на цент так и н заработал? Стоит ли пробовать этот код?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.04.2013, 16:17
Помогаю со студенческими работами здесь

Глобальный "ХУК" на клавиатуру
в общем мне нужно создать Глобальный хук чтобы клавиши отлавливались везде деже если программа в трее!я слышал что нужно создать DLL'ку но...

глобальный хук
помогите с программой(с какой стороны начинать) : нужно что бы работала как глобальный хук - в любой папке выбрав файл и нажав клавишу...

Глобальный хук
Всем доброго времени суток! Помогите написать глобальный хук и функцию для него, чтобы перехватывал вводимый текст с клавиатуры и писал в...

Глобальный хук на CreateProcess
требуется отслеживать запуск некоторых приложений и прибивать их при запуске, подскажите как реализовать чую полез в дремучий лес , если не...

Глобальный хук клавиатуры
Привет. Мне нужно сделать глобальный хук клавиатуры, но я не знаю как. В интернете примеров на C++ мало и все не работают, потому что люди...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru