Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Глобальный хук на клавиатуру без dll.


Страницы:   1 2 3

Cerberus ©   (2006-06-20 15:12:00) 

сабж


Leonid Troyanovsky   (2006-06-23 19:53:00) [21]


> programania ©   (23.06.06 19:44) [26]

> тем более что WH_KEYBOARD_LL у меня в D5 нет и


Дык, оно есть в NT4SP3+, о чем уж, вроде, говорилось.
Дельфи тут вовсе ни причем.

--
Regards, LVT.


Rouse_   (2006-06-23 19:52:00) [22]


> Похоже кроме меня никто не использовал RegisterHotKey
> так повторяю: назначенные клавиши вообще никогда не попадут
> в целевые оконные процедуры активного окна ни до ни после
> кто не верит может испытать программу по ссылке в [7]
> и нет тут никакого чуда
> просто все сделано для удобства решения типовой задачи

Молодой человек, вы не поторопились?
Давайте я переопределю задачу, поставленную begin...end чтобы вы четко поняли сам механизм.
Задача звучит так: При запуске нашей програмы предотвратить ввод данных в окно любого приложения до тех пор, пока не будет набранна комбинация "qwe" без кавычек в этом окне.

Вперед любезный...

Желаю успехов...


programania   (2006-06-23 19:44:00) [23]

> begin...end ©   (22.06.06 22:23) [21]

Спасибо за пример
Лучше бы его привести сразу в [6] раз это так просто
ведь не все понимают ваши намеки
тем более что WH_KEYBOARD_LL у меня в D5 нет и
видно вы описали ее только чтоб оправдать свой намек

>Тогда приведите его, пожалуйста

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

>Если Ваша "ловушка" заведомо будет получать НЕ ВСЕ сообщения,
>а только те, которые посылаются одному-единственному окну,
>то это уже будет совсем НЕ ГЛОБАЛЬНАЯ ловушка.

так и в вашем примере все сообщения получает одно окно TestForm
и уже потом посылает другим - CallNextHookEx
а у меня - SendMessage(GetForegroundWindow

>Игорь Шевченко ©   (23.06.06 09:53) [24]
>Дорогой друг, убедительная просьба рассказывать подобные сказки в другой аудитории.

Спасибо за совет Дорогой друг, я думал это форум для всех
И как же в вашей аудитории обьясняют наличие функции RegisterHotKey,
дублирующей SetWindowsHookEX,  наверно так: "пути господни неисповедимы"

>Rouse_ ©   (23.06.06 13:37) [25]

Похоже кроме меня никто не использовал RegisterHotKey
так повторяю: назначенные клавиши вообще никогда не попадут
в целевые оконные процедуры активного окна ни до ни после
кто не верит может испытать программу по ссылке в [7]
и нет тут никакого чуда
просто все сделано для удобства решения типовой задачи


Rouse_   (2006-06-23 13:37:00) [24]

Нет, вы погодите, я все-же хочу увидеть это чудо:

> Могу,
> причем именно до того, как они попадут в целевые оконные
> процедуры
> и хотя не уверен насчет всех сообщений,

Дерзай programania :)


Игорь Шевченко   (2006-06-23 09:53:00) [25]


> я думаю что создав SetWindowsHookEX ее создатели ужаснулись
> делу рук своих и решили что американский человек никогда
> этого не поймет и
> поэтому для самого типового использования ловушек и создали
> RegisterHotKey
> спрятав все хуки внутрь что вас и смутило


Дорогой друг, убедительная просьба рассказывать подобные сказки в другой аудитории. Совет такой добрый.


ANB   (2006-06-23 09:26:00) [26]

Глобальные низкоуровневые хуки на клавиатуру и мышу можно ставить прямо из своего экзешника. Пример есть MSDN, а подробности можно почитать в Рихтере (хорошо, что он есть на русском).


Leonid Troyanovsky   (2006-06-22 22:32:00) [27]


> programania ©   (22.06.06 21:39) [20]

> и можете не считать это глобальным хуком, но это работает


А можно мы будем звать оное по-старинке, т.е. aka hot key?
Заранее благодарны.


> и пора бы и вам предложить свое решение без dll


И почему, собс-но, пора?
Хотя, все уже украдено до нас: http://www.msdn.microsoft.com

--
Regards, LVT.


begin...end   (2006-06-22 22:23:00) [28]

> programania ©   (22.06.06 21:39) [20]

> Могу

Тогда приведите его, пожалуйста. Причём именно такое решение, в котором ловушка устанавливается функцией RegisterHotKey. И решение именно задачи, поставленной в [19], а не какой-либо другой.

> и хотя не уверен насчет всех сообщений,
> но те что получает FormKeyDown доходят

Это плохо. Если Ваша "ловушка" заведомо будет получать НЕ ВСЕ сообщения, а только те, которые посылаются одному-единственному окну, то это уже будет совсем НЕ ГЛОБАЛЬНАЯ ловушка.

> и пора бы и вам предложить свое решение без dll

Что ж, пожалуй, действительно, пора. Собственно, направление для поиска я дал ещё в [6]. А конкретный код может быть таким:

type
 TTestForm = class(TForm)
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   Hook: HHOOK;
 end;

var
 TestForm: TTestForm;

function HookProc(nCode, wParam, lParam: Integer): LRESULT; stdcall;
type
 PKBDLLHookStruct = ^TKBDLLHookStruct;
 TKBDLLHookStruct = packed record
   vkCode, scanCode, flags, time: Cardinal;
   dwExtraInfo: PCardinal;
 end;
const
 MsgNames: array [0..4] of string =
   ('UNKNOWN', 'WM_KEYDOWN', 'WM_KEYUP', 'WM_SYSKEYDOWN', 'WM_SYSKEYUP');
var
 I: Integer;
begin
 if nCode = HC_ACTION then
 begin
   case WParam of
     WM_KEYDOWN:     I := 1;
     WM_KEYUP:       I := 2;
     WM_SYSKEYDOWN:  I := 3;
     WM_SYSKEYUP:    I := 4;
   else
     I := 0
   end;
   with PKBDLLHookStruct(lParam)^ do
     TestForm.Caption := Format('Message: %s  Virtual code: %d  Scan code: %d', [MsgNames[I], vkCode, scanCode])
 end;
 Result := CallNextHookEx(0, nCode, wParam, lParam)
end;

procedure TTestForm.FormCreate(Sender: TObject);
const
 WH_KEYBOARD_LL = 13;
begin
 Hook := SetWindowsHookEx(WH_KEYBOARD_LL, @HookProc, HInstance, 0)
end;

procedure TTestForm.FormDestroy(Sender: TObject);
begin
 UnhookWindowsHookEx(Hook)
end;


P.S. Всё же не теряю надежды на то, что увижу Ваше решение.


programania   (2006-06-22 21:39:00) [29]

>begin...end ©   (22.06.06 20:05) [19]
>Так Вы можете решить её, или нет?

Могу,
причем именно до того, как они попадут в целевые оконные процедуры
и хотя не уверен насчет всех сообщений,
но те что получает FormKeyDown доходят, а другие вряд ли кому нужны
и имеено глобально: например я это это использовал для регулировки
громкости своего плеера и захвата экрана во время Direct3D и OpenGL игр
а если нужно обработать и передать дальше так вы и сами знаете как
и можете не считать это глобальным хуком, но это работает
и пора бы и вам предложить свое решение без dll


begin...end   (2006-06-22 20:05:00) [30]

> programania ©   (22.06.06 19:26) [18]

> RegisterHotKey не так универсальна как SetWindowsHookEX
> и можете называть ее как хотите, но она решает ту же задачу
> для клавиатуры проще

Какую "ту же задачу"? Я в [10] попросил Вас решить задачу, а в [15] повторил просьбу. Могу повторить условие ещё раз: перехватывать ВСЕ сообщения WM_KEYDOWN до того, как они попадут в целевые оконные процедуры.

Вы только что (в [18]) согласились с тем, что эта задача -- типичная для использования хуков. Ранее (в [7] и [9]) Вы утверждали, что установить глобальный хук можно функцией RegisterHotKey.

Получается, что задачу, о которой я говорю, можно решить за счёт этой функции. Так Вы можете решить её, или нет? Жду ответа.


programania   (2006-06-22 19:26:00) [31]

>begin...end ©   (21.06.06 22:35) [15]
>К сожалению, это типичная задача, для которой используются ловушки.

Совершенно верно,
я думаю что создав SetWindowsHookEX ее создатели ужаснулись
делу рук своих и решили что американский человек никогда этого не поймет и
поэтому для самого типового использования ловушек и создали RegisterHotKey
спрятав все хуки внутрь что вас и смутило

>перехватывать WM_KEYDOWN до того, как оно попадёт в оконную процедуру.

при использовании RegisterHotKey, WM_KEYDOWN вообще не попадает
в процедуру активного окна, а только в процедуру окна указаного при регистрации
поэтому я и решил что вам нужно все-таки передать в активное окно

>Правда, непонятно, зачем перехваченное нажатие куда-то посылать
>-- при использовании хука оно само дойдёт туда, куда надо

Так вы же просили: "т.е. с помощью функции RegisterHotKey." [10]

>а вместо этого согласиться с тем, что RegisterHotKey к установке
>глобальных клавиатурных хуков отношения не имеет

Тут я могу согласиться что RegisterHotKey не так универсальна как SetWindowsHookEX
и можете называть ее как хотите, но она решает ту же задачу для клавиатуры проще
и не требует dll что и нужно для решения вопроса темы

>ors_archangel ©   (22.06.06 16:24) [16]
Надо AttachThreadInput попробовать, чёрт, у меня щас delphi нет под рукой!!!

После AttachThreadInput программа конечно будет получать все нажатия
но только потому что получит фокус, а для клавиатурного шпиона это недопустимо


begin...end   (2006-06-22 18:43:00) [32]

> ors_archangel ©   (22.06.06 16:24) [16]

Надеюсь, Вас тоже не затруднит привести рабочий пример установки ГЛОБАЛЬНОГО хука с помощью AttachThreadInput.


ors_archangel   (2006-06-22 16:24:00) [33]

Надо AttachThreadInput попробовать, чёрт, у меня щас delphi нет под рукой!!!


begin...end   (2006-06-21 22:35:00) [34]

> programania ©   (21.06.06 19:36) [13]

> К сожалению мне пока не требовалось решать такие задачи

К сожалению, это типичная задача, для которой используются ловушки. Непонятно, почему Вы считаете возможным давать советы, не имея опыта решения даже типичных задач по теме вопроса.

> да я и не понял что вам еще конкретно нужно

Странно. По-моему, в [10] задание сформулировано достаточно чётко: перехватывать WM_KEYDOWN до того, как оно попадёт в оконную процедуру.

> возможно вы не знаете как передать перехваченное
> нажатие активному окну, так это можно сделать примерно так
> SendMessage(GetForegroundWindow,WM_CHAR,wparam,0);

Спасибо, но с тем, как послать сообщение окну, я, слава Аллаху, знаком. Правда, непонятно, зачем перехваченное нажатие куда-то посылать -- при использовании хука оно само дойдёт туда, куда надо (после того, как на него посмотрят внутри функций цепочки ловушек).

> однако мне кажется что вы и сами прекрасно разберетесь

К сожалению, Вы ошибаетесь. Без Вас разобраться в том, как можно функцией RegisterHotKey установить глобальный хук на клавиатуру, мне вряд ли удастся. Поэтому всё же хотелось бы увидеть решение задачи -- думаю, оно будет интересно не только мне.

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

Жду ответа.


Yanis   (2006-06-21 19:45:00) [35]


> возможно вы не знаете как передать перехваченное
> нажатие активному окну

:D


programania   (2006-06-21 19:36:00) [36]

>begin...end ©   (20.06.06 21:53) [10]

К сожалению мне пока не требовалось решать такие задачи
да я и не понял что вам еще конкретно нужно
возможно вы не знаете как передать перехваченное
нажатие активному окну, так это можно сделать примерно так
SendMessage(GetForegroundWindow,WM_CHAR,wparam,0);
однако мне кажется что вы и сами прекрасно разберетесь


Rouse_   (2006-06-21 13:22:00) [37]


> Если в Windows произойдет событие нажатия заданой клавиши,
>  
> то будет вызвана заданная процедура это и есть hook на это
> событие

Поразительно, вот уж не знал что это тоже называется хуком.
Рихтер нервно курит в сторонке :)


Elen   (2006-06-21 11:54:00) [38]


> Cerberus
Глобальный хук на клавиатуру без dll.

А чем DLL мешает?


begin...end   (2006-06-20 21:53:00) [39]

> programania ©   (20.06.06 20:30) [9]

Разумеется, Вы можете называть карандаш ластиком, а ластик -- карандашом. Правда, от этого карандаш не начнёт стирать, а ластик не начнёт писать, но это, по-видимому, Вас не очень беспокоит.

Я же при описании чего-либо предпочитаю пользоваться  либо терминологией того, кто это "что-либо" создал, либо общепринятой терминологией. В данном случае -- терминологией Microsoft, которая, во-первых, введена "создателем" ОС, в которой эти самые хуки и устанавливаются, а во-вторых, является практически общепринятой. В MSDN написано следующее: "A hook is a point in the system message-handling mechanism where an application can install a subroutine to monitor the message traffic in the system and process certain types of messages before they reach the target window procedure."

Допустим, я хочу отслеживать сообщения WM_KEYDOWN (monitor the message traffic in the system) и, если нужно, изменять параметры этих сообщений до того, как они будут попадать в соответствующие оконные процедуры (process certain types of messages before they reach the target window procedure). Причём хочу отслеживать сообщения, отправляемые любому из потоков в системе. То есть, хочу установить глобальный хук на клавиатуру (по терминологии Microsoft).

Так вот -- если Вас не затруднит, приведите, пожалуйста, рабочее решение этой задачи с помощью глобального хука, но уже по Вашей терминологии, т.е. с помощью функции RegisterHotKey. Желаю успеха, и с нетерпением жду Вашего ответа.


programania   (2006-06-20 20:30:00) [40]

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


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо