KeyHook в другой теме

77
6

В моем приложении С# я хочу сделать keyhook, но так, что метод, вызываемый при нажатии клавиши, вызывается в другом потоке. Таким образом, этого не произойдет, что моя программа не указана, потому что мое приложение было занято чем-то другим. Как я могу сделать это в другом потоке? Я нашел информацию, что в зависимости от потока, в котором я создаю hook, метод, вызываемый при нажатии клавиши, будет вызываться в этом потоке, но этого не происходит. Независимо от потока, в котором я его подключил, этот метод всегда вызывается в основном потоке. Пожалуйста помоги. Это схема моего кода:

int HookProc(int code, int wParam, ref lParamStruct lParam)
{
// ... this should be invoked in another thread - thread th, which I use to call SetWindowsHook
}
void SetWindowsHook()
{
lpMsg msg = new lpMsg();

PeekMessage(out msg, new IntPtr(0), 0, 0, PM_NOREMOVE);

hhook = SetWindowsHookEx(WH_KEYBOARD_LL, HookProc, new IntPtr(0), 0);

while (GetMessage(out msg, new IntPtr(0), 0, 0))
{
DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
if (abortThreadFlag)
break;

}
UnhookWindowsHookEx(hhook);
}

SetWindowsHook вызывается таким образом, но id не заставляет метод вызываться в другом потоке:

 Thread th = new Thread(SetWindowsHook);
th.Start()

спросил(а) 2021-01-19T15:05:21+03:00 6 месяцев, 1 неделя назад
1
Решение
78

Точка цикла сообщения - дать Windows возможность вызвать вашу процедуру hook. Другого способа назвать код нельзя. Он не может взломать и заставить ваш поток запускать код, что может вызвать ужасные проблемы с повторным подключением. Процедура hook может выполняться только тогда, когда ваш код вызывает GetMessage(). И будет работать в контексте этого потока. Вы можете проверить это, посмотрев на возвращаемое значение GetCurrentThreadId().

Использование нити в противном случае не является фиксированной для медленной процедуры крючка. Windows не будет отправлять какие-либо другие события ввода до тех пор, пока процедура hook не вернется. Сделайте его достаточно медленным, и Windows будет убивать крюк принудительно для восстановления. Подумайте, вместо этого используйте рабочий поток, который вы кормите из потоковой очереди, что позволяет быстро вернуться к процедуре захвата.

ответил(а) 2021-01-19T15:05:21+03:00 6 месяцев, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема