Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 25

/ вопрос открыт /

Уважаемые эксперты! Каким образом можно котроллировать набор текста в любом приложении из программы? Требуется получать набираемый на клавиатуре текст и выполнять его обработку... Например, как делает Punto Switcher? То-есть программе неважно, где мы набираем текст: в Word'е, в Блокноте, в Проводнике или ещё где - нужно перехватывать набор и при этом не подавлять его. Заранее благодарю за ответы.

Dron Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Dron (статус: Студент)
Вопрос отправлен: 3 июня 2006, 19:14
Состояние вопроса: открыт, ответов: 2.

Ответ #1. Отвечает эксперт: bruder

Здравствуй, Dron!
Тебе придётся использовать DLL и "хуки".
Загрузив эту длл, (LoadLibrary('X:\Files\Delphi6\Bin\PS.dll');) она будет показывать коды нажатых клавиш.

Приложение:
  1.  
  2.  
  3. library PuSw;
  4.  
  5. uses
  6. Windows, SysUtils;
  7.  
  8. {$R *.res}
  9. var
  10. KHook: HHOOK;
  11.  
  12. function KProc(Code: integer; wParam: Word; lParam: LongInt): LongInt; stdcall;
  13. const
  14. KState: integer = 1073741824; // 01000000000000000000000000000000
  15. begin
  16.  
  17. if not (Code=HC_ACTION) then
  18. begin
  19. Result:=CallNextHookEx(KHook, code, wParam, lParam);
  20. Exit;
  21. end;
  22.  
  23. if (lParam and KState) <> 0 then
  24. begin
  25. Result:=CallNextHookEx(KHook, code, wParam, lParam);
  26. Exit;
  27. end;
  28.  
  29. if wParam>0 then
  30. begin
  31. MessageBox(0,PChar(IntToStr(wParam)),'PS',0);
  32. end;
  33.  
  34. end;
  35. begin
  36. KHook:=SetWindowsHookEx(WH_KEYBOARD, @KProc, HInstance, 0);
  37. end.


Ответ отправил: bruder (статус: 4-ый класс)
Время отправки: 3 июня 2006, 19:57
Оценка за ответ: 4

Комментарий к оценке: В принципе, всё работает, только хотел бы узнать, как передать wParam в само приложение? Например, записать в TMemo...

Ответ #2. Отвечает эксперт: Вадим К

А что же здесь передавать? С символами, здесь всё просто - просто делаете так
char(WParam mod 256).
Для функциональных клавиш используются старшие биты. Думаю теперь уже не будет проблем.
Замечу, что многие антивирусы/фаэрволы могут быть не равнодушными к вашему перехватчику клавиш. Это связано с тем, что этот метод используют многие кейлогеры, которые записывют нажатия ваших клавиш, когда вы вводите пароли и передают своим хозяевам.
Поэтому ваш перехвтчик может не работать или работать неустойчиво. Будьте внимательны.

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 5 июня 2006, 10:34
Оценка за ответ: 4

Комментарий к оценке: Спасибо за информацию.

Мини-форум вопроса

Всего сообщений: 9; последнее сообщение — 23 июня 2006, 16:04; участников в обсуждении: 2.
bruder

bruder (статус: 4-ый класс), 3 июня 2006, 20:05 [#1]:

Вместо "MessageBox(0,PChar(IntToStr(wParam)),'PS',0);" пишешь свою обработку... ;)
Dron

Dron (статус: Студент), 3 июня 2006, 20:49 [#2]:

Так как всё-таки передать данные из dll в приложение?
С уважением.
bruder

bruder (статус: 4-ый класс), 4 июня 2006, 10:23 [#3]:

Раз работает, то ставить нада 5, а не 4 ;) Да по-разному, на что фантазии хватит =) Например можно посылать сообщение из длл в программу, а параметр указывать в параметр (сори за туфту).

const
MY_MESSAGE = WM_USER + 4242;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
// Handler that receive the Message
procedure MessageReceiver(var msg: TMessage); message MY_MESSAGE;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
txt: string;
begin
txt := 'Hello World';
SendMessage(Form1.Handle, MY_MESSAGE, 0, DWORD(PChar(txt)));
end;

// To receive this custom Message that is addressed to form1.handle
// you need a message handler.

procedure TForm1.MessageReceiver(var msg: TMessage);
var
txt: PChar;
begin
txt := PChar(msg.lParam);
msg.Result := 1;
ShowMessage(txt);
end;

Чуть-чуть изменишь - и покатит.
Вот такие пироги =)
P.S. Качай исходники KeyLogger'ов и сё...
Dron

Dron (статус: Студент), 12 июня 2006, 09:52 [#4]:

Большое спасибо!
С уважением.
Dron

Dron (статус: Студент), 23 июня 2006, 09:06 [#5]:

Делаю всё как написано, но почему-то при нажатии отправляется сразу три или четыре одинаковых сообщения, хотя нажатие клавиши обычное. Как от этого можно избавиться?
С уважением.
bruder

bruder (статус: 4-ый класс), 23 июня 2006, 13:01 [#6]:

Да, кстати, ловушку закрывать надо... (вроде =))UnhookWindowsHookEx(KHook)
Это происходит из-за того, что этот хук перехватывает сообщения WM_KEYDOWN, WM_KEYUP...
https://www.delphi-int.ru/expert/?step=download&id=3
Смотри, разбирайся...
Dron

Dron (статус: Студент), 23 июня 2006, 15:45 [#7]:

Честно говоря, не понял, куда добавить эту строку с UnhookWindowsHookEx... Если в саму DLL, то хук, естественно, не срабатывает... Впрочем, вроде бы всё и так стало работать...
Только теперь проблема в другом... Как отлавливать русские символы? Хук ловит только основные (английские), да и то без регистра - всё время верхний регистр. Как же избавиться от этого?
Из представленных примеров один не компилируется (требует модуль global), а второй какой-то очень мудрёный, да и он тоже русские символы не способен отловить.
Кроме того, приложение пишется не обязательно для русской системы - там может быть любой другой язык, а в разных системах там разные символы (зависит от языка)...
bruder, спасибо... Жду помощи.
С уважением.
bruder

bruder (статус: 4-ый класс), 23 июня 2006, 15:58 [#8]:

Ждать ещё придётся долго. Минимум 2 дня... дела =)
UnhookWindowsHookEx можно впихнуть в длл в ф-ию. И при закрытии программы вызывать её из длл.
Dron

Dron (статус: Студент), 23 июня 2006, 16:04 [#9]:

Ну хорошо, только чтоб не особо долго :-) Буду ждать.
С уважением.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:42
Выполнено за 0.03 сек.