Казалось бы, тривиальная задача, но бьюсь над ее решением уже второй день и ничего не могу придумать! На форме лежит RichEdit, размазанный по нижнему краю формы (свойство Align = alBottom). Над ним лежит Splitter соответственно с таким же выравниванием, что позволяет изменять размеры RichEdit. Ключевой необходимостью является ограничение минимальной высоты как RichEdita, так и оставшейся пустой верхней области формы. Они не должны быть меньше 80 пикселов. Соблюдение необходимых ограничений при перетаскивании сплитера легко обеспечивается установлением его свойства MinSize равным 80. Все проблемы возникают при попытке соблюсти указанные ограничения при изменении высоты формы. Необходимо, чтобы несмотря на начальные значения высоты RichEdita и верхней области, при уменьшении формы они сначала уменшались обое пропорционально их высотам, когда высота одного станет <= 80 пикселам, форма продолжала уменьшатся за счет высоты другого, а когда и его высота достигнет ограничения, изменение высоты формы блокировалось. При увеличении высоты формы ситуация проще - обе области (RichEdit и пустая верхняя) должны увеличиваться пропорционально своим размерам. И, конечно же, желательно, чтобы при изменении размеров формы ничего не мерцало и не скакало туда-сюда.
Проблема в том, что при уменьшении высоты формы обе области уменьшаются пропорционально, и если высота верхней пустой области была до уменьшения 80, то ограничить ее дальнейшее уменьшение не представляется возможным. Если же програмно ограничивать верхнюю границу RichEdit в событии OnCanResize, то возникает сильное мерцание в результате того, что RichEdit все таки накладывается на пустую область, а потом насильно возвращается назад.
Еще раз - задача свиду кажется элементарной, но при практической реализации оказывается довольно сложной. По-крайней мере я уже все, что мог, перепробовал - не получилось. Кризис жанра.
Если у кого-то будут какие-то идеи или кто-нибудь с такой задачей сталкивался на практике - буду очень благодарен за любый советы и предложения.
ПС. Пишу на C++ Builder 6, но это в даном контексте значения не имеет.
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
19-04-2006 02:56 | Сообщение от автора вопроса
Михаил Извеков, я благодарен за проявленную заботу. Но два но: 1) у меня и при наявности панели экран мерцает в области сплиттера; 2) панель вылезет мне боком в виду специфики моей програмы, поэтому этот вариант мной хотя и разглядывался вначале, потом вынужден был от него отказаться...
15-04-2006 16:37 | Комментарий к предыдущим ответам
Не знаю как в Билдере, а в Делфи Constraints элементов при ресайзе формы очень даже действует. WishMaster вот вы пишете, что сделали так, как я написал, а ниже пишете, что панели вверху нет... А я настаиваю - поставьте туда панель и все будет ok.
Может я неправ, но панель и одна строка кода куда лучше 5 ваших процедур.
Михаил Извеков, может на этот раз уже я чего-то не понял, но сделал специально еще раз так, как написали Вы - не помагает, так как при изменении формы Constraints элементов не действует. Приведенная операция в OnCanRecize приводит к миганию. Делал в Билдере, ошибаться негде. Не думаю, что в Делфи что-то по другому. К тому же, сверху панели нет, там пустое место. И ограничение для него, как сами понимаете, не поставиш. Хоча как видно, и оно не очень то помагает.
Так что если подытожить, я не вижу пока что альтернативы тому, как сделал я.
Благодарю всех, кто брал участие в дискуссии.
Решил я проблему. Работает все практически идеально, так как я и хотел. Ключевым моментом было то, что пришлось для RichEdita и Splittera отключать свойство Align = alBottom (то есть сделать его alNone) в начале события OnCanRecize формы и вручную управлять их размерами и расположением. Это дало возможность избежать мерцания и реализовать все именно так, как я хотел. А в событии OnPaint свойства устанавливаются назад. Ниже выкладываю текст, если вдруг комуто пригодится. Исходные условия - на форме RichEdit и Splitter, у обоих - свойство Align = alBottom. Что необходимо было получить я писал в вопросе. Единственное изменение - тут я не задавал свойство MinSize для Splittera, а управлял через событие OnCanResize Splittera, что дало мне возможность отдельно ограничить высоту RichEdit (20 пикселей) и оставшейся верхней пустой области (80 пикселей). Писал на C++ Builder 6.
Давайте может быть подумаем, в каком событии можна упредить сдвижению верхнего края RichEdit при уменьшении высоты формы? Мерцание вызвано именно этим, потому как в событии OnCanResize формы это не помогает.
Andy_Great, минимальные размеры формы я и так установил в Constraints формы. Но это не дает возможности ограничить размеры какой-либо одной области при уменьшении высоты формы.
Василий,
Спасибо за предложение, я сейчас скомпилю простенький "мерцающий вариант" и отошлю Вам на мыло.
Странно это...Вообще то я подобной пропорциональностью никогда не задавался. Но при формировании подобных панелей обычно размещаю на форме нужное количество панелей (без бордеров и кэпшенов) и сплиттеров. И использую именно OnCanResize. Никаких мерцаний никогда не наблюдал. На панелях обычно у меня дроугриды. Пришли код - на "незамыленный" взгляд наверняка ошибку увижу.
Василий, я использовал эти параметры формы в указанном событии. Во-первых, при использовании именно этого события изменения размеров и положения RichEdita все равно имеют место, то есть оно в сущности генерируется уже после перемещения элементов внутри формы. По-крайней мере на практике это выходит именно так. Во-вторых, в этом событии я пробовал проверять координаты верхней границы RichEdit и если они были меньше 80, то програмно устаналивать ее в 80 и соответственно менять высоту этого элемента. При этом элемент все же заходил на пустую область, а потом насильно спускался вниз. Вследствии элемент сильно мерцал + так как пустая область все равно между событиями ставала меньше 80, у меня вылазила програмная ошибка.
Может что-нибудь конкретнее подскажете, что я мог упустить? Буду благодарен.
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.