![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Глобальный хук на клавиатуру без dll.
Cerberus © (2006-06-20 15:12:00)сабж
cerber (2006-10-29 16:31:00) [1]
> Leonid Troyanovsky © (28.10.06 14:52) [44]
Забыл скопировать:
Leonid Troyanovsky 9 Нояб. 2003 03:10
Группы новостей: fido7.ru.delphi.chainik
http://groups.google.com/group/fido7.ru.delphi.chainik/msg/ba088c4f6ad9649f
Приветствую, Denis.
LT> Установка системных WH_KEYBOARD_LL и WH_MOUSE_LL, т.е. хуков низкого
LT> уровня, не требуют библиотеки.
DVS> жаль только Delphi о них понятия не имеет.
Gero (2006-10-29 15:44:00) [2]> begin...end ©
Будь самим собой, не нужно изображать из себя Юрия Зотова. Ты изменился в худшую сторону.
PS: Это никоим образом не наезд на Юрия.
GrayFace (2006-10-29 15:41:00) [3]Еще есть WH_JOURNALRECORD.
programania © (20.06.06 20:30) [9]
Если в Windows произойдет событие нажатия заданой клавиши,
то будет вызвана заданная процедура это и есть hook на это событие
причем это произойдет при [b]любой[/b] активной программе
это и есть глобальный hook
В Morrowind, I of the Dragon к любым относятся? Хуки в них работают, горячие клавиши - нет. Соответственно, никаких хуков в RegisterHotKey не спрятано, оно работает по другому.
Хотя в какой-то игре и хуки не работают, поэтому я перехватывал клаву по таймеру в своей подсобной проге.
programania © (23.06.06 19:44) [26]
так и в вашем примере все сообщения получает одно окно TestForm
и уже потом посылает другим - CallNextHookEx
а у меня - SendMessage(GetForegroundWindow
Гы. Ну да, хуки - это, оказывается, таже окна...
Игорь Шевченко © (27.06.06 10:36) [42]
А GetKeyState относится к локальной очереди потока...
Но обычно он работает! В упомянутой подсобной проге вызывал по таймеру и управлял ВинАмпом и т.п. Перестает работать, например, когда установлен WH_JOURNALRECORD.
Psychedelic (2006-10-29 00:11:00) [4]Спасиб! Посмеялся хоть :))
Наивный programania и старающийся не выйти из себя begin..end
Leonid Troyanovsky (2006-10-28 14:52:00) [5]
> cerber (28.10.06 14:37) [43]
> Лови, студент!
Ты б хоть сослался.
Джефу Рихтеру, наверное, это пофигу,
а мне, как переводчику, было б приятно.
--
Regards, LVT.
cerber (2006-10-28 14:37:00) [6]Лови, студент!
const
WH_KEYBOARD_LL = 13;
WH_MOUSE_LL = 14;
LLKHF_EXTENDED = KF_EXTENDED shr 8;
LLKHF_INJECTED = $00000010;
LLKHF_ALTDOWN = KF_ALTDOWN shr 8;
LLKHF_UP = KF_UP shr 8;
LLMHF_INJECTED = $00000001;
{ Structure used by WH_KEYBOARD_LL }
type
tagKBDLLHOOKSTRUCT = packed record
vkCode : DWord;
scanCode : DWord;
flags : DWord;
time : DWord;
dwExtraInfo : PDWord;
end;
TKBDLLHOOKSTRUCT = tagKBDLLHOOKSTRUCT;
PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;
{ Structure used by WH_MOUSE_LL }
tagMSLLHOOKSTRUCT = packed record
pt : TPoint;
mouseData : DWord;
flags : DWord;
time : DWord;
dwExtraInfo : PDWord;
end;
tMSLLHOOKSTRUCT = tagMSLLHOOKSTRUCT;
PMSLLHOOKSTRUCT = ^TMSLLHOOKSTRUCT;
Вот, например, что когда-то предлагал Джеф Рихтер для
отключения любимых номеров (в вольном переводе):
function LowLevelKeyboardProc(nCode :Longint; awParam: WParam; alParam:
LParam): DWord; stdcall;
var
fEatKeystroke: Boolean;
p: PKBDLLHOOKSTRUCT;
buf: array [0..255] of Char;
sc: UINT;
begin
fEatKeystroke := False;
if (nCode = HC_ACTION) then
case (awParam) of
WM_KEYDOWN, WM_SYSKEYDOWN,
WM_KEYUP, WM_SYSKEYUP:
begin
p := PKBDLLHOOKSTRUCT(alParam);
fEatKeystroke :=
((p.vkCode = VK_TAB) and (p.flags and LLKHF_ALTDOWN <> 0)) or
((p.vkCode = VK_ESCAPE) and ((p.flags and LLKHF_ALTDOWN) <> 0)) or
((p.vkCode = VK_ESCAPE) and ((GetKeyState(VK_CONTROL) and $8000)
<>0));
end;
end;
if fEatKeystroke then
Result := 1
else
Result := CallNextHookEx(0, nCode, awParam, alParam);
end;
var
hhk: HHOOK;
procedure TForm1.Button1Click(Sender: TObject);
begin
hhk:= SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, Hinstance, 0);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
UnHookWindowsHookEx(hhk);
end;
Игорь Шевченко (2006-06-27 10:36:00) [7]
> У кого-нибудь повернется язык назвать это глобальным перехватом?
А GetKeyState относится к локальной очереди потока...
Elen (2006-06-27 07:59:00) [8]Хей Мастера! А как вам такой примерчик? :
procedure TForm1.Timer1Timer(Sender: TObject);
var i:word;
begin
for i:=0 to 255 do begin
if (GetKeyState(i)=-128) or (GetKeyState(i)=127) then begin
memo1.Lines.Append ( chr(i));
end else
end;
end;
У кого-нибудь повернется язык назвать это глобальным перехватом?
begin...end (2006-06-26 20:13:00) [9]> programania © (26.06.06 19:33) [39]
Мой пример ничего не блокирует, а только показывает, как можно посмотреть на интересующие сообщения до того, как они попадут в оконные процедуры. В том числе, и на сообщения от клавиш Ctrl, Alt и Del (даже нажатых вместе).
> кстати, Ваш пример в W98 вообще ничего не ловит
Совершенно верно -- мой пример не работает в Win98. Надеюсь, что ни для кого из читающих ветку, кроме Вас, это новостью не является, ведь я сам сказал об этом ещё в [6].
> а мой работает нормально
Совершенно верно -- Ваш пример работает в Win98. Правда, к теме ветки он не имеет ни малейшего отношения.
LOL.
programania (2006-06-26 19:33:00) [10]>begin...end © (26.06.06 13:13) [38]
>я не обещал намекнуть Вам, как заблокировать CAD.
так я нигде и не говорил что обещали,
я имел в виду любые сообщения от клавиатуры о которых Вы сказали достаточно
если CAD не то же самое, то извините
кстати, Ваш пример в W98 вообще ничего не ловит
а мой работает нормально
>Юрий Зотов © (25.06.06 12:02) [35]
>Наслаждался...
Вот специально обучил своего бота отвечать на вопросы
о delphi, программах и т.п. как тут это принято
спрашивайте и наслаждайтесь
http://programania.com/pi
жду новых забавных ответов, подходящих к любому вопросу
begin...end (2006-06-26 13:13:00) [11]> Юрий Зотов © (25.06.06 12:02) [35]
Чем?
> programania © (25.06.06 19:03) [36]
> Непонятно, правда, зачем в [10] нужно было говорить обратное,
> ну да ладно.
В [10] я не говорил обратного. А именно, я не обещал намекнуть Вам, как заблокировать CAD. Поэтому рекомендую Вам забрать свои слова обратно, пока не пришлось извиняться снова.
Игорь Шевченко (2006-06-26 10:46:00) [12]
> так оно и случилось, RegisterHotKey не устанавливается на
> ctrl+alt+del
Устанавливается. Только не всеми...
programania (2006-06-25 19:03:00) [13]>begin...end © (20.06.06 21:53) [34]
>Непонятно, правда, зачем в [20] нужно было говорить обратное
в [20] я как раз и намекал на этот случай
"и хотя не уверен насчет всех сообщений,"
так оно и случилось, RegisterHotKey не устанавливается на ctrl+alt+del
>Нет, не намекну
Непонятно, правда, зачем в [10] нужно было говорить обратное, ну да ладно.
"если нужно, изменять параметры этих сообщений до того,
как они будут попадать в соответствующие оконные процедуры ...
Причём хочу отслеживать сообщения, отправляемые любому из потоков в системе."
Юрий Зотов (2006-06-25 12:02:00) [14]> begin...end
Наслаждался...
:о)
begin...end (2006-06-24 19:32:00) [15]> programania © (24.06.06 19:28) [33]
> Извините все, но при помощи RegisterHotKey эту задачу решить
> не могу
Наконец-то. Непонятно, правда, зачем в [20] нужно было говорить обратное, ну да ладно.
> однако может намекнете...
Нет, не намекну.
programania (2006-06-24 19:28:00) [16]begin...end © (24.06.06 08:25) [32]
>Rouse_ © (23.06.06 19:52) [27]
> При запуске нашей програмы предотвратить ввод данных в окно любого приложения
> до тех пор, пока не будет набранна комбинация "qwe" без кавычек в этом окне.
Извините все, но при помощи RegisterHotKey эту задачу решить не могу
да и не обещал решать любые задачи
однако может намекнете как при помощи SetWindowsHookEX
предотвратить ввод ctrl+alt+del в любом окне
после чего нашу программу можно снять мышью
begin...end (2006-06-24 08:25:00) [17]> programania © (24.06.06 02:43) [31]
> Я могу только повторить что уже писал [18]
А я могу повторить то, что Вы писали в [20]: "Могу" . Вы утверждали, что можете решить [19]. Так можете, или нет? Если да, приведите решение. Если нет, извинитесь. Кажется, это я уже говорил...
> конечно можно придумать разные каверзные случаи
> неподходящие для нее
В задаче [19] нет ничего каверзного. Эта задача -- типичная для применения хуков. И Вы сами с этим согласились в [18]. А если RegisterHotKey не решает даже типичных задач из этой области -- вероятно, она предназначена для чего-то другого, не правда ли?
> однако для типового применения
> она вполне заменит SetWindowsHookEX
См. выше -- [19] представляет собой типовую задачу. Однако код, решающий её с помощью SetWindowsHookEx, уже есть (см. [21]), а кода, решаающего её функцией RegisterHotKey (которая, по Вашим словам, для типовых задач вполне заменяет SetWindowsHookEx), Вы пока почему-то не привели. Так за чем же дело стало?
> что я и предложил поскольку ничего лучше тогда еще никто
> не предложил
Вы невнимательно читаете. [6] было предложено ещё до того, как Вы появились в этой ветке.
> хотя и мог как оказалось и только благодаря моему упорству
> удалось получить информацию полезную многим
LOL.
> и это главная цель форума
> а все остальное никто и читать не будет
Давайте, всё-таки, поменьше слов и побольше дела. Либо код, либо извинения.
programania (2006-06-24 02:43:00) [18]>Rouse_ © (23.06.06 19:52) [27]
>Вперед любезный...
>begin...end © (23.06.06 20:45) [30]
>Жду ответа. Желательно в виде рабочего кода (причём по теме).
Я могу только повторить что уже писал [18]
RegisterHotKey не так универсальна как SetWindowsHookEX
и конечно можно придумать разные каверзные случаи
неподходящие для нее однако для типового применения
она вполне заменит SetWindowsHookEX для чего и предназначена
что я и предложил поскольку ничего лучше тогда еще никто не предложил
хотя и мог как оказалось и только благодаря моему упорству
удалось получить информацию полезную многим
в доступном всем виде и это главная цель форума
а все остальное никто и читать не будет
begin...end (2006-06-23 20:45:00) [19]> programania © (23.06.06 19:44) [26]
> Спасибо за пример
> Лучше бы его привести сразу в [6] раз это так просто
> ведь не все понимают ваши намеки
За пример -- пожалуйста. Однако право решать, когда МНЕ приводить СВОИ примеры (которых я никому не обещал), оставьте, пожалуйста, за МНОЙ . И мой "намёк" в [6] был вполне конкретен: поиск в MSDN по указанному ключевому слову даёт хорошие результаты, в которых остаётся лишь вдумчиво разобраться.
> тем более что WH_KEYBOARD_LL у меня в D5 нет
Вы будете смеяться, но у меня в D7 его тоже нет. Что, однако, не помешало мне написать рабочий пример. Ибо дело, как уже замечено в [28], совсем не в Delphi.
> видно вы описали ее только чтоб оправдать свой намек
Я описал эту константу для того, чтобы написать рабочий пример в виде нормально читаемого кода. Если Вы считаете, что я, приводя пример, перед кем-то оправдывался, то это Ваши проблемы.
> так и в вашем примере все сообщения получает одно окно TestForm
В моём примере ВСЕ сообщения WM_KEYDOWN (предназначенные ЛЮБОМУ из потоков в системе) получает функция ловушки HookProc (на то она, ловушка, и ГЛОБАЛЬНАЯ ). Потом эти сообщения уходят туда, куда они изначально направлялись -- в данном случае функция хука этому не мешает. А форма TestForm в примере используется лишь для демонстрации результата, и её можно было вообще выкинуть из кода -- сама ловушка от этого не стала бы работать хуже.
> так я уже привел все что мог и обьяснил что
> это вполне подходит для типовых случаев
Э... нет, уважаемый, так дело не пойдёт. Я в [19] сформулировал КОНКРЕТНУЮ задачу? Сформулировал. Вы в [20] сказали, что МОЖЕТЕ решить эту КОНКРЕТНУЮ задачу функцией RegisterHotKey? Сказали.
Однако пока что Вашего решения я не увидел. В чём же дело?
Поскольку у нас в форуме за свои слова принято отвечать (см. правила), повторю свою просьбу в N-й раз: приведите, пожалуйста, решение этой конкретной задачи (которая представляет собой установку глобального хука) своим способом, тем самым подтвердив своё заявление о том, что функцию RegisterHotKey можно использовать для установки этого самого глобального хука. Или, если у Вас нет решения и Вы не можете его написать, извинитесь перед автором темы.
> и уже потом посылает другим - CallNextHookEx
Функция CallNextHookEx никаким окнам (в том числе и "другим") никаких сообщений не посылает. Похоже, следует прислушаться к [29].
Жду ответа. Желательно в виде рабочего кода (причём по теме ), а не слов (причём не по теме ).
Игорь Шевченко (2006-06-23 19:57:00) [20]
> И как же в вашей аудитории обьясняют наличие функции RegisterHotKey,
>
> дублирующей SetWindowsHookEX, наверно так: "пути господни
> неисповедимы"
функция registerhotkey никоим образом не дублирует SetWindowsHookEx. Давайте так договоримся, вы немножко матчасть подучите, а потом мы с вами с удовольствием подискутируем. Просто в дискуссии хотелось бы рассчитывать на определенный уровень грамотности собеседника...
С наилучшими,