![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Глобальный хук на клавиатуру без dll.
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