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

WH_KEYBOARD_LL Хук, русские буквы из чужого окна


neo

Вопрос

Всем привет!
Перехватываю нажатия клавиш... но к сожалению не получается перехватить буквы с разной раскладкой =(

если печатаю в своём же окне то всё ок!
делаю это так:

 

  SC := MapVirtualKey(PBDLLHOOKSTRUCT(lParam).vkCode, MAPVK_VK_TO_VSC);
  VK := MapVirtualKey(PBDLLHOOKSTRUCT(lParam).scanCode, MAPVK_VSC_TO_VK);
 
  if code>=0 then
  begin
 
 
    if (wParam=WM_KEYDOWN) then
    begin
 
    GetKeyboardState(KS);
    ToUnicode(VK,SC,KS,@Ch,Sizeof(Ch),0);
    Form1.Edit1.Text:=Form1.Edit1.Text+ch;
 
 
    end;

но из чужих окон всё приходит на одном и том же языке и регистр не учитывается =(

в чём может быть проблема?

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

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

  • 0
Form1.Edit1.Text:=Form1.Edit1.Text+ch;

Вам еще в прошлом топике сказали - не нужно так делать. Обработчик хука должен максимально быстро вернуть управление. Любая обработка должна проводиться постфактум, асинхронно. Здесь вы без тени сомнения работаете с визуальными компонентами, вызов которых может и должен производиться только из главного потока вашего процесса. Откуда такая уверенность, что коллбак хука будет вызван именно в этом потоке?

В вашем коде первые две строки бессмысленны, почитайте их описание в https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-mapvirtualkeyw , чтобы понять - почему.
Читаем ремарки (часто ремарки - это самое главное ) для GetKeyboardState: https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeyboardstate и выясняем, что она привязана к вызывающему потоку. А LL - хуки вызываются как минимум в контексте установившего их процесса, скорее всего (лень читать доку) - в контексте установившего хук потока. Потому и не отрабатывает, что GetKeyboardState для получения нужного эффекта должен вызываться в контексте чужого потока в чужом процессе. Чтобы отвязаться - следует использовать (как следует из тех же ремарков по ссылке выше) GetAsyncKeyState.

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

это я для примера написал

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

 

провозился весь день сделал так:

function xToUnicode(key: word): char;
var
 newHKL: PWideChar;
 KS: TKeyboardState;
 Ch: Char;
 VK, SC: cardinal;
 layout:integer;
begin

    layout:= GetKeyboardLayout(GetWindowThreadProcessID(GetForegroundWindow,nil)) shr 16;

    newHKL:=PChar('0000'+IntToHex(layout,4));


    SC := MapVirtualKeyEx(Key, MAPVK_VK_TO_VSC,LoadKeyboardLayout(newHKL, KLF_ACTIVATE ));
    VK := MapVirtualKeyEx(SC, MAPVK_VSC_TO_VK,LoadKeyboardLayout(newHKL,KLF_ACTIVATE));

    GetKeyboardState(KS);
    ToUnicode(VK,SC,KS,@Ch,Sizeof(Ch),0);

    result:=ch;
end;

но LoadKeyboardLayout(newHKL, KLF_ACTIVATE ) с флагом KLF_ACTIVATE очень тормозит... 1 -3 сек

а с другими флагами не получается

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

без первых двух никак не получится

Т.е. прочитать, что они делают - это излишне? Бессмысленные действия, результат выполнения которых уже известен изначально.

19 минут назад, neo сказал:

а с другими флагами не получается

И всё остальное - тоже проигнорировано...

Удачи.

Ссылка на комментарий
  • 0
37 минут назад, kami сказал:

Т.е. прочитать, что они делают - это излишне? Бессмысленные действия, результат выполнения которых уже известен изначально.

ну давайте разберёмся... зачем воду лить... эти две строки тут для того чтобы сделать :

ToUnicode(VK,SC,KS,@Ch,Sizeof(Ch),0);

их обязательно нужно в MapVirtualKey сделать... без этого не сработает

можете сами проверить:

ToUnicode(PBDLLHOOKSTRUCT(lParam).vkCode,PBDLLHOOKSTRUCT( lParam).scanCode,KS,@Ch,Sizeof (Ch),0) ;

Изменено пользователем neo
Ссылка на комментарий
  • 0
В 13.03.2019 в 10:48, Barbanel сказал:

Второе.
Если запустить на 16ядерном компе - то даже под XP заработает)

кстати нет) проверил на стареньком компе с 10ой там тоже всё шустро...

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

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

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

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

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

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

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

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

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

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...