| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > PageControl, прокрутка закладок |
| Автор: Seroga 29.10.2014, 10:47 | ||
| Здравствуйте! Собрался я сделать прокрутку мышью закладок у PageControl'а когда они выходят за границы выдимости, как это сделано в например в браузерах. То есть неважно где сейчас фокус, если наводишь мышь на область закладок и крутишь колесо мышки закладки прокручиваются. Другой пример Outlook из офиса, неважно где фокус, куда наводишь мышь в той области и делается прокрутка. Сделал для пробы отлова сообщения так:
Все работает в случае если фокус у компонента который лежит на PageControl'е. То есть тут работает цепочка по которой передается сообщение "выше" на парента и аж до формы. Но когда фокус у контрола который лежит рядом, например на панели, WM_MOUSEWHEEL на PageControl не приходит. Вариант заюзать TApplication.OnMessage нежелателен. Можно ли как-то еще отловить сообщение WM_MOUSEWHEEL если контрол на который оно пришло не имеет в цепочке Parent'ов PageControl? |
| Автор: drkot 30.10.2014, 13:16 |
| Вам нужно перехватывать WM_MOUSEWHEEL на уровне формы. если есть несколько областей реагирующих на колесико, то их можно поместить в разные контейнеры и производить перехват на уровне контейнеров (TPanel) |
| Автор: Seroga 31.10.2014, 17:58 | ||
Не, на уровне формы не подоходит, я же компонент делаю, на каждой форме такое лепить не фонтан. Насоветовали глянуть в сторону хуков мышки. Начал лазить по исходникам делфи, нашел у компонента Ribbon как раз то что ищу, у него закладки скролятся и сделано через хук. Предварительный вариант такой:
|
| Автор: drkot 1.11.2014, 22:20 |
чтоб хорошего насоветовали... а вот всякой пакости как всегда вагон.... Вы отдаете себе отчет в том, что будет если на форме (или приложении) окажутся два и более таких компонента? Как оно будет работать? Если Вы делаете "отдельный" компонент, то имеет смысл сделать свойство MouseWheelOwner: TForm и задать в него форму на которой лежит панель. при создании панели в соответствующие Event свойства MouseWheelOwner прописать свои обработчики. Это если Вам уж так хочется заниматься тем, что порицают все сишники. А так нормальное решение Вам предложено... хотите страдать - страдайте... |
| Автор: Seroga 3.11.2014, 19:00 | ||||
Ну и в чем тут удобство? А если мне на форме нужны будут эти обработчики, то как быть? Как быть с сотней других форм где есть уже PageControl? Их всех перелопатить? Добавлено через 26 секунд
Ну оно вроде так и сделано. Нужно только код из Destroy перенести в finalization. |
| Автор: bems 4.11.2014, 23:58 |
| это можно, а вот из Create просто перенести в initialization нельзя, потому что тогда при использовании компонента в длл это будет обращение к user32 api из DllMain, а это черевато |
| Автор: drkot 5.11.2014, 23:51 |
только это не соответствует идеологии VCL... а делать то можно... у Вас все PageControl получат уведомление о прокрутке и все прокрутятся. Принятие решения о том кому "адресовано" действие равносильно прописыванию общей реакции для формы. О чем и говорилось выше.... Другими словами хук будет простым решение только для условия одного "живого" PageControl. В остальных случаях решение теряет тривиальность и потребует широкого напильника для каждого конкретного случая. При этом получение события формой (контейнером) и принятие решения кого крутить остается одинаково тривиальным при любом масштабе задачи. извольте... какой DllMain? Хук то локальный должен быть! |
| Автор: bems 6.11.2014, 04:18 |
хук-то локальный, но он не при чем. компонент должен же работать в том числе и из длл, как все нормальные компоненты |