Страницы: 1 2 вся ветка
Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.11;
Скачать: [xml.tar.bz2];




Вниз

Блокировка клавиш! 


ЛамерОК   (2002-01-07 19:41) [0]

Как мне в моей программе заблокировать все клавиши, кроме ENTER?? А на OnCloseQuery - разблокировать?
если такое, конечно возможно!



Юрий Зотов   (2002-01-08 11:26) [1]

И снова SetWindowsHookEx.



Vovchik   (2002-01-08 12:29) [2]

Удалено модератором



Юрий Зотов   (2002-01-08 12:48) [3]

> Vovchik © (08.01.02 12:29)

Почти наверняка - не была учтена изолированность адресных пространств процессов (стандартная ошибка).

Загляните сюда:
http://delphi.mastak.com/cgi-bin/forum.pl?look=1&id=992616736&n=2



Vovchik   (2002-01-08 14:59) [4]

Удалено модератором



Юрий Зотов   (2002-01-08 15:06) [5]

> Ловит, если активный.

Практически уверен в том, что ЛОВИТ как раз всегда, но способна правильно СООБЩИТЬ об этом только когда активна Ваша программа.

Приведите код, тогда можно будет сказать точно.



Vovchik   (2002-01-08 16:37) [6]

Удалено модератором



Виктор Щербаков   (2002-01-08 16:49) [7]

FH - своя для каждого процесса.



Юрий Зотов   (2002-01-08 17:12) [8]

> Vovchik © (08.01.02 16:37)

> Между прочим, не у меня одного это не получалось.

Угу, я в курсе. Потому что видел эту ошибку десятки раз. Так оно и есть - не учтено разделение адресных пространств процессов.

Дело в том, что переменная FH получит правильное значение ТОЛЬКО в контексте одного-единственного процесса - того, который вызвал SetWindowsHookEx (то есть, ТОЛЬКО для Вашей программы). Для всех же остальных эта переменная останется нулем и поэтому ловушка сможет отослать сообщение WM_USER+1 ТОЛЬКО когда активна Ваша программа. Что мы и наблюдаем на практике.

Именно поэтому в примере я и поместил хэндл окна-приемника в memory mapped file - то есть, сделал его доступным ВСЕМ процессам. Абсолютно то же самое касается переменной HP.

Вы же писали, что сделали все как в примере - оказывается, нет, самое главное Вы как раз и выбросили. Сделайте все ТОЧНО так же, должно работать.



Vovchik   (2002-01-08 19:05) [9]

Удалено модератором



Vovchik   (2002-01-08 19:29) [10]

Удалено модератором



Юрий Зотов   (2002-01-08 20:14) [11]

> Vovchik © (08.01.02 19:05)

Открываем MSDN (раздел LowLevelKeyboardProc), жмем кнопку Requirements и читаем:

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Unsupported.

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

Остается разве что добавить 2 вещи.

1. Win9x/ME НЕ КРИВЫЕ, они просто ДРУГИЕ.
2. Я предпочитаю писать код, который работает в ЛЮБОЙ Win32 и с ЛЮБЫМ SP. А что предпочитаете Вы - это дело Ваше.

По поводу разделения адресных пространств.

> По хорошему должно быть сделано так, чтобы сначала клавиши
> хватало ядро, которое потом смотрит, чего в очереди
> обслуживания клавиш есть, и отдаёт...

Так оно и сделано. Но никто же не виноват в том, что Вы засунули хэндл окна в переменную внутри DLL, а потом почему-то захотели, чтобы этот хэндл был доступен ВСЕМ процессам. Это же DLL, у нее нет СОБСТВЕННОГО адресного пространства, она использует адресное пространство самой программы. И это ГЛОБАЛЬНЫЙ хук, он обслуживает ВСЕ процессы - а они ИЗОЛИРОВАНЫ и, значит, он ДОЛЖЕН быть спроецирован в КАЖДЫЙ, иначе он просто НЕ СМОЖЕТ быть ГЛОБАЛЬНЫМ. А поскольку никакая другая программа, кроме Вашей, SetWindowsHookEx не вызывала, то и взять им этот хэндл негде. То есть, что Вы сами написали - то и получили.

И по поводу возгласов типа "отстой", "масдай", "надстройка над DOS" и других подобных.

Кричать мы все горазды. Но сделайте СВОЕ и сделайте ЛУЧШЕ. Вот когда Вы это СДЕЛАЕТЕ - тогда и получите право так говорить. А до тех пор - извините, но лучше помолчать.



Юрий Зотов   (2002-01-08 20:23) [12]

> В SDK ничего такого не написано.

Написано. Но не на ЭТОЙ странице. В SDK, помимо описания ФУНКЦИЙ содержится еще и описание КОНЦЕПЦИЙ. И предполагается, что человек, программирующий под Win32 эти концепции прочел, понял и запомнил. А если человек понял, что такое процессы, адресные пространства, проецирование EXE и DLL и пр., то и тонкости глобальных хуков становятся ему вполне понятны.



Vovchik   (2002-01-08 20:47) [13]

Удалено модератором



Vovchik   (2002-01-08 21:26) [14]

Удалено модератором



Vovchik   (2002-01-08 21:43) [15]

Удалено модератором



Dimaond Cat   (2002-01-08 22:21) [16]

Посмотрел на продолжения данного спора и подивился, вопрос-то собственно был о том как заблокировать клавиши в своей программе нафига тогда вообще городить весь огород с глобальным перехватчиком, когда можно обойтись блокировкой сообщений типа wm_keydown wm_char и т.д. в конце концов этоже своя программа другие нас не волнуют!!!
2 Юрий Зотов а ты мне так и не написал -:о[]



Юрий Зотов   (2002-01-08 22:42) [17]

> Vovchik © (08.01.02 20:47)


> Могу утверждать, что нашёл ошибку в примере Юрия Зотова.

И зря Вы это утверждаете. Сейчас докажу.


> Но ведь никакой оазницы нет передавать хэндлы как глобальные
> переменные или указатель, который тоже будет неопределён для
> всех процессов, отличных от процесса, породившего хук!

Естественно, никакой разницы нет (точнее, все же есть - передавать указатели еще хуже). Но где же Вы нашли то место в коде, где, как Вы утверждаете, указатель передается между процессами? Можете показать пальцем? Боюсь, что вряд ли. Потому что такого там просто НЕТ.


> А Вы можете протестировать ваш пример под NT.

Еще раньше я тестировал его под 98SE, ME и NT4+SP6. И только что протестировал еще раз, под 2kPro (надеюсь, этого достаточно?). Везде пример работал без малейших проблем, а результат последнего теста см. ниже.

> ... поставьте ShowMessage(IntToStr(Integer(Data))).
> И Вы убедитесь, что он равен 0!

Хотя это и плохой способ тестирования (кто хочет понять, почему он плохой, пусть повторит - увидит сам), но я решил сделать строго как Вы сказали. И поставил. И убедился, что никаких нулей там нет и в помине. По крайней мере у МЕНЯ нет, а у ВАС - не знаю.

Собственно, ничего этого можно было и не проверять. Потому что Pointer(0) - это nil, а если Data=nil, то что дадут выражения Data^.AppWnd и Data^.OldHook? Ту самую Access Violation, конечно. Однако же, не дают ведь, вот в чем штука-то.

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

function ShellHook(Code: Integer; ParamW: WPARAM; ParamL: LPARAM): LRESULT; stdcall;
begin
if (Code in [HSHELL_WINDOWCREATED, HSHELL_WINDOWDESTROYED, HSHELL_REDRAW]) and (Data <> nil) then
SendMessage(Data^.AppWnd, WM_USER, ParamW, Code);
Result := CallNextHookEx(Data^.OldHook, Code, ParamW, ParamL)
end;

И убедитесь, что все по-прежнему прекрасно работает.


> Видимо, под НТ разделение как раз ещё большее,
> т.е. более грамотное!

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

Знаете шоферскую поговорку?
"Дело было не в бобине - ... (программист?) сидел в кабине".


> All

Желающим протестировать пример предлагаю скопировать код и запустить, не внося НИКАКИХ изменений. А результаты сообщить сюда.

Код и все пояснения к нему находятся здесь:
http://delphi.mastak.com/cgi-bin/forum.pl?look=1&id=992616736&n=2



Raptor   (2002-01-08 23:46) [18]

Привет, всем!

Да что там говорить и тестировать. Пример полностью правильный и правильно работает под любые Win. А корректный и работоспособный пример глобального клавиатурного хука давно уже лежит в FAQ по ссылке
http://delphi.mastak.ru/cgi-bin/faq.pl?look=1&id=15-988619882. Он написан по образцу примера который привел Юрий Зотов, и специально поставлен в FAQ, что бы начинающие могли разобраться на корректном примере. Только вот начинающие чего-то упорно не хотят заглядывать в этот самый FAQ который для них, собственно, и написан. А зря...

2Vovchik
Советую сначала разобраться что к чему, а потом уже говорить что оно работает неправильно. Надо делать именно так как указал Юрий Зотов. Безо всяких импровизаций. Тогда все у тебя получится.

Raptor.



Юрий Зотов   (2002-01-09 12:09) [19]

Только что прочитал сообщение Vovchik © (08.01.02 21:43). Волосы дыбом.


> Но, как я понял...

Тут не надо ДОГАДЫВАТЬСЯ, механизм подключения DLL надо просто ЗНАТЬ. Почему не открыть книжку, вместо того, чтобы строить СВОИ предположения?


> ...под 9х при хуке происходит вызов DllEntryPoint с параметром DLL_PROCESS_ATTACH.

Не только под 9x, а под ЛЮБОЙ Win32. И не только при хуке, а при проецировании ЛЮБОЙ DLL. Это, извините, азбука, которую тоже надо просто ЗНАТЬ.


> Так вот, под опреационными системами (я хотел сказать под
> NT/2K) этот вызов НЕ происходит

В самом деле? То есть, DllEntryPoint с DLL_PROCESS_ATTACH под NT/2K НЕ вызывается?

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


И уж во всяком случае, не стоит вступать в спор по тем вопросам, в которых Вы, мягко говоря, пока еще не очень сильны. Ни с Зотовым, ни с Ивановым, ни с Сидоровым - вообще с кем бы то ни было.

Надеюсь, этот постинг вызовет у Вас достаточную обиду для того, чтобы упереться и засесть за книжки. И еще надеюсь, что Вы достаточно умны и объективны для того, чтобы обидеться на самого себя, а не на кого-либо другого.

Успехов. Это искренне.



Vovchik   (2002-01-09 14:04) [20]

Удалено модератором



Юрий Зотов   (2002-01-09 14:11) [21]

Увы, бесполезно. А значит, бессмыссленно.
До свидания.



Vovchik   (2002-01-09 14:18) [22]

Удалено модератором



Виктор Щербаков   (2002-01-09 14:34) [23]

to Vovchik
Тебе с другими профессионалами надо было поконсультироваться.



Vovchik   (2002-01-09 14:36) [24]

Удалено модератором



nikkie   (2002-01-09 15:28) [25]

>Vovchik
цитата из MSDN (с инета - в моей локальной версии от 1998 такого текста нет). я думаю она снимает вопрос почему WH_KEYBOARD_LL работал с твоим кодом.

...The keyboard input can come from the local keyboard driver or from calls to the keybd_event function. If the input comes from a call to keybd_event, the input was "injected". However, the WH_KEYBOARD_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.



Vovchik   (2002-01-09 15:33) [26]

Удалено модератором



Виктор Щербаков   (2002-01-09 15:53) [27]

>Там же ядро ДОСовое (что бы не говорил ЮЗ).
Ядро там не досовое, а Юрий Зотов правильно тебе говорил - книжки надо читать.



Vovchik   (2002-01-09 15:54) [28]

Удалено модератором



Виктор Щербаков   (2002-01-09 15:56) [29]

Обыкновенное ядро многозадачной операционной системы.



Vovchik   (2002-01-09 16:00) [30]

Удалено модератором



Виктор Щербаков   (2002-01-09 16:17) [31]

По-моему ядро Вин9х - это библиотека kernel32.dll.
Какое отношение к ДОСу она имеет?



XM-AD   (2002-01-09 18:06) [32]

На сколько я знаю (конечно же я могу и ошебаться, я винды не писал :), а что там в нутри знают только программеры Microsoft-a)Windows Me и Windows 95/98 основаны на MS-DOS и являются 16/32-битными ОС-ками. 9х загружается из -MSDOS-, она достраивает ядро и командный процессор системы MS-DOS собственными ядром и графическим интерфейсом. M$-еры сделали все возможное для того, чтобы скрыть MS-DOS Prompt в Windows Me однако DOS полностью находится в недрах Me, так же как и в предыдущих версиях 9x.
>>>По-моему ядро Вин9х - это библиотека kernel32.dll
Да, и плюс еще User32.dll и GDI32.dll



Vovchik   (2002-01-09 20:02) [33]

Удалено модератором



Юрий Зотов   (2002-01-09 20:52) [34]

Да, уж... знаток, что и говорить. Ну действительно, зачем знатоку читать книжки? Он и сам все знает. Правда, путает загрузчик с оболочкой, а ядро - вообще неизвестно с чем, но так это же неважно, верно?


> XM-AD
User и GDI к ядру не относятся. Ядро - это Kernel. Поэтому оно именно так и называется.


> Виктор Щербаков
Виктор, Вы еще собираетесь тратить время на этот бесполезный ликбез?


> Всем, ДЕЙСТВИТЕЛЬНО интересующимся архитектурой W9x и тем,
> насколько она базируется на DOS (а не просто специалистам по
> болтовне)

Рекомендую книгу "Windows 95 изнутри". Автора зовут Эндрю, вот фамилию уже не помню, слишком давно читал. В оригинале книга называлась "Windows 95 Unleashed". Весьма глубоко и, самое главное, основано на собственных исследованиях автора, а не на официальной документации Microsoft.



Vovchik   (2002-01-10 00:48) [35]

Удалено модератором



Виктор Щербаков   (2002-01-10 08:56) [36]

Да...
Теперь и я понял, что это бесполезно.



Юрий Зотов   (2002-01-10 12:40) [37]

> All

Мой последний постинг в эту ветку. Ну уж так смешно стало, что просто не выдержал (воистину, слаб человек...).

Сначала вспомним тривиальную и всем известную истину.

Если некая надстройка может работать без поддержки со стороны ядра, то, очевидно, такое "ядро" становится уже ненужным и его можно смело выгружать. Следовательно, если любая надстройка ДЕЙСТВИТЕЛЬНО является всего лишь НАДСТРОЙКОЙ, то без ядра она работать НЕ МОЖЕТ, а может работать только ОДНОВРЕМЕННО с ядром.

Теперь процитирую два следующих подряд утверждения уважаемого "знатока".

1. > 98х - это надстройка над дос, работающая в защищённом режиме.
2. > Ядро работает в реальном режиме!

Итак, по мнению все того же уважаемого "знатока", ядро 9x работает в реальном режиме (???!!!), а надстройка над ним - в защищенном.

Ну а поскольку, как мы выяснили, надстройка может работать только одновременно с ядром, то по все тому же мнению все того же уважаемого "знатока", CPU под 9x либо работает в реальном и в защищенном режимах ОДНОВРЕМЕННО (???!!!), либо, как минимум, почти непрерывно (???!!!) переключается из одного режима в другой.

Потому что (снова цитирую) "kernel32.dll - это всего лишь интерфейс между функциями ядра и пользовательскими программами". А если это так, то КАЖДОЕ (!!!) обращение к Kernel32 приводит к вызову ядра и мы тут же имеем 2 переключения - сначала в реальный режим, затем обратно (???!!!). А обращения к Kernel32, как известно, происходят очень часто.

Что сказать?

1. Бедняга CPU!
2. Ха-ха-ха!

Другие комментарии нужны?



Vovchik   (2002-01-10 21:25) [38]

Удалено модератором



KEP   (2002-01-10 23:06) [39]

Если вы думаете, что @@l тяжело распознать как метку, то это вы плохо знаете ассеммблер, ибо можно придумать более сложную метку.



Almaz   (2002-01-11 00:17) [40]

>Vovchik
>Настоящая ОС не вешается от такого:
>@@l: cli
> jmp @@l
В таком случае DOS - тоже не настоящая ОС, ибо она также виснет от этого кода.




модератор   (2002-01-11 07:56) [41]

>Vovchik
Хами твоим профессионалам.



Vovchik   (2002-01-11 20:03) [42]

Модератор ты _Д_Е_Р_Ь_М_А кусок, также как и Юрий Зотов!!!
Мог бы хоть не вмешиваться. В том, что ты удалил я как раз не хамил! Идиот!!!!!!



Vovchik   (2002-01-11 20:09) [43]

Модерато, ну ты вабще мудило! Я бы тебя самого удалил, сука!



Vovchik   (2002-01-11 20:11) [44]

>moderator
Юрий зотов тоже хамить умеет, его ты не удаляешь???????




Страницы: 1 2 вся ветка
Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.11;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.83 MB
Время: 0.073 c
7-32590           volph                 2001-11-13 15:45  2002.03.11  
Как завершить работу компьютера ?


14-32563          Егор                  2002-01-18 08:51  2002.03.11  
Microsoft Agent


1-32509           Igor_                 2002-02-25 12:50  2002.03.11  
Как определить сколько дней в заданном месяце


14-32556          Феликс                2002-01-25 18:49  2002.03.11  
Пилевин? Пробитый нарк-писатель или одно из двух?


4-32613           vvr                   2002-01-10 17:25  2002.03.11  
CREATECARET