Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

WH_KEYBOARD [D7, Win95/98, WinXP]


Wiz@rd ©   (2004-04-04 19:13:00) 

Как правильно использовать этот хук, чтобы отслеживать и русские, и латинские символы - с учётом регистра?


xamlo   (2004-04-06 01:13:00) [1]

ты не очень внимательно прочел, там вообще-то и дллка и ехешка.
тама просто все в куче. но вообще, тебе большое спасибо :)


rimd   (2004-04-05 08:31:00) [2]

CallNextHookEx в конце KeyBoardProc! Но вообще по мойму ты написал чушь! И это работать не будет! Каким образом ты устанавливаешь глобальный Хук из своего приложения? Это должно быть в твоей DLL. А вот эта штука GetProcAddress(hinstDLL, 'KeyboardProc') должна возращать адрес типа SetHook, который должен находиться в твоей dll. Иначе, по-мойму, это не имеет смысла


xamlo   (2004-04-05 01:44:00) [3]

у меня проблема похожего типа. я хочу написать драйвер для мультимедийной клавиатуры. Так вот, вопрос следующий, как сделать так чтобы сообщения отправить дальше в виндовс, а то делает недоступными клавиши остальным приложениям. пример не мой.

// текст библиотеки, т.е. полное содержимое файла KeyHook.dpr
library KeyHook;

uses
 shellapi,
 windows;

var
g_hhk: HHOOK;

function KeyboardProc(nCode: Integer; wParam: wParam; lParam: lParam ): LParam; stdcall;
var
f:textfile;
begin
MessageBeep(0);
assignfile(f, 'c:\hook.txt');
try
 append(f);
except
 rewrite(f);
end;
writeln(f, nCode,',',wParam,',',lParam);
close(f);
end;

exports
KeyboardProc;
begin
end.

// Пример установки WindowsHook
procedure TForm1.Button1Click(Sender: TObject);
var
 hinstDLL: HINST;
 hkprcKeyboard: TFNHookProc;
 msg: TMsg;
begin
 hinstDLL := LoadLibrary('KeyHook.dll');
 hkprcKeyboard := GetProcAddress(hinstDLL, 'KeyboardProc');
 SetWindowsHookEx(WH_KEYBOARD, hkprcKeyboard, hinstDLL, 0);
end;
end.


Игорь Шевченко   (2004-04-04 23:05:00) [4]

Wiz@rd ©   (04.04.04 22:24)


> Тут не только клавиатурный шпион - тут целый мега троян
> :)


Не на этом сайте.


Wiz@rd   (2004-04-04 22:24:00) [5]

Да всё правильно работает  - оказывается - просто я тестил на FAR'е - а он почему всегда показывает русскую раскладку.

А вообще дело клавиатурным шпионом попахивает :)

Тут не только клавиатурный шпион - тут целый мега троян :)


sir John   (2004-04-04 20:17:00) [6]

надо дождаться вопрошающего, однако... :) А вообще дело клавиатурным шпионом попахивает :) Может быть я и ошибаюсь :)


DVM   (2004-04-04 20:13:00) [7]


> а на кой он нам тут? :)

Так он сам упомянул хук. Я полагаю, чтобы отслеживать нажатия клавиш в других программах.


sir John   (2004-04-04 20:07:00) [8]

To DVM:
а на кой он нам тут? :) Может я чего не так понял из описания Wiz@rd?


DVM   (2004-04-04 20:02:00) [9]


> Для этого необходимо использовать перехват сообщения WM_CHAR.

Тогда это уже другой хук WH_GETMESSAGE


sir John   (2004-04-04 19:52:00) [10]

To Wiz@rd:
Нам не надо использовать WH_KEYBOARDтак как в данномслучае эта функция для нас бесполезна, ибо она только позволяет приложению отслеживать сообщения WM_KEYDOWNи WM_KEYUP. Нам же надо перехватить конкретное нажатие клавиш. В данном случае распознать русские ли буквы нажаты или английские. Для этого необходимо использовать перехват сообщения WM_CHAR. Ниже приведен пример, который отслеживате тольконажатие русских или английских букв:

private
   Procedure HookAppChar(var msg: TWMCHAR); message WM_CHAR;

Это заголовок процедуры, который помещен в секцию private.


procedure TForm1.HookAppChar(var msg: TWMCHAR);
begin
if (msg.CharCode in [65..122]) then
 ShowMessage ('English Key Pressed! Char is: ' + Chr(msg.CharCode) + ' Code: '+ IntToStr(msg.CharCode));
if (msg.CharCode in [192..255]) then
 ShowMessage ('Russian Key Pressed! Char is: ' + Chr(msg.CharCode) + ' Code: '+ IntToStr(msg.CharCode));
end;

Это тело процедуры. При нажатии на клавиатуру, в случае, если это анг. или русская буква, Вам будет выдано сообщение с именем буквы и ее кодом. Надеюсь Вам этот пример поможет. Удачи!


Wiz@rd   (2004-04-04 19:30:00) [11]

Тогда посмотрите что неправильно (у меня тока русские символы показываются, хотя делаю GetKeyboardLayout):

procedure OnKeyHook(var Msg: TMsg);
var
 S: String;
 c: char;
 ClassName: array [0..255] of char;
 f: textfile;
 Buffer: array [0..50] of Char;
 Flags : Word;
 ks: TKeyboardState;
 kl: HKL;
 shift: Boolean;

begin
 if Msg.Message = WMHook then
 begin
   GetKeyboardState (ks);
   kl := GetKeyboardLayout (GetWindowThreadProcessId (GetFocus));
   ToAsciiEx (Msg.wParam, MapVirtualKey(Msg.wParam, 3), ks, @c, 0, KL);
   shift := GetKeyState (VK_SHIFT) <> 0;
   if (Ord (c) in [Ord('A')..Ord('Z')]) or (Ord (c) in [Ord('a')..Ord('z')]) or
   (Ord (c) in [Ord('А')..Ord('Я')]) or (Ord (c) in [Ord('а')..Ord('я')]) then
   begin
     S := c;
     if Shift then
       c := char(Ord(c) + 32);
   end
   else
   if (Ord(c) in [32..64, 91..96, 123..191]) then
   begin
     s := c;
   end;
   {if (Ord (c) in [33..47]) then
   begin
     S := c;
     if Shift then
       c := char(Ord(c) + 15);
   end;}

     {32: s := ' ';
     33..47:
     begin
        if  shift then
          c := char(Ord(c) + 15);
        S := c;
     end;}
   {else                                    
     s := '[' + Buffer + ']';}
   Flags := Msg.lParam shr 16;
   if (Flags and KF_UP) <> 0 then
   begin
     //S := S + ' down'
   end
   else
   if (Flags and KF_REPEAT) <> 0 then
   begin
     //S := S + ' repeat'
   end
   else
   begin
     //S := S + ' up';
     NeedLog := True;
     //Beep(500, 100);
   end;

 //s - результат

end;


DVM   (2004-04-04 19:27:00) [12]

Этим хуком отслеживаются нажатия клавиш. А символ надо получить самому, узнав текущую раскладку клавиатуры и состояние клавиш Shift и CapsLock


Наверх

Титульная страница Поиск, карта сайта Написать письмо