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

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

Блокировка клавиш! [D5, Win95/98]


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

ЛамерОК ©   (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]

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

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

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


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

Наверх

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