![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Зависание меню после установки хука [D5, Win2k]
Новичок © (2009-03-25 11:13:00)Добрый день.
Пожалуйста помогите разобраться с хуками. Ситуация такая: устанавливаю локальный хук на мышь и клавиатуру в MDI приложении. Задачей хука является отсылка уведомления в главное окно. При попытке выбрать мышкойпункт выпадающего меню, не главного!, а, например, "Главное->Файл->Открыть", приложение замерзает. Более того, ощутимо начинает тормозить система пока не срубишь это приложение. Проблема решается заменой PostMessage в коде хука на SendMessage. Причем проблема не возникает если выбирать меню с клавиатуры! Не могли бы Вы объяснить причину происходящего?!
implementation
....
var
KbrdInputHook: HHOOK = 0;
MouseInputHook: HHOOK = 0;
function KbrdHookProc(code: integer; wparam: WPARAM; lparam: LPARAM): LRESULT; stdcall;
begin
Result:= CallNextHookEx(KbrdInputHook, code, wparam, lparam);
if code >= 0 then
begin
PostMessage(Application.MainForm.Handle, FRX_IDLE_USER_INPUT, 0, 0);
end;
end;
function MouseHookProc(code: integer; wparam: WPARAM; lparam: LPARAM): LRESULT; stdcall;
begin
Result:= CallNextHookEx(MouseInputHook, code, wparam, lparam);
if code >= 0 then
begin
PostMessage(Application.MainForm.Handle, FRX_IDLE_USER_INPUT, 0, 0);
end;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
KbrdInputHook:= SetWindowsHookEx(WH_KEYBOARD, @KbrdHookProc, 0, MainThreadID);
MouseInputHook:= SetWindowsHookEx(WH_MOUSE, @MouseHookProc, 0, MainThreadID);
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
if KbrdInputHook <>0 then UnhookWindowsHookEx(KbrdInputHook);
if MouseInputHook <> 0 then UnhookWindowsHookEx(MouseInputHook);
end;
Сергей М. (2009-03-25 13:06:00) [1]
> все равно не понял
Windows вызывает хук WH_KEYBOARD/WH_MOUSE с кодом HC_NOREMOVE, когда клавиатурное/мышиное сообщение не удаляется из очереди, потому что приложение вызвало функцию PeekMessage с параметром PM_NOREMOVE.
Новичок (2009-03-25 12:54:00) [2]Насчет бесцельного тыканья мышью - вопрос десятый. Я потом напишу необходимые проверки. Это просто демонстрационный пример.
Спасибо за ссылку. По тексту все равно не понял, почему мой PostMessage вгоняет систему в ступор.
Сергей М. (2009-03-25 12:36:00) [3]
> доступно объяснить суть происходящего
https://wasm.ru/forum/viewtopic.php?id=12047
> отследить отсутствие клавиатурно/мышиного ввода от пользователя
А если юзер просто тупо бесцельно елозит мышью, это разве не считается мышиным вводом ?
Новичок (2009-03-25 12:21:00) [4]Обработка действия по пункту меню здесь абсолютно не при чем. Просто возникает проблема с меню при установленом хуке. Задача заключается в том, чтобы отследить отсутствие клавиатурно/мышиного ввода от пользователя.
Удалось найти решение!
В процедуре условие
if code >= 0 then
begin
PostMessage(Application.MainForm.Handle, FRX_IDLE_USER_INPUT, 0, 0);
end;
изменяется на
if code = HC_ACTION then
begin
PostMessage(Application.MainForm.Handle, FRX_IDLE_USER_INPUT, 0, 0);
end;
и все работает!!!
Просто получается так, что если в момент прихода code = HC_NOREMOVE отправлять PostMessage.. то приложение попадает в мертвую петлю. В общем, решение вроде как найдено, но основного вопроса это не снимает:
Не могли бы Уважаемые Мастера доступно объяснить суть происходящего? Спасибо за внимание.
Сергей М. (2009-03-25 12:04:00) [5]Не понятна сама затея с хуком ..
Если хук устанавливается на основной поток процесса своего собственногоприложения, то что мешает вместо этого просто обрабатывать событие выбора пункта интересующего меню или событие выполнения акции, ассоциированной с этим пунктом меню ?