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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Глобальный хук, на несколько клавиш без dll 
:(
    Опции темы
Poseidon
  Дата 27.12.2005, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

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



Я тут порылся по форуму и нашел код Рауса

Код
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

var
  hHook: THandle;

{$R *.dfm}

function LowLevelKeyboardProc(nCode: Integer;
  WParam: WPARAM; LParam: LPARAM): LRESULT stdcall;
type
  PKbdDllHookStrukt = ^TKbdDllHookStrukt;
  _KBDLLHOOKSTRUCT = record
    vkCode: DWORD;
    scanCode: DWORD;
    flags: DWORD;
    time: DWORD;
    dwExtraInfo: PDWORD;
  end;
  TKbdDllHookStrukt = _KBDLLHOOKSTRUCT;

const
  RPT_WPARAM_DATA = 'Keyboard message = %s ';
  RPT_LPARAM_DATA = 'scan code = %s [%d]';
var
  StrResult: String;
begin
  StrResult := '';
  if nCode = HC_ACTION then
    Result := CallNextHookEx(hHook, nCode, WParam, LParam);
  case WParam of
    WM_KEYDOWN: StrResult := Format(RPT_WPARAM_DATA, ['WM_KEYDOWN']);
    WM_KEYUP: StrResult := Format(RPT_WPARAM_DATA, ['WM_KEYUP']);
    WM_SYSKEYDOWN: StrResult := Format(RPT_WPARAM_DATA, ['WM_SYSKEYDOWN']);
    WM_SYSKEYUP: StrResult := Format(RPT_WPARAM_DATA, ['WM_SYSKEYUP']);
  end;

  StrResult := StrResult + Format(RPT_LPARAM_DATA, [
    Chr(PKbdDllHookStrukt(LParam)^.vkCode), PKbdDllHookStrukt(LParam)^.vkCode]);
  Form1.Memo1.Lines.Add(StrResult);
end;

procedure TForm1.FormCreate(Sender: TObject);
const
  WH_KEYBOARD_LL = 13;
begin
  hHook := SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0);
  if hHook = 0 then RaiseLastOSError;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if not UnhookWindowsHookEx(hHook) then RaiseLastOSError;
end;

end.
Как видно, реализован отлов нажатия клавиши без использования dll. Все вроде ОК, но вот только я что-то не могу понять, как можно подобным способом (не использую dll) отловить нажатие 2 или даже 3 клавиш одновременно?


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
JoyEx
Дата 27.12.2005, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дядя
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 21.6.2005
Где: Москва, РФ

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



Смотрите MSDN:

SetWindowsHookEx
Hook Scope
WH_KEYBOARD_LL Global only


Значит без длл не обойтись


--------------------
Если ты уже никого не боишься, значит ты самый страшный 
PM IM ICQ AOL YIM MSN   Вверх
Poseidon
Дата 27.12.2005, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

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



Цитата(JoyEx @ 27.12.2005, 20:12)
Значит без длл не обойтись

JoyEx, но ведь одну клавишу отловить можно и без dll...


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
JoyEx
Дата 27.12.2005, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дядя
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 21.6.2005
Где: Москва, РФ

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



Poseidon

Это смотря где ловить, если в своём процессе, то тогда можно и без длл


--------------------
Если ты уже никого не боишься, значит ты самый страшный 
PM IM ICQ AOL YIM MSN   Вверх
Poseidon
Дата 27.12.2005, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

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



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


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
JoyEx
Дата 27.12.2005, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дядя
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 21.6.2005
Где: Москва, РФ

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



Цитата
SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0);


hInstance - это ведь базовый адрес длл для WH_KEYBOARD_LL. Или нет?


--------------------
Если ты уже никого не боишься, значит ты самый страшный 
PM IM ICQ AOL YIM MSN   Вверх
Albinos_x
Дата 27.12.2005, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

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



по идее клава также генерирует код... я так понимаю ты хочешь отловить Шифт и альт...?
нада по экспериментировать с возвращаемыми значениями... при зажатой какой-нибудь из этих клавиш
один из возвращёных байтов должен иметь приблизительно такой формат:

бит - клавиша

0 - нажата правая шифт
1 - нажата левая шифт
2 - нажата Ctrl
3 - нажата Alt
4 - нажата scroll lock
5 - нажата num lock
6 - нажата caps lock
7 - нажата insert

т.е. к примеру байт равный 32 ($20)(00100000) - соответствует, что включён num lock из всех выше перечисленных.


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Poseidon
Дата 27.12.2005, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

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



Цитата(Albinos_x @ 27.12.2005, 22:50)
я так понимаю ты хочешь отловить Шифт и альт...?
Если честно мне все-равно. Можно и "буквенные" клавиши отлавливать. Вот только как это сделать? Приведенный код отлавливает KeyDown и KeyUp по отдельности каждой клавиши. А вот нажатие нескольких не хочет... smile



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
p0s0l
Дата 27.12.2005, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

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



Если нажать одновременно 3 кнопки, сгенерится 3 WM_KEYDOWN'а... Когда отпустишь кнопки - сгенерится 3 WM_KEYUP'а... Что еще нужно - не понятно...
Объясни конкретно, что ты хочешь и в каком виде ?
Ты хочешь, чтобы одним WM_KEYDOWN'ом тебе сообщили, что нажалось 50 кнопок ? smile
И также, то что для тебя кажется "одновременным" на самом деле отнюдь не одновременно...

Это сообщение отредактировал(а) p0s0l - 27.12.2005, 23:35


--------------------
С уважением, г-н Посол.
PM   Вверх
Albinos_x
Дата 27.12.2005, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

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



как вариант, можно попробовать установить типа задержки длительностью допустим 250 мс во время задержки считывать нажатые клавиши в строку, а потом уже анализировать, если несколько символов и они отличаются, то зажаты несколько клавиш...


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
p0s0l
Дата 27.12.2005, 23:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

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



В WM_KEYDOWN ставим флажок в массиве, в WM_KEYUP убираем, потом можно по массиву определить сколько и какие кнопки зажаты...
Либо проще и надежнее GeyKeyboardState.
Или если нужно проверить нажатие определенных кнопок - GetKeyState...

Это сообщение отредактировал(а) p0s0l - 27.12.2005, 23:46


--------------------
С уважением, г-н Посол.
PM   Вверх
Albinos_x
Дата 28.12.2005, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

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



Цитата(Albinos_x @ 27.12.2005, 23:40)
как вариант, можно попробовать установить типа задержки длительностью допустим 250 мс во время задержки считывать нажатые клавиши в строку, а потом уже анализировать, если несколько символов и они отличаются, то зажаты несколько клавиш...

вот приблизительно так:
Код

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var    
  hHook: THandle;
  StrResult: String;

  function LowLevelKeyboardProc(nCode: Integer;
  WParam: WPARAM; LParam: LPARAM): LRESULT stdcall;
type
  PKbdDllHookStrukt = ^TKbdDllHookStrukt;
  _KBDLLHOOKSTRUCT = record
    vkCode: DWORD;
    scanCode: DWORD;
    flags: DWORD;
    time: DWORD;
    dwExtraInfo: PDWORD;
  end;
  TKbdDllHookStrukt = _KBDLLHOOKSTRUCT;
const
  RPT_WPARAM_DATA = 'Keyboard message = %s ';
  RPT_LPARAM_DATA = 'scan code = %s [%d]';

begin
  if nCode = HC_ACTION then
    Result := CallNextHookEx(hHook, nCode, WParam, LParam);
  StrResult := StrResult + Chr(PKbdDllHookStrukt(LParam)^.vkCode);
end;


procedure TForm1.FormCreate(Sender: TObject);
const
  WH_KEYBOARD_LL = 13;
begin    
  hHook := SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0);
  Timer1.Enabled:=true;
  if hHook = 0 then RaiseLastOSError;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
if not UnhookWindowsHookEx(hHook) then RaiseLastOSError;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Clear;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var l,i,j:integer;
    c:char;
    str:string;
begin
str:=StrResult;
l:=length(Str);
if l=0 then exit;
if l>1 then
   begin
   c:=Str[1];
   i:=1;
   j:=2;
   while i<=l do
      begin
      while j<=l do
         begin
         if j=i then break;
        if Str[i]=Str[j] then
            begin
            delete(Str,j,1);
            l:=length(Str);;
            end;
         inc(j);
         end;
      j:=2;   
      inc(i);
      end;
   if l>1 then
      begin
      Memo1.Lines.Add('Íà÷àòû êëàâèøè:');
      for i:=1 to l do
          Memo1.Lines.Add(Str[i]+'  ('+inttostr(ord(Str[i]))+')');
      end;
   end;
StrResult := '';
end;

end.


только в этом коде (не до конца разобрался) глюк с удалением повторных символов (когда долго зажата клавиша)


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Albinos_x
Дата 28.12.2005, 00:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

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



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


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Poseidon
Дата 28.12.2005, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

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



Цитата(p0s0l @ 27.12.2005, 23:44)
Или если нужно проверить нажатие определенных кнопок - GetKeyState...
smile

Код

function LowLevelKeyboardProc(nCode: Integer;
  WParam: WPARAM; LParam: LPARAM): LRESULT stdcall;
begin
  if nCode = HC_ACTION then
    Result := CallNextHookEx(hHook, nCode, WParam, LParam);

   If ((GetKeyState(VK_CONTROL) AND 128)=128) and
      ((GetKeyState(80)      AND 128)=128) and
      ((GetKeyState(VK_Menu)   AND 128)=128)
   then
       Application.MessageBox('Нажаты Ctrl+Alt+P','Сработало!',MB_ICONWARNING+MB_SYSTEMMODAL);;
end;


Спасибо p0s0l smile


PS. Albinos_x, если честно, то твой вариант с таймором мягко говоря ....

Это сообщение отредактировал(а) Poseidon - 28.12.2005, 18:27


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Albinos_x
Дата 28.12.2005, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

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



Цитата(Poseidon @ 28.12.2005, 18:25)
PS. Albinos_x, если честно, то твой вариант с таймором мягко говоря ....

знаю...

PS: в этот раз колесо получилось прямоугольным smile

Это сообщение отредактировал(а) Albinos_x - 28.12.2005, 23:49


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.

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


 




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


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

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