Chertenok.ru - все о программировании
Вход  |  Регистрация  |  Поиск 
Праздник
Сегодня :

День славянской письменности и культуры


хук на клаву
На страницу 1, 2  След.

Новая тема  Ответить  Печать Предыдущая тема  Следующая тема
Автор Сообщение
morph
Гость







СообщениеЧт, 06-Май-2004 16:00    Заголовок сообщения: хук на клаву
Цитата

поможите с кодом. нужно чтоб прога отслеживала нажатие батонов(клавиш) на клаве и при нажатии нужной комбинации выполняла действия. знаю что надо делать с помощью hook, но я в WinAPI ничё не понимаю, события типа хоткей не предлагать, мне нужно именно отслеживание нажатия клавиш.
В начало
DrPass
Знающий :)
/Почетный Модератор/


Возраст: 31
Знак зодиака: Лев
Зарегистрирован: 02.05.2002
Сообщения: 5709
Откуда: Донецк
СообщениеЧт, 06-Май-2004 21:23 
Цитата

С прогой будет не все так просто - если ты собрался перехватывать все нажатия, то тебе нужен глобальный хук. А глобальные хуки делаются только с помощью DLL. Почитай Рихтера на эту тему. WinAPI - не такой уж и сложный зверь.
_________________
Да пребудет с вами Сила!
В начало
Посмотреть профиль Отправить личное сообщение
morph
Гость







СообщениеЧт, 06-Май-2004 21:32 
Цитата

а где достать?
В начало
DrPass
Знающий :)
/Почетный Модератор/


Возраст: 31
Знак зодиака: Лев
Зарегистрирован: 02.05.2002
Сообщения: 5709
Откуда: Донецк
СообщениеПт, 07-Май-2004 20:52 
Цитата

Бумажный вариант - в магазинах. Книжный - в Интернете. Он точно есть, у меня на работе лежит кем-то скачанный. Только не знаю откуда
_________________
Да пребудет с вами Сила!
В начало
Посмотреть профиль Отправить личное сообщение
morph
Гость







СообщениеПт, 07-Май-2004 21:07 
Цитата

а на сайт ентон выложить сможешь? или вспомни плз где он выкачан, а то я искал - толкового не нашёл((
В начало
Пол:Муж Шурик
Я живу тут....


Возраст: 42
Знак зодиака: Овен
Зарегистрирован: 15.01.2003
Сообщения: 1951
Откуда: Киев
СообщениеВт, 11-Май-2004 18:43 
Цитата

У меня есть какие-то примеры по блокировке клавиатуры через хуки. Если хочешь -- дам. Хоть может уже где-то здесь выкладывал. По идее там немного нужно добавить для проверки клавиш. Я как-то пробовал ловить пару клавиш. Не помню, кажется выходило.

DrPass писал(а):
А глобальные хуки делаются только с помощью DLL.

К сожалению теорию не читал. Если бы делал такое -- в виде ехе без интерфейса.

_________________
Ответ готов, готов ли твой вопрос?
В начало
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
morph
Гость







СообщениеВт, 11-Май-2004 20:13 
Цитата

а скока они весят? если меньше мега то кинь на morphfaq[at]mail.ru
В начало
DrPass
Знающий :)
/Почетный Модератор/


Возраст: 31
Знак зодиака: Лев
Зарегистрирован: 02.05.2002
Сообщения: 5709
Откуда: Донецк
СообщениеВт, 11-Май-2004 21:05 
Цитата

Цитата:
К сожалению теорию не читал. Если бы делал такое -- в виде ехе без интерфейса.

Логика простая: если какое-то окно получило захученное событие, для его обработки управление должно передаться в хуковую функцию, и только после нее - в оконную процедуру. А для этого хуковая функция должна где быть? Правильно, в адресном пространстве процесса этого окна. Для этого и пишут DLL - винда должна отобразить ее на адресные пространства процессов.
Цитата:
а на сайт ентон выложить сможешь? или вспомни плз где он выкачан, а то я искал - толкового не нашёл((

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

_________________
Да пребудет с вами Сила!
В начало
Посмотреть профиль Отправить личное сообщение
Пол:Муж Шурик
Я живу тут....


Возраст: 42
Знак зодиака: Овен
Зарегистрирован: 15.01.2003
Сообщения: 1951
Откуда: Киев
СообщениеВт, 11-Май-2004 21:17 
Цитата

Я здесь уже выкладывал этот пример. Ходи СЮДА.

Там в функции обработки KeyHook есть закоментированный код, обрабатывающий нажатие пробела. Раскоментируй и проверь, дожно работать. Проверка старшего бита LParam нужна для различения нажатия и отпускания клавиши. Зачем посылка сообщения окну уже не помню точно. Может что-то предусматривалось делать на основе этого, а может просто не работало.

А вообще, я думаю что тебе достаточно будет этого примера и имеющейся Справки по АПИ. Найди там раздел по функции SetWindowsHookE а потом описание обработчика по WH_KEYBOARD.

_________________
Ответ готов, готов ли твой вопрос?
В начало
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
Пол:Муж Шурик
Я живу тут....


Возраст: 42
Знак зодиака: Овен
Зарегистрирован: 15.01.2003
Сообщения: 1951
Откуда: Киев
СообщениеВт, 11-Май-2004 21:44 
Цитата

to DrPass
Да, действительно, что-то в этом есть. В этом примере нормально ловится пробел только для приложения, из которого установлен хук. Если нажать пробел в другом приложении то блокировка теряется. А пробел в редакторе Delphi вобще выбил всё IDE. Я это и раньше замечал но не знал почему.

Ну хорошо, а почему (и как) работает тривиальный код обработчика, рассчитанный только на блокировку?
Код:
  function KeyHook( Code: integer; WParam: word; LParam: Longint ): Longint; stdcall;
  begin
    Result:= -1;
  end;

Т.е. если из ехе вызывается SetWindowsHookEx(WH_KEYBOARD, @KeyHook, HInstance, 0), то что будет вызываться при нажатии клавиш в других приложениях? В каком адресном пространстве будет работать эта функция?

Если честно я несколько плаваю в вопросах связанных с взаимодействием адресных пространств разных процессов. Какое-то представление есть (делал СОМы в осх) но не очень чёткое.

_________________
Ответ готов, готов ли твой вопрос?
В начало
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
VaDima
Энтузиаст


Возраст: 36
Знак зодиака: Овен
Зарегистрирован: 18.12.2002
Сообщения: 369
Откуда: Из лесу, вестимо
СообщениеСр, 12-Май-2004 12:33 
Цитата

Читай матчасть по функции RegisterHotKey.
А вот кусочек моего объектика для сабжа. Остальное - несущественно.
Код:
{ TGlobalHotKey }

constructor TGlobalHotKey.Create(Collection: TCollection);
begin
  inherited Create(Collection);
  FParentList := (Collection as TGlobalHotKeys).FHotKeyList;
  FAtom:=GlobalAddAtom(PChar(IntToStr(LongInt(Self))));
  FWndHandle:=AllocateHWnd(NewWndProc);
  FActive:=True;
end;

destructor TGlobalHotKey.Destroy;
begin
  if FGlobalKey<>0 then HotKey:=0;
  DeleteAtom(FAtom);
  if FWndHandle <> 0 then
    DeallocateHWnd(FWndHandle);
  FWndHandle := 0;
  inherited Destroy;
end;

procedure TGlobalHotKey.NewWndProc(var Message: TMessage);
var
  tmp:Word;
  sh:TShiftState;
begin
  case Message.Msg of
    WM_HOTKEY: begin
                  try
                    ShortCutToKey(FGlobalKey, tmp, sh);
                    if Assigned(FOnKeyDown) then
                      FOnKeyDown(self, tmp, sh);
                    if Assigned(FParentList.FOnDownKey) then
                      FParentList.FOnDownKey((FParentList as TObject), FIndex);
                  except
                    Application.HandleException(Self);
                  end;
               end;
    else
      with Message do
        result := DefWindowProc(FWndHandle, Msg, wParam, lParam);
  end;
end;

procedure TGlobalHotKey.SetEnabled(aValue: Boolean);
var
  sh:TShiftState;
  tmpi:Integer;
  tmp:Word;

begin
  if FActive<>aValue then
    begin
      FActive:=aValue;
      if (csDesigning in FParentList.ComponentState) then exit;
      if FActive then
        begin
          tmpi:=0;
          ShortCutToKey(FGlobalKey, tmp, sh);
          if ssCtrl in sh then tmpi:=MOD_CONTROL;
          if ssAlt in sh then tmpi:=tmpi or MOD_ALT;
          if ssShift in sh then tmpi:=tmpi or MOD_SHIFT;
          RegisterHotKey(FWndHandle, FAtom, tmpi, tmp);
        end
      else
        if FGlobalKey<>0 then UnregisterHotKey(FWndHandle, FAtom);
    end;
end;

procedure TGlobalHotKey.SetHotKey(aValue: TShortcut);
var
  sh:TShiftState;
  tmpi:Integer;
  tmp:Word;

begin
  if (FGlobalKey<>aValue) then
    begin
      if (csDesigning in FParentList.ComponentState) then
        begin
          FGlobalKey:=aValue;
          exit;
        end;
      if FActive then
        if aValue<>0 then
          begin
            tmpi:=0;
            ShortCutToKey(aValue, tmp, sh);
            if ssCtrl in sh then tmpi:=MOD_CONTROL;
            if ssAlt in sh then tmpi:=tmpi or MOD_ALT;
            if ssShift in sh then tmpi:=tmpi or MOD_SHIFT;
            RegisterHotKey(FWndHandle, FAtom, tmpi, tmp);
          end
        else
          if FGlobalKey<>0 then UnregisterHotKey(FWndHandle, FAtom);
      FGlobalKey:=aValue;
    end;
end;

_________________
Он умудрялся на бегу прописать дырочку в снегу. (Веня Дркин)
В начало
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
morph
Гость







СообщениеСр, 12-Май-2004 13:34 
Цитата

to VaDima, разьясни код плз. Кстать а как сделать чтоб ещё лог по нажатым клавишм вёлся???
В начало
VaDima
Энтузиаст


Возраст: 36
Знак зодиака: Овен
Зарегистрирован: 18.12.2002
Сообщения: 369
Откуда: Из лесу, вестимо
СообщениеСр, 12-Май-2004 13:55 
Цитата

Цитата:
разьясни код плз

Код:

// добавляем атом:
FAtom:=GlobalAddAtom(PChar(IntToStr(LongInt(Self))));

// создаем окно, которое будет обрабатывать msgs:
FWndHandle:=AllocateHWnd(NewWndProc);
...

// в Destroy, соответственно, удаляем.
...

// начинаем обрабатывать HotKey Message:
WM_HOTKEY: begin

// вызываем обработчик:
FOnKeyDown(self, tmp, sh);

// если не наше сообщение, то передаем его "правильному" окну:
else
      with Message do
        result := DefWindowProc(FWndHandle, Msg, wParam, lParam);

// шоб не коолбасило IDE:
if (csDesigning in FParentList.ComponentState) then exit;

// регистрируем глобальную хоткеину. Это API функция. (Ты хоть МЗДН читал, шо тебе говорили?):
RegisterHotKey(FWndHandle, FAtom, tmpi, tmp);


Цитата:
а как сделать чтоб ещё лог по нажатым клавишм вёлся???

Не поверишь: вести его ;)

PS. А здесь ты найдешь ответы на все свои вопросы:
http://ln.com.ua/~openxs/articles/smart-questions-ru.html

_________________
Он умудрялся на бегу прописать дырочку в снегу. (Веня Дркин)
В начало
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
morph
Гость







СообщениеЧт, 13-Май-2004 15:59 
Цитата

to VaDima, пасябо!!!
В начало
DrPass
Знающий :)
/Почетный Модератор/


Возраст: 31
Знак зодиака: Лев
Зарегистрирован: 02.05.2002
Сообщения: 5709
Откуда: Донецк
СообщениеЧт, 13-Май-2004 22:40 
Цитата

Цитата:
Ну хорошо, а почему (и как) работает тривиальный код обработчика, рассчитанный только на блокировку?

Действительно, работает вопреки логике. Будет время, поработаю с отладчиком - все-таки интересно, почему?

_________________
Да пребудет с вами Сила!
В начало
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Страница 1 из 2 На страницу 1, 2  След.
Перейти:  
Новая тема  Ответить  Печать

Вы можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете присоединять файлы в этом форуме
Вы можете скачивать файлы в этом форуме
хостинг от .masterhost 
Rambler's Top100