Перейти к содержанию
Fire Monkey от А до Я
  • 0

Проблемы с хуком WH_KEYBOARD_LL + PeekMessage/GetMessage


neo

Вопрос

Ребята здарова!
выручайте) весь уже измучился =( не получается =(

Тема такая, работаю с хуком, использую WH_KEYBOARD_LL
тк нужно работать и с 32 битной и 64 битной разрядностью.
и вообще мне нравится с ним работать всё очень просто и удобно но появилось одно НО =(

WH_KEYBOARD_LL работает до добавления сообщения в очередь в контексте потока.

и это действительно так =(

дело в том что я через хук ловлю введённую информацию и потом обрабатываю это через
idHTTP (ищу в интернете ответ)... если сигнал хороший то всё круть... а когда связь не очень..
и происходят небольшие задержки..
как я понимаю в WH_KEYBOARD_LL складируются результаты которые он не может передать
и затем хук выбивается... тоесть чтобы всё вновь заработало нужно сделать так
 
KeyboardHandle:=SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardHook, HInstance, 0);

и хук по прежнему работает до тех пор пока не вылетит вновь.

Чтобы решить эту проблему как я понял нужно использовать PeekMessage или GetMessage
и удалять излишки... Но в сети очень мало информации о том как ими пользоваться я не понимаю
куда и как их вставлять.
Я делал вот так... писал в ДЛЛке

function KeyboardHook(code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
msg:TMsg;
begin
 if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then exit;

 if code>=0 then
  begin
    if (wParam=WM_KEYDOWN) then
    begin

    SendMessage(FindWindow('TForm1', 'Form1'), KeyboardEvent, 0,PBDLLHOOKSTRUCT(lParam).vkCode);

    end;
  end;
  Result:=CallNextHookEx(KeyboardHandle, code, wParam, lParam)

end;
// if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then exit;
// типа если есть излишки выходи


так же вставлял там это:
    while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
    begin
        TranslateMessage(Msg);
        DispatchMessage(Msg);
      end;

но не помогает =(

Может это где-то в ЕХЕшнике нужно вставлять? я не понимаю как с ним работать =(
Может кто на форуме знает? помогите пожалуйста ответом

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

PeekMessage - бессмысленно и даже вредно с флагом PM_REMOVE. Убрать.

SendMessage - эта функция отправляет данные окну и дожидается, пока окно их обработает. А хук ждать не должен, его задача - максимально быстро отработать. Заменить на PostMessage.

длл здесь не нужна. LL-хуки работают из любого места. Просто перенести весь код в exe.

 

Изменено пользователем kami
Ссылка на комментарий
  • 0
5 часов назад, kami сказал:

PeekMessage - бессмысленно и даже вредно с флагом PM_REMOVE. Убрать.

SendMessage - эта функция отправляет данные окну и дожидается, пока окно их обработает. А хук ждать не должен, его задача - максимально быстро отработать. Заменить на PostMessage.

длл здесь не нужна. LL-хуки работают из любого места. Просто перенести весь код в exe.

 

да уже пробовал в ехе делать но всё также...пост тоже пробовал но всё криво тогда работает... неправильно ответы приходят... там в любом случае должна быть небольшая синхронизации тк нужно дожидаться ответа от idHTTP

пробовал даже через таймер и отдельный поток но всё не так качественно работает как через SendMEssage... вот вроде решение этой проблемы на Си но я его не понимаю =(

#include "stdafx.h"
#include <windows.h>
     
LRESULT CALLBACK LLKeyProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if(nCode <= 0)
    {
        if(wParam == WM_KEYDOWN)
            keybd_event( 0x41, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0 );
 
        return 1;
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}
     
int main()
{
    HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, LLKeyProc, GetModuleHandle(NULL), 0);
    if(hook)
    {
        while(WaitMessage())
        {
            MSG msg = {0};
            while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                if(msg.message == WM_QUIT)
                {
                    UnhookWindowsHookEx(hook);
                    return 0;
                }
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    }
    return 0;
}

кстати Подскажите... а как узнать что
 KeyboardHandle:=SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardHook, HInstance, 0); - слетел?
я думал что хендл должен стать 0 но он не меняется =(

также я писал в основной функции lastError:=GetLastError;

но после того как она слетает lastError так и остаётся 0 =(
вот как получить код этой моей ошибки??? =( 

через try except тоже выявить ошибку не получается =(

так бы я на таймер просто повесил: если слетел -подгрузи снова

 

Ссылка на комментарий
  • 0
6 часов назад, neo сказал:

всё криво тогда работает

Исчерпывающее описание проблемы.

6 часов назад, neo сказал:

там в любом случае должна быть небольшая синхронизации тк нужно дожидаться ответа от idHTTP

Вам сама операционная система говорит - нельзя так делать, вы тормозите ВСЁ что только можно, в результате ваш хук признается вредоносным и исключается из цепочки. Но вы упорный...

Ждите ответа. Но в своем коде, а не в хуке. А в свой код передавайте данные асинхронно, через тот же postMessage

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...