| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > "подменить" функцию WindowProc |
| Автор: Teleport 7.5.2009, 22:33 | ||
Как-то раз мне требовалось, чтобы компонент не реагировал на действия пользователя вообще никак, если курсор мышки находится над определенными координатами на компоненте. Вот какое решение мне предложили (на примере Button):
Все работает замечательно. Но сейчас мне требуется для многих компонетов сделать такое ограничение реагирования. Например для Button2 - не реагировать, если координаты x и y меньше 75. А для Button3 - не реагировать, если координаты курсора x и y менее 50. Попробовал просто продублировать код для других компонентов, например для Button2 и Button3, - да не тут то было. Компоненты не отображаются вообще. А при завершении приложения - выскакивают ошибки. Я и ожидал, что такое не сработает, так как у нас в FormCreate присваивание происходит... Как сделать? |
| Автор: Teleport 7.5.2009, 23:23 | ||||||
2 kami
Дублировал я не очень много. Сейчас покажу:
я понимаю, что написано внутри NewWindowProc. Это и есть тот самый единый принцип/формуа. Пробовал присваивание:
делать в событии MouseMove для каждого компонента- тоже не помогает... |
| Автор: kami 7.5.2009, 23:41 |
| А теперь посмотри внимательнее на NewWndProc. Она: 1. Становится стандартной виндовой процедурой для Button1 и Button2. 2. Вызвается при каждом сообщении, которое пришло для Button1 и Button2 3. А ВНУТРИ СЕБЯ ВЫЗЫВАЕТ СТАРУЮ ОКОННУЮ ФУНКЦИЮ Button1. Даже если это было сообщение для Button2. И чего же ты хочешь, собственно говоря от второй кнопки, когда ей ничего не доходит? Добавлено через 1 минуту и 55 секунд Вот именно, что "недопередублировал". Добавлено через 4 минуты и 55 секунд Видимо, не совсем понимаешь. Увы - нет. Принцип должен "выплыть" из Button1MouseMove и Button2MouseMove, которые должны слиться в одну и работать с тем, что за кнопка/другой компонент вызывал событие через Sender. |
| Автор: Teleport 7.5.2009, 23:51 |
| как дорога в тумане...)) почему второй кнопке ничего не доходит? |
| Автор: kami 7.5.2009, 23:58 |
Диктую по буквам, голосом, выпуклыми буквами, русским по экрану. 1. В FormCreate ты сохраняешь старые оконные функции для кнопки1 и для кнопки2. 2. Присваиваешь одну на двоих новую оконную функцию. 3. Теперь сообщения, которые пришли для кнопки1 и для кнопки2 будут проходить через NewWindowProc. 4. Смотрим в код NewWindowProc. Внимательно смотрим. 5. Проверяется куча условий, после чего если ни одно не выполнено вызываем "старую" оконную процедуру кнопки1. НО! Читаем внимательно пункт 3. Что будет, когда придет сообщение для кнопки2? (например, WM_Paint) ? Правильно, проверится куча условий и вызовется оконная процедура кнопки1. А на кой кнопке1 сообщение, которое должно было дойти кнопке2? Как результат - у кнопки1 пухнет голова от избытка информации, которая ей не нужна. Кнопка2 находится в неведении, что происходит - она не получила ни одного сообщения, не знает, в каком состоянии она находится, и тем более не может отслеживать ничего. |
| Автор: Teleport 8.5.2009, 00:42 |
| Тему считаю закрытой. |
| Автор: Rrader 8.5.2009, 06:42 |
| Teleport, если это для кнопки, то дело решается 0 строк кода, я тебе уже давал код. |
| Автор: kami 8.5.2009, 07:36 |
Можно ссылку? Мне тоже интересно. |
| Автор: Teleport 8.5.2009, 12:31 | ||||
| 2 Rrader - это когда я про прыжки ползунков на ScrollBox спрашивал? Типа хитрое наследование? Мне не для кнопки, а для листа TNextSheet. Вот в первом посту моем - рабочий код и для кнопки и для листа TNextSheet - если по отдельности. Но я не могу понять, как для двух компонетов сделать-то? по советам kami пришел к единой процедуре MouseMove:
но где сделать присваивание
и такое ли оно - не пойму. Пихал его в MouseMove - не прокатывает. Одни ошибки. |
| Автор: Rrader 8.5.2009, 13:27 | ||||
Вот, я это имел в виду. Надо сразу об этом говорить, потому что так легко запутать отвечающих. kami, имелось в виду сделать единую процедуру. И при каждой новодобавленной кнопке работать только в Object Inspector. Для этого примера - проставить Button1.Tag = 100, Button2.Tag = 75. Для второй кнопки выставляем OnMouseDown = Button1MouseDown.
Но Teleport нас обманул, поэтому для TNextSheet пусть сам думает |
| Автор: Teleport 8.5.2009, 15:28 |
| вопрос как подменить WindowProc для нескольких компонетов. ReleaseCapture - это я знаю. Но оно мне не надо. |
| Автор: kami 8.5.2009, 18:36 | ||
Гхм. А вы вообще представляете, что такое Sender? На всякий случай поясню - это компонент, вызывавший событие. В данном случае, в событии TForm1.FormCreate это Form1. И поясните тогда, свой код в этой процедуре, с учетом Sender=Form1. Ладно, поясню сам: 1. В этом событии Sender - это Form1. 2. C учетом (1) получаем FOldWindowProc := TButton(Form1).WindowProc; 3. Ничего не смущает? А именно - где Form1 и где TButton? В остальном, если comp_mouse_move - это OnMouseMove для Button1 и Button2 все нормально. Сделай прямое присваивание новых оконных ф-й в FormCreate для каждой кнопки и будет счастье. Вопрос "кому оно будет" - другой и подлежит переносу в другую ветку |
| Автор: Teleport 8.5.2009, 21:11 |
| вобщем, обойдусь дублированием для каждого компонента. |