• 0
neo

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

Вопросы

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

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

 

  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;

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 ответов на этот вопрос

  • 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

Приехал домой мой код с MapVirtualKeyEx под Win10 отлично работает... до этого тестировал на Win7..

интересно это из за винды или комп мощней?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 11.03.2019 в 19:41, neo сказал:

интересно это из за винды или комп мощней?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 13.03.2019 в 10:48, Barbanel сказал:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

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

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