Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ловушка сообшений 
:(
    Опции темы
Proger101
Дата 30.6.2007, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 16.5.2007

Репутация: нет
Всего: нет



Уважаемые системные прграммисты, простите за(возможно) ламерский вопрос.
Я хочу перехватывать все клавиши для всех приложений и для этого ставлю ловушку сообшиний:

Код


////////////////////////////////
function Key_Hook(code : integer; wParam: Integer; 

lParam : Integer): Integer; stdcall;
begin
  if (code <> HC_ACTION)then
  begin
    Append(ScnFile);
    WriteLn(ScnFile, '<KeyPresed>');
    Writeln(ScnFile, '  ', wParam);
    WriteLn(ScnFile, '<KeyPresed/>');
    CloseFile(ScnFile);

  end;

  CallNextHookEx(HKey, Code, wParam, lParam);
end;

function StartHookKey(Path : String) : hHook;
begin
  // Инициализация файловой переменной
  AssignFile(ScnFile, Path);
  // Установка ловушки
  HKey := SetWindowsHookEx(WH_KEYBOARD, @Key_Hook, 

hInstance, 0);
  Result := HKey;
  if Result = 0 then  // Ловушка не установилась
    ShowMessage('Ошибка');

end;

procedure RemoveHookKey(var h : hHook);
begin
  if h <> 0 then
  begin
    UnhookWindowsHookEx(h);
    h := 0;
  end;
end;


Вызов процедур из основного модуля:
Код

/////////////////////////////////////////////////////////
procedure TForm1.MRecExecute(Sender: TObject);
begin
  Rewrite(ScnFile);
  CloseFile(ScnFile);
  HookKey := StartHookKey(ScnPath);
end;


procedure TForm1.MStopExecute(Sender: TObject);
begin
  RemoveHookKey(HookKey);
end;


Ловушка должна перехватывать нажатие всех клавиш и записывать в файл коды нажатых клавиш.
Но проблема в том что callback функция даже не вызывается!!!!!

Помогите пожалуста.

Заранее благодарен.
PM MAIL   Вверх
Ak47black
Дата 30.6.2007, 23:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



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

Это сообщение отредактировал(а) Ak47black - 30.6.2007, 23:48

Присоединённый файл ( Кол-во скачиваний: 43 )
Присоединённый файл  gpHook.rar 45,20 Kb
PM MAIL   Вверх
ilyalyu
Дата 2.7.2007, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 25.10.2006

Репутация: нет
Всего: нет



При написании такого приложение есть два момента:

1. Hook надо создавать не внутри приложения, а в отдельной DLL.

2. Информацию от DLL к приложению надо передавать с помощью сообщений (windows messages), а не с помощью callback functions.

Вот как это примерно выглядит:

Код

library hooks;

uses SysUtils, Windows;

{$R *.res}

var HookKB: HHook = 0;
    HookMsg: UINT = 0;

function HookProcKB(nCode: Integer; MsgID: WParam; Data: LParam): LResult; stdcall;
begin
  PostMessage(FindWindow('TForm', nil), HookMsg, SomeData, SomeData);
  // TForm - это та форма, в которую должно передаваться сообщение (конечно, это должно быть какое-нибудь более сложное название)
  Result := CallNextHookEx(HookKB, nCode, MsgID, Data)
end;

procedure Hook; stdcall;
begin
  if HookKB = 0 then HookKB := SetWindowsHookEx(WH_KEYBOARD, @HookProcKB, HInstance, 0);
end;

procedure Unhook; stdcall;
begin
  if HookKB <> 0 then UnhookWindowsHookEx(HookKB);
  HookKB := 0;
end;

exports Hook, Unhook;

begin
end.

PM MAIL   Вверх
mr.Anderson
Дата 2.7.2007, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: нет
Всего: 128



Цитата
Hook надо создавать не внутри приложения, а в отдельной DLL.

Далеко не факт. Могу предоставить функцию для перехвата нажатий любых клавиш, которую пишем прямо в модуле программы, безо всяких DLL, что очень удобно.

А вообще, все зависит от задачи. Если требуется отловить клавиши только в пределах формы приложения, то вполне хватит переопределения AppMsg.
Код

type
 Form1 = class( ... )
  ...
 public
  procedure AppMsg( var Msg: TMsg; var Handle: Boolean ); virtual;



--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
Ak47black
Дата 2.7.2007, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Цитата

Далеко не факт. Могу предоставить функцию для перехвата нажатий любых клавиш, которую пишем прямо в модуле программы, безо всяких DLL, что очень удобно.

Интересно как если можно, я вроде думал всегда что надо через Dll перехватывать ( или дрова писать, там что угодно перехватить тогда можно) так как по идее простому окну от всех окон сообщения не приходят.
И действует-ли твой метод на виндах от 98 по vista?

Это сообщение отредактировал(а) Ak47black - 2.7.2007, 23:56
PM MAIL   Вверх
MetalFan
Дата 3.7.2007, 06:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 16
Всего: 128



Цитата(Ak47black @  3.7.2007,  00:55 Найти цитируемый пост)
Интересно как если можно

есть понятие локального и глобального хука. локальный действует - в пределах приложения.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
W4FhLF
Дата 3.7.2007, 09:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 6
Всего: 121



Цитата(MetalFan @  3.7.2007,  06:41 Найти цитируемый пост)
есть понятие локального и глобального хука. локальный действует - в пределах приложения.


Но задача сформулирована:

Цитата(Proger101 @  30.6.2007,  18:26 Найти цитируемый пост)
Я хочу перехватывать все клавиши для всех приложений


Поэтому мне тоже интересно как с помощью системного механизма хуков mr.Anderson без DLL внедряется во все приложения. 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
mr.Anderson
Дата 3.7.2007, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: нет
Всего: 128



Действует ли на Vista - понятия не имею, с ней никогда не работал. А вот на 98 работать должно вполне.

Насчет пределов приложения - я специально проверил, работает в пределах всей системы, даже если окно программы свернуто и неактивно.

Итак, поехали. В главном модуле программы рисуем функцию:
Код

function KeyboardProc( nCode: Integer; wParam, lParam: DWORD ): Integer; stdcall;
type
 PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;
 KBDLLHOOKSTRUCT  = record
  vkCode      : DWORD;
  scanCode    : DWORD;
  flags       : DWORD;
  time        : DWORD;
  dwExtraInfo : Pointer;
 end;
const
 KeyStroke : BOOL = FALSE;
 LLKHF_ALTDOWN    = KF_ALTDOWN shr 8;
var
 p : PKBDLLHOOKSTRUCT;
begin
 //функция перехватывает нажатие всех системных клавиш, включая ALT + F4, CTRL + ESC, WIN и так далее
 if( nCode < 0 ) then
  CallNextHookEx( hook, nCode, wParam, lParam );

 if( nCode = HC_ACTION ) then
  case wParam of
   WM_KEYDOWN, WM_SYSKEYDOWN, WM_KEYUP, WM_SYSKEYUP:
   begin
    p         := PKBDLLHOOKSTRUCT( wParam );
    KeyStroke := ( ( p.vkCode = VK_LWIN ) or ( p.vkCode = VK_RWIN ) ) or
                 ( ( p.vkCode = VK_TAB ) and ( ( p.flags and LLKHF_ALTDOWN ) <> 0 ) or
                 ( ( p.vkCode = VK_ESCAPE ) and ( ( p.flags and LLKHF_ALTDOWN ) <> 0 ) or
                 ( ( p.vkCode = VK_ESCAPE ) and ( ( GetKeyState( VK_CONTROL ) and $8000 ) <> 0 ) ) or
                 ( ( p.vkCode = VK_F4 ) and ( ( p.flags and LLKHF_ALTDOWN ) <> 0 ) );
   end; // case item
  end; // case

  if( KeyStroke ) then
   Result := 1; //currect action is not allowed
  else Result := CallNextHookEx( hook, nCode, wParam, lParam );
end;

Объявляем глобальную переменную:
Код

hook : HHOOK;

Затем в OnCreate формы ставим хук:
Код

hook := SetWindowsHookEx( WH_KEYBOARD_LL, @KeyboardProc, GetModuleHandle( nil ), 0 )

На OnClose формы:
Код

UnhookWindowsHookEx( hook );

Запускаем и радуемся.

Это сообщение отредактировал(а) mr.Anderson - 3.7.2007, 09:54


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
Rennigth
Дата 3.7.2007, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 8
Всего: 76



Цитата(mr.Anderson @  3.7.2007,  09:52 Найти цитируемый пост)
А вот на 98 работать должно вполне.

 smile  



--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
mr.Anderson
Дата 3.7.2007, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: нет
Всего: 128



Rennigth, а почему нет? Я не проверял, правда, дома только XP есть, но почему не должно работать-то? Или там системы хуков нет?


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
W4FhLF
Дата 3.7.2007, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 6
Всего: 121





--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Ak47black
Дата 3.7.2007, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



MetalFan, а почему тогда вообще хуком отлавливать если только из своего приложения нужно.
Тут просто можно написать свою процедуру обработки окна которая ловит WM_CHAR и хуков не каких ненужно.

mr.Anderson
Мда интересно не думал что так можно сделать.
Но я лучше буду использовать с dll чтобы не промахнуться на другой винде.

Это сообщение отредактировал(а) Ak47black - 3.7.2007, 11:41
PM MAIL   Вверх
W4FhLF
Дата 3.7.2007, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 6
Всего: 121



Цитата(Ak47black @  3.7.2007,  11:40 Найти цитируемый пост)
Но я лучше буду использовать с dll чтобы не промахнуться на другой винде.


MSDN читаем, DLL тут не причём, это не случайность, а известная feature. 

from link:

Цитата

Minimum operating systems    Windows NT 4.0 SP3


Это сообщение отредактировал(а) W4FhLF - 3.7.2007, 12:30


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
mr.Anderson
Дата 4.7.2007, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: нет
Всего: 128



W4FhLF, вот я как раз хочу спросить, раз так, то какая разница - в DLL или в программе ставить хук? Все равно ниже чем на XP не сработает?


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
dumb
Дата 4.7.2007, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 7
Всего: 158



Цитата(mr.Anderson @  4.7.2007,  17:03 Найти цитируемый пост)
хочу спросить, раз так, то какая разница - в DLL или в программе ставить хук?

для всех глобально устанавливаемых хуков(кроме _LL - WH_KEYBOARD_LL/WH_MOUSE_LL) процедуры обработки должны быть помещены в dll. система подгружает эту dll в адресные пространства всех оконных приложений для того, чтобы вызывать процедуру обработки хука в контексте генерирующего событие приложения.

для _LL-хуков это не требуется, так как при вызове хук-процедуры происходит переключение в контекст установившего хук приложения(это доходчиво написано в ссылке, приведенной W4FhLFом).

для локального хука dll, естественно, тоже не нужна.

Цитата(mr.Anderson @  4.7.2007,  17:03 Найти цитируемый пост)
Все равно ниже чем на XP не сработает? 

а это ты откуда выкопал?  smile
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

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

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0864 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.