| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C++ Builder > Создание компонента. Сообщения... |
| Автор: dencraft 16.5.2011, 16:52 | ||||
| Что-то я совсем запутался Пишу новый компонент на основе базового. Нужно переопределять стандартные действия над компонентом UpDown. При нажатии на мышу должно отрабатывать мое событие, а событие компонента не должно. Вроде сделал - все работает. Но как только добавил второй экземпляр компонента на форму - начались проблемы. На сообщения стал отвечать именно второй компонент, первый стал работать стандартно. Внутри компонента я переопределил методы Application->OnMessage и Form->WindowProc. Ламерский вопрос но все же....В чем различие между этими обработчиками Application->OnMessage и Form->WindowProc. Так есть ли разница где размещать код в этих обработчиках. И как определять в каком я нахожусь объекте. Узнать например какой у меня HWND компонента к которому пришло сообщение кусок кода:
и дальше я реализую новые возможности тут
|
| Автор: dencraft 16.5.2011, 17:59 | ||
Вот еще. Кажется начинаю понимать где собака зарылась....
Получается когда выполняется конструктор, он изменяет указатели на методы обработки сообщений. Но тогда как быть со вторым компонентом и последующими? При выполнении конструктора второго компонента, он затирает FOwnerForm->WindowProc новым своим значением. И сообщения идут уже последнему компоненту обновившему FOwnerForm->WindowProc. Как тут быть? |
| Автор: borisbn 17.5.2011, 09:42 | ||
переопределять WindowProc не Owner'а, а свой
а зачем вообще перехватывать все сообщения приложения (Application->OnMessage) ? |
| Автор: dencraft 17.5.2011, 11:21 |
| А мне нужно перехватывать сообщение мыши за пределами компонента и даже формы. По сути у меня все работает через SetCapture(Application->Handle); Я в Application->OnMessage перехватываю сообщения WM_SETCURSOR, далее относительно него, я уже определяю какая кнопка была нажата. Дело в том, что мне нужно еще отловить момент отпускания кнопки, который может быть не только над данным компонентом, но и над главной формой или за ее пределами, или другим компонентом. Через пары BEGIN_MESSAGE_MAP/END_MESSAGE_MAP не получается перехватить отпускание мыши над другими компонентами. И почему-то не работает SetCapture(Application->Handle). |
| Автор: borisbn 17.5.2011, 13:48 | ||||
для этого существует TApplicationEvents. делаешь так
|
| Автор: dencraft 23.5.2011, 03:10 |
| C TApplicationEvents получилось. Но не до конца. Это по сути то тот же WinProc в удобной оболочке. Но уже вроде работает раздельно. Но все же одна проблема осталась. Я пользуюсь SetCapture(...) для перехвата всех сообщений мыши, даже если она вышла за пределы компонента, над которым я нажал кнопку мыши. Но вот за пределами главного окна программы, сообщения уже идут мимо приложения, т.е. мимо WinProc. Вот поэтому я тогда и использовал переопределенный обработчик Application->OnMessage. Только туда направляются все сообщения WM_MOUSEMOVE даже если мышь за пределами главного окна. Это работает только при нажатии кнопки и удержании ее в нажатом положении при перемещении курсора за пределы главного окна приложения. Хотелось бы все реализовать независимо от основного приложения. Но похоже тут придется писать какой-нибудь ретранслятор сообщений компонентам. Что-то вроде автоматической рассылки сообщений из сообщений приложения этому компоненту если совпадает его Handle. Не хотелось бы, т.к. это разрушает саму идею компонента - "все в одном". |
| Автор: dencraft 30.5.2011, 16:34 |
| Решил проблему несколько по-другому. Может кому будет интересно. Использую TApplicationEvents. При нажатии кнопки мыши запускается таймер и SetCapture(). По этому таймеру я определяю координаты мыши через GetCursorPos(). SetCapture нужен для того чтобы отлавливались сообщения об отпускании мыши за пределом текущего компонента. Вот собственно и все. И без переопределения WinProc и Application->OnMessage. Все замечательно работает в любом количестве этих компонентов на форме. Также, кому интересно, что это было и для чего. Это Spinner, созданный на основе TUpDown, значение Position которого можно менять не только нажатием на стрелки Up и Down, но и перетаскиванием мыши вверх и вниз. Если курсор выходит за край экрана, то он перебрасывается на противоположную сторону, тем самым обеспечивается бесконечное прокручивание. Весьма удобно для интерактивного изменения параметров и отображения результата в окне. Далее буду прикручивать к нему уже TEdit, работу с Float, округлением и может еще чего. |