Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
 
 21:09 W0lt
 
 
Во Флориде и в Королевстве сейчас  21:17[Войти] | [Зарегистрироваться]
Ответ на вопрос № 41659

14-04-2006 06:15
Казалось бы, тривиальная задача, но бьюсь над ее решением уже второй день и ничего не могу придумать! На форме лежит RichEdit, размазанный по нижнему краю формы (свойство Align = alBottom). Над ним лежит Splitter соответственно с таким же выравниванием, что позволяет изменять размеры RichEdit. Ключевой необходимостью является ограничение минимальной высоты как RichEdita, так и оставшейся пустой верхней области формы. Они не должны быть меньше 80 пикселов. Соблюдение необходимых ограничений при перетаскивании сплитера легко обеспечивается установлением его свойства MinSize равным 80. Все проблемы возникают при попытке соблюсти указанные ограничения при изменении высоты формы. Необходимо, чтобы несмотря на начальные значения высоты RichEdita и верхней области, при уменьшении формы они сначала уменшались обое пропорционально их высотам, когда высота одного станет <= 80 пикселам, форма продолжала уменьшатся за счет высоты другого, а когда и его высота достигнет ограничения, изменение высоты формы блокировалось. При увеличении высоты формы ситуация проще - обе области (RichEdit и пустая верхняя) должны увеличиваться пропорционально своим размерам. И, конечно же, желательно, чтобы при изменении размеров формы ничего не мерцало и не скакало туда-сюда.

Проблема в том, что при уменьшении высоты формы обе области уменьшаются пропорционально, и если высота верхней пустой области была до уменьшения 80, то ограничить ее дальнейшее уменьшение не представляется возможным. Если же програмно ограничивать верхнюю границу RichEdit в событии OnCanResize, то возникает сильное мерцание в результате того, что RichEdit все таки накладывается на пустую область, а потом насильно возвращается назад.

Еще раз - задача свиду кажется элементарной, но при практической реализации оказывается довольно сложной. По-крайней мере я уже все, что мог, перепробовал - не получилось. Кризис жанра.

Если у кого-то будут какие-то идеи или кто-нибудь с такой задачей сталкивался на практике - буду очень благодарен за любый советы и предложения.

ПС. Пишу на C++ Builder 6, но это в даном контексте значения не имеет.

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

19-04-2006 02:56 | Сообщение от автора вопроса
Михаил Извеков, я благодарен за проявленную заботу. Но два но: 1) у меня и при наявности панели экран мерцает  в области сплиттера; 2) панель вылезет мне боком в виду специфики моей програмы, поэтому этот вариант мной хотя и разглядывался вначале, потом вынужден был от него отказаться...

15-04-2006 16:37 | Комментарий к предыдущим ответам
Не знаю как в Билдере, а в Делфи Constraints элементов при ресайзе формы очень даже действует.
WishMaster вот вы пишете, что сделали так, как я написал, а ниже пишете, что панели вверху нет... А я настаиваю - поставьте туда панель и все будет ok.
Может я неправ, но панель и одна строка кода куда лучше 5 ваших процедур.

15-04-2006 12:43 | Сообщение от автора вопроса
Михаил Извеков, может на этот раз уже я чего-то не понял, но сделал специально еще раз так, как написали Вы - не помагает, так как при изменении формы Constraints элементов не действует. Приведенная операция в OnCanRecize приводит к миганию. Делал в Билдере, ошибаться негде. Не думаю, что в Делфи что-то по другому. К тому же, сверху панели нет, там пустое место. И ограничение для него, как сами понимаете, не поставиш. Хоча как видно, и оно не очень то помагает.
Так что если подытожить, я не вижу пока что альтернативы тому, как сделал я.
Благодарю всех, кто брал участие в дискуссии.

15-04-2006 12:33 | Сообщение от автора вопроса
Решил я проблему. Работает все практически идеально, так как я и хотел. Ключевым моментом было то, что пришлось для RichEdita и Splittera отключать  свойство Align = alBottom (то есть сделать его alNone) в начале события OnCanRecize формы и вручную управлять их размерами и расположением. Это дало возможность избежать мерцания и реализовать все именно так, как я хотел. А в событии OnPaint свойства устанавливаются назад. Ниже выкладываю текст, если вдруг комуто пригодится. Исходные условия - на форме RichEdit и Splitter, у обоих - свойство Align = alBottom. Что необходимо было получить я писал в вопросе. Единственное изменение - тут я не задавал свойство MinSize для Splittera, а управлял через событие OnCanResize Splittera, что дало мне возможность отдельно ограничить высоту RichEdit (20 пикселей) и оставшейся верхней пустой области (80 пикселей). Писал на C++ Builder 6.


double RichEditHeight;

//---------------

__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
  RichEditHeight = RichEdit1->Height;
}

//---------------

void __fastcall TForm1::FormCanResize(TObject *Sender, int &NewWidth,
      int &NewHeight, bool &Resize)
{
  if (NewHeight != Height || NewWidth != Width)
    {
      RichEdit1->Align = alNone;
      Splitter1->Align = alNone;
      int riznytsya = Height - RichEdit1->Top - RichEdit1->Height;
      double koef = (double)(NewHeight - riznytsya)/(Height - riznytsya);
      if (NewHeight - riznytsya - (int)(koef*RichEditHeight) <= 80)
        {
          RichEdit1->Top = 80;
          if (NewHeight - riznytsya - 80 <= 20)
            {
              RichEdit1->Height = 20;
              NewHeight = RichEdit1->Top + RichEdit1->Height + riznytsya;
            }
          else RichEdit1->Height = NewHeight - riznytsya - 80;
          RichEditHeight = RichEdit1->Height;
        }
      else
        {
          if ((int)(koef*RichEditHeight) <= 20) RichEditHeight = 20;
          else RichEditHeight *= koef;
          RichEdit1->Height = RichEditHeight;
          RichEdit1->Top = NewHeight - riznytsya - RichEdit1->Height;
        } 
      RichEdit1->Width = NewWidth - Width + RichEdit1->Width;
      Splitter1->Top = RichEdit1->Top - Splitter1->Height;
      Splitter1->Width = RichEdit1->Width;
    }
}

//---------------

void __fastcall TForm1::FormPaint(TObject *Sender)
{
  RichEdit1->Align = alBottom;
  Splitter1->Align = alBottom;
}

//---------------

void __fastcall TForm1::Splitter1Moved(TObject *Sender)
{
  RichEditHeight = RichEdit1->Height;
}

//---------------

void __fastcall TForm1::Splitter1CanResize(TObject *Sender, int &NewSize,
      bool &Accept)
{
  int riznytsya = Height - RichEdit1->Top - RichEdit1->Height;
  if (Height - riznytsya - NewSize < 80) Accept = false;
  if (NewSize < 20) Accept = false;
}

//---------------

15-04-2006 12:09
Может конечно я что-то не то делаю, но проблемы не нашел :)

Условия:

RichEdit1:
Constraints.MinHeight = 80
align = alBottom

Splitter1:
align = alBottom
MinSize = 80
AutoSnap = false

Panel1: (играет роль свободного места вверху)
align = alClient;
Constraints.MinHeight = 80

В OnCanResize формы строка

  RichEdit1.Height := RichEdit1.Height - ((Height - NewHeight) div 2);


Все работает, ничего не дергается.




14-04-2006 14:14 | Сообщение от автора вопроса
Давайте может быть подумаем, в каком событии можна упредить сдвижению верхнего края RichEdit при уменьшении высоты формы? Мерцание вызвано именно этим, потому как в событии OnCanResize формы это не помогает.

14-04-2006 14:06 | Сообщение от автора вопроса
Andy_Great, минимальные размеры формы я и так установил в Constraints формы. Но это не дает возможности ограничить размеры какой-либо одной области при уменьшении высоты формы.

Василий,
Спасибо за предложение, я сейчас скомпилю простенький "мерцающий вариант" и отошлю Вам на мыло.

14-04-2006 13:05
Странно это...Вообще то я подобной пропорциональностью никогда не задавался. Но при формировании подобных панелей обычно размещаю на форме нужное количество панелей (без бордеров и кэпшенов) и сплиттеров. И использую именно OnCanResize. Никаких мерцаний никогда не наблюдал. На панелях обычно у меня дроугриды. Пришли код - на "незамыленный" взгляд наверняка ошибку увижу.

14-04-2006 08:13
Я может не совсем понял данный вопрос, но похоже просто стоит перехватывать сообщение WM_GETMINMAXINFO и установить минимальные размеры для формы

14-04-2006 07:21 | Сообщение от автора вопроса
Василий, я использовал эти параметры формы в указанном событии. Во-первых, при использовании именно этого события изменения размеров и положения RichEdita все равно имеют место, то есть оно в сущности генерируется уже после перемещения элементов внутри формы. По-крайней мере на практике это выходит именно так. Во-вторых, в этом событии я пробовал проверять координаты верхней границы RichEdit и если они были меньше 80, то програмно устаналивать ее в 80 и соответственно менять высоту этого элемента. При этом элемент все же заходил на пустую область, а потом насильно спускался вниз. Вследствии элемент сильно мерцал + так как пустая область все равно между событиями ставала меньше 80, у меня вылазила програмная ошибка.
Может что-нибудь конкретнее подскажете, что я мог упустить? Буду благодарен.

14-04-2006 07:06
У формы есть эвент OnCanResize с параметрами
var NewWidth,NewHeight: Integer; var Resize: Boolean
их вполне достаточно для решения Вашей проблемы.

14-04-2006 06:35
Могу попробовать написать пример.
Если надо, пришли мне текст вопроса на мыло.

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Раз дощечка, два дощечка будет лесенка. Раз словечко, два словечко, будет ЧТО?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования