Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.04.2009, 18:28   #1
rem37
 
Регистрация: 14.04.2009
Сообщений: 8
По умолчанию Глобальный хук на клаву

Устанавливаю хук, который отправляет код символа моей программе. Все работает и работает везде.
Код стандартный взял с форума:
Код:
function KeyHook(CODE, WParam, LParam: DWORD): DWORD; stdcall;
var
  ServerWnd: THandle;
  ScanCode:integer;
begin
  if CODE = HC_ACTION then
   if ((LParam or (1 shl 30))=LParam) then
    begin
     ServerWnd:=FindWindow(nil,'myprogram');
     GetKeyboardState(KeybrdState);
     ScanCode:=(LParam shr 16)and $FF;
     if ToAscii(WParam,ScanCode,KeybrdState,@Symbol,0)>0 then
      PostMessage(ServerWnd, WM_KEYEVENT, ord(Symbol[0]), LParam)
     else
      PostMessage(ServerWnd, WM_KEYEVENT, 0, LParam);
     end;
  Result := CallNextHookEx(HookHandle, code, WParam, LParam);
end;

procedure SetKeyHook; stdcall; export;
begin
  if HookHandle=0 then
   HookHandle:=SetWindowsHookEx(WH_KEYBOARD, @KeyHook, hInstance, 0);
end;

procedure DelKeyHook; stdcall; export;
begin
  if HookHandle <> 0 then UnhookWindowsHookEx(HookHandle);
   HookHandle:=0;
end;
Но мне нужно чтобы некоторые символы не доходили бы до программы в которой набираеться текст. Т. е. символ должен быть отправлен моей программе, но не должен появиться в окне, где была нажата клавиша. Как это сделать? Спасибо за помощь.

Последний раз редактировалось rpy3uH; 14.04.2009 в 18:59.
rem37 вне форума Ответить с цитированием
Старый 14.04.2009, 19:06   #2
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

код надо оформлять в тегах CODE

по теме:
в функции KeyHook при получении символа, который надо заблокировать, не вызывай функцию CallNextHookEx и возвращай значение отличное от нуля.

Код:
function KeyHook(CODE, WParam, LParam: DWORD): DWORD; stdcall;
var
  ServerWnd: THandle;
  ScanCode:integer;
begin
  if CODE = HC_ACTION then
   if ((LParam or (1 shl 30))=LParam) then
    begin
     ServerWnd:=FindWindow(nil,'myprogram');
     GetKeyboardState(KeybrdState);
     ScanCode:=(LParam shr 16)and $FF;
     if ToAscii(WParam,ScanCode,KeybrdState,@Symbol,0)>0 then
      PostMessage(ServerWnd, WM_KEYEVENT, ord(Symbol[0]), LParam)
     else
      PostMessage(ServerWnd, WM_KEYEVENT, 0, LParam);
     if <если символ надо заблокировать> then
      begin
       result:=1;
       exit;
      end;
     end;  
  Result := CallNextHookEx(HookHandle, code, WParam, LParam);
end;
например так
rpy3uH вне форума Ответить с цитированием
Старый 14.04.2009, 19:21   #3
MrWinDos
Новичок
Джуниор
 
Аватар для MrWinDos
 
Регистрация: 13.04.2009
Сообщений: 2
По умолчанию

Можна поставити hook WH_GETMESSAGE і змінювати код клавіші на 0 (у структурі TMsg) при WM_KEYUP чи WM_KEYDOWN. Правда працює лише для віконних програм.
MrWinDos вне форума Ответить с цитированием
Старый 14.04.2009, 21:22   #4
rem37
 
Регистрация: 14.04.2009
Сообщений: 8
По умолчанию

К сожалению не всё так просто. Не вызывать CallNextHookEx нельзя - видимо это нарушает работу хуков некоторых программ. Например в notepad работает, в Microsoft office нет.

WH_GETMESSAGE тоже пробовал - если обнулять структуру TMsg, символ действительно не доходит, но появляеться другая проблема - каждый символ передаёться моей программе несколько раз, например в Microsoft Office 5 paз, в notepad всё ok. Как с этим бороться - непонятно.

Вопрос остаёться открытым...
rem37 вне форума Ответить с цитированием
Старый 15.04.2009, 08:16   #5
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

ну попробуй так
Код:
if <если символ надо заблокировать> then
 begin
  CallNextHookEx(HookHandle, code, WParam, LParam);
  result:=1;
  exit;
 end;
rpy3uH вне форума Ответить с цитированием
Старый 15.04.2009, 18:36   #6
rem37
 
Регистрация: 14.04.2009
Сообщений: 8
По умолчанию

Цитата:
Сообщение от rpy3uH Посмотреть сообщение
ну попробуй так
Код:
if <если символ надо заблокировать> then
 begin
  CallNextHookEx(HookHandle, code, WParam, LParam);
  result:=1;
  exit;
 end;
Не помогает. Виноват именно result:=1. Если result:=0 работает, но символ доходит. Отладка показала, что если result:=1, не срабатывает условие if CODE = HC_ACTION then.
rem37 вне форума Ответить с цитированием
Старый 16.04.2009, 12:29   #7
rem37
 
Регистрация: 14.04.2009
Сообщений: 8
По умолчанию

Похоже тупик...

Моя задача такая:
1. надо перехватить нобор текста в любом окне
2. передать каждый символ моей программе
3. там я меняю символы как мне надо
4. то, что получилось, передаю назад в то же самое окно
5. и последняя задача, которую я считал простой, чтобы некоторые символы не доходили бы до программы в которой набираеться текст.

Первые 4 реализованны и работают нормально, последняя никак...

Видимо придёться искать другой путь... Но как такое сделать?

P.S. Простите за возможные ошибки - русский не родной мне язык.
rem37 вне форума Ответить с цитированием
Старый 03.05.2009, 01:25   #8
rem37
 
Регистрация: 14.04.2009
Сообщений: 8
По умолчанию

Ещё вопрос появился...

Передаю символы в чужое окно. Нужно стереть символ который стоит перед курсором. Думал будет работать так:

Код:
PostMessage(handle, WM_KEYDOWN, VK_BACK, 0);
PostMessage(handle, WM_KEYUP, VK_BACK, 0);
PostMessage(handle, WM_CHAR, Word(tmp[1]), 0);
Однако стирает мой последний символ:
Тогда попытался так:

Код:
PostMessage(handle, WM_CHAR, Word(tmp[1]), 0);
PostMessage(handle, WM_KEYDOWN, VK_LEFT, 0);
PostMessage(handle, WM_KEYUP, VK_LEFT, 0);
PostMessage(handle, WM_KEYDOWN, VK_BACK, 0);
PostMessage(handle, WM_KEYUP, VK_BACK, 0);
PostMessage(handle, WM_KEYDOWN, VK_RIGHT, 0);
PostMessage(handle, WM_KEYUP, VK_RIGHT, 0);
Стирает символ перед курсором, но и мой тоже.
Что я делаю не так? Этот код находиться в процедуре которая обрабатывает хук на клаву.
rem37 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Глобальный хук. Проблема с dll =\\ Zeraim Win Api 11 19.12.2008 00:18
Ловушка на клаву(нужно немного улутшить ее) xshStasX Win Api 2 11.08.2008 15:50
Глобальный хук на мышь не глобальный О_о JTG Общие вопросы Delphi 3 05.06.2008 17:41
глобальный поиск по винтам Simply-Art Общие вопросы Delphi 5 27.11.2006 17:02
глобальный хук & событие отжатия клавиши Nowichok Общие вопросы Delphi 9 24.11.2006 17:51