![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Блокировка клавиш! [D5, Win95/98]
ЛамерОК © (2002-01-07 19:41:00)Как мне в моей программе заблокировать все клавиши, кроме ENTER?? А на OnCloseQuery - разблокировать?
если такое, конечно возможно!
Vovchik (2002-01-09 14:36:00) [21]Удалено модератором
Виктор Щербаков (2002-01-09 14:34:00) [22]to Vovchik
Тебе с другими профессионаламинадо было поконсультироваться.
Vovchik (2002-01-09 14:18:00) [23]Удалено модератором
Юрий Зотов (2002-01-09 14:11:00) [24]Увы, бесполезно. А значит, бессмыссленно.
До свидания.
Vovchik (2002-01-09 14:04:00) [25]Удалено модератором
Юрий Зотов (2002-01-09 12:09:00) [26]Только что прочитал сообщение Vovchik © (08.01.02 21:43). Волосы дыбом.
> Но, как я понял...
Тут не надо ДОГАДЫВАТЬСЯ, механизм подключения DLL надо просто ЗНАТЬ. Почему не открыть книжку, вместо того, чтобы строить СВОИ предположения?
> ...под 9х при хуке происходит вызов DllEntryPoint с параметром DLL_PROCESS_ATTACH.
Не только под 9x, а под ЛЮБОЙ Win32. И не только при хуке, а при проецировании ЛЮБОЙ DLL. Это, извините, азбука, которую тоже надо просто ЗНАТЬ.
> Так вот, под опреационными системами (я хотел сказать под
> NT/2K) этот вызов НЕ происходит
В самом деле? То есть, DllEntryPoint с DLL_PROCESS_ATTACH под NT/2K НЕ вызывается?
Огромная просьба - в дальнейшем, прежде, чем утверждать подобную, извините, чушь почитайте все же книжки. Видите ли, все системы работают все же так, как они работают. А не так, как Вы себе их работу представляете.
И уж во всяком случае, не стоит вступать в спор по тем вопросам, в которых Вы, мягко говоря, пока еще не очень сильны. Ни с Зотовым, ни с Ивановым, ни с Сидоровым - вообще с кем бы то ни было.
Надеюсь, этот постинг вызовет у Вас достаточную обиду для того, чтобы упереться и засесть за книжки. И еще надеюсь, что Вы достаточно умны и объективны для того, чтобы обидеться на самого себя, а не на кого-либо другого.
Успехов. Это искренне.
Raptor (2002-01-08 23:46:00) [27]Привет, всем!
Да что там говорить и тестировать. Пример полностью правильный и правильно работает под любые Win. А корректный и работоспособный пример глобального клавиатурного хука давно уже лежит в FAQ по ссылке
http://delphi.mastak.ru/cgi-bin/faq.pl?look=1&id=15-988619882.Он написан по образцу примера который привел Юрий Зотов, и специально поставлен в FAQ, что бы начинающие могли разобраться на корректном примере. Только вот начинающие чего-то упорно не хотят заглядывать в этот самый FAQ который для них, собственно, и написан. А зря...
2Vovchik
Советую сначала разобраться что к чему, а потом уже говорить что оно работает неправильно. Надо делать именно так как указал Юрий Зотов. Безо всяких импровизаций. Тогда все у тебя получится.
Raptor.
Юрий Зотов (2002-01-08 22:42:00) [28]> 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
Dimaond Cat (2002-01-08 22:21:00) [29]Посмотрел на продолжения данного спора и подивился, вопрос-то собственно был о том как заблокировать клавиши в своей программе нафига тогда вообще городить весь огород с глобальным перехватчиком, когда можно обойтись блокировкой сообщений типа wm_keydown wm_char и т.д. в конце концов этоже своя программа другие нас не волнуют!!!
2 Юрий Зотова ты мне так и не написал -:о[]
Vovchik (2002-01-08 21:43:00) [30]Удалено модератором
Vovchik (2002-01-08 21:26:00) [31]Удалено модератором
Vovchik (2002-01-08 20:47:00) [32]Удалено модератором
Юрий Зотов (2002-01-08 20:23:00) [33]> В SDK ничего такого не написано.
Написано. Но не на ЭТОЙ странице. В SDK, помимо описания ФУНКЦИЙ содержится еще и описание КОНЦЕПЦИЙ. И предполагается, что человек, программирующий под Win32 эти концепции прочел, понял и запомнил. А если человек понял, что такое процессы, адресные пространства, проецирование EXE и DLL и пр., то и тонкости глобальных хуков становятся ему вполне понятны.
Юрий Зотов (2002-01-08 20:14:00) [34]> 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" и других подобных.
Кричать мы все горазды. Но сделайте СВОЕ и сделайте ЛУЧШЕ. Вот когда Вы это СДЕЛАЕТЕ - тогда и получите право так говорить. А до тех пор - извините, но лучше помолчать.
Vovchik (2002-01-08 19:29:00) [35]Удалено модератором
Vovchik (2002-01-08 19:05:00) [36]Удалено модератором
Юрий Зотов (2002-01-08 17:12:00) [37]> Vovchik © (08.01.02 16:37)
> Между прочим, не у меня одного это не получалось.
Угу, я в курсе. Потому что видел эту ошибку десятки раз. Так оно и есть - не учтено разделение адресных пространств процессов.
Дело в том, что переменная FH получит правильное значение ТОЛЬКОв контексте одного-единственного процесса - того, который вызвал SetWindowsHookEx (то есть, ТОЛЬКОдля Вашей программы). Для всех же остальных эта переменная останется нулем и поэтому ловушка сможет отослать сообщение WM_USER+1 ТОЛЬКОкогда активна Ваша программа. Что мы и наблюдаем на практике.
Именно поэтому в примере я и поместил хэндл окна-приемника в memory mapped file - то есть, сделал его доступным ВСЕМпроцессам. Абсолютно то же самое касается переменной HP.
Вы же писали, что сделали все как в примере - оказывается, нет, самое главное Вы как раз и выбросили. Сделайте все ТОЧНОтак же, должно работать.
Виктор Щербаков (2002-01-08 16:49:00) [38]FH - своя для каждого процесса.
Vovchik (2002-01-08 16:37:00) [39]Удалено модератором
Юрий Зотов (2002-01-08 15:06:00) [40]> Ловит, если активный.
Практически уверен в том, что ЛОВИТ как раз всегда, но способна правильно СООБЩИТЬ об этом только когда активна Ваша программа.
Приведите код, тогда можно будет сказать точно.