Руководство разработчика

Сохранение размеров и расположения диалога

В платформе предусмотрен механизм синхронизации и сохранения значений размера и положения у диалогов в момент их закрытия.

Механизм синхронизации позволяет обновлять значения полей ширина, высота, левый, верхний при изменении позиционирования и размеров физического объекта формы, то есть отображаемого на экране диалога.

Сохранение положения и размера окон производится в локальный профиль клиентского приложения, где хранятся различные настройки. Механизм сохранения обеспечивает восстановление расположения и размеров предыдущего показа диалога, и заключается в том, что происходит считывание профиля и присвоение полям ширина, высота, левый, верхний значений прошлого расположения и размеров диалога. Сохранение размеров и положения диалогов происходит, если для них в поле идент задана непустая строка, иначе сохранение не выполняется.

Для MDI-окон и окон верхнего уровня, показываемых на экране методами ПОКАЗАТЬ_МДИ, ПОКАЗАТЬ_ВЕРХНЕГО_УРОВНЯ обновление и сохранение положения не происходит, так как они по умолчанию располагаются каскадом и поля левый и верхний для них игнорируются. У всплывающих диалогов, показываемых на экране методами ПОКАЗАТЬ_МОДАЛЬНЫЙ и ПОКАЗАТЬ за свободное позиционирование всплывающего окна на экране отвечают поля левый, верхний. Чтобы значения этих полей не игнорировались, у свойства центр должно быть установлено значение НЕТ, иначе диалог будет центрирован на экране.

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

Чтобы лучше понимать процедуру автоматического обновления и сохранения размеров и положения диалога действия платформы проиллюстрированы в примере.

В таблице ниже для формы типа ДИАЛОГ приведена зависимость режима показа формы и поведения сохранения/обновления ее размеров и положения.

Аспект поведения Режим показа
ПОКАЗАТЬ_МДИ, ПОКАЗАТЬ_ВЕРХНЕГО_УРОВНЯ ПОКАЗАТЬ,ПОКАЗАТЬ_МОДАЛЬНЫЙ
Загрузка/сохранение значений полей левый и верхний из/в настроек.Никогда.При значении полей центр=НЕТ и идент<>"".
Загрузка/сохранение значений полей ширина и высота из/в настроек. При значении полей авто_размер=НЕТ и идент<>"". Если установлен обработчик размер, то он вызывается при удачной загрузке.При значении поля идент<>"" и установленном обработчике размер. Вызывается обработчик размер при удачной загрузке.
Обновление значений полей левый и верхний при перемещении формы. Никогда.При значении поля центр=НЕТ.
Обновление значений полей ширина и высота при изменении размера формы. При значении поля авто_размер=НЕТ и установленном обработчике размер.При установленном обработчике размер.

Пример

Пример иллюстрирует сохранение расположения и размеров диалога при его закрытии в профиль и восстановление из профиля параметров предыдущего показа и применение их в текущем показе. В до_открытии принудительно вызывается обработчик размер, обеспечивающий изменение размеров элементов управления при изменении размеров самого окна.

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

Считывание профиля и присвоение прошлого расположения и размеров диалогу можно также производить в обработчике открытие. Тогда отпадает необходимость принудительно делать вызов обработчика размер, так как он будет вызван при показе уже существующей формы, размер которой изменен.

Тем не менее, предпочтительнее использовать вариант восстановления состояния диалога в обработчике до_открытия.

ТИП Диалог1(ДИАЛОГ)
[
  ПОДМЕНА ширина = 450;
  ПОДМЕНА высота = 1600;
  ПОДМЕНА размер = {изм_размер};
  ПОДМЕНА шрифт = [ имя = "Tahoma" ];
  ПОДМЕНА центр = НЕТ;
  ПОДМЕНА до_открытия = {до_откр};
  ПОДМЕНА закрытие = {Закрытие};
  ПРОФИЛЬ: п = [ тип = ПРОФ_СЕАНС];

  КНОПКА: КнопкаОК = [ левый = 264,
                       верхний = 1565,
                       ширина = 80,
                       высота = 25,
                       табиндекс = 1001,
                       текст = "ОК",
                       нажатие = {НажатаОК} ];
  КНОПКА: КнопкаОтмена = [ левый = 357,
                           верхний = 1565,
                           ширина = 80,
                           высота = 25,
                           табиндекс = 1002,
                           текст = "Отмена",
                           нажатие = {НажатаОтмена} ];
  СПИСОК_ОПЦИЙ: Список_опций1 = [ левый = 15,
                                  верхний = 15,
                                  ширина = 420,
                                  высота = 1540,
                                  табиндекс = 1003 ];

  ФУНКЦИЯ НажатаОК(ПЕРЕМ КНОПКА: кнопка);
  ФУНКЦИЯ НажатаОтмена(ПЕРЕМ КНОПКА: кнопка);
  ФУНКЦИЯ ЛОГИКА: изм_размер(ПЕРЕМ ДИАЛОГ: форма; 
                             ЧИСЛО: старая_ширина; ЧИСЛО: старая_высота; 
                             ЧИСЛО: новая_ширина; ЧИСЛО: новая_высота);
  ФУНКЦИЯ ЛОГИКА: до_откр;

  ФУНКЦИЯ ЛОГИКА: Закрытие(СТРОКА: код_выхода)
    п.ЗАПИСАТЬ("высота", высота)
    п.ЗАПИСАТЬ("ширина", ширина)
    п.ЗАПИСАТЬ("левый", левый)
    п.ЗАПИСАТЬ("верхний", верхний)
    РЕЗУЛЬТАТ = ДА
  КОНЕЦ_ФУНКЦИИ
]

...

ФУНКЦИЯ ЛОГИКА: Диалог1.изм_размер(ПЕРЕМ ДИАЛОГ: форма; 
                                   ЧИСЛО: старая_ширина; ЧИСЛО: старая_высота; 
                                   ЧИСЛО: новая_ширина; ЧИСЛО: новая_высота)
  ОТЛАДКА(СТР(старая_ширина) + " х " + СТР(старая_высота) + 
          " -> " + СТР(новая_ширина) + " х " + СТР(новая_высота))
  ПЕРЕМ ЧИСЛО: дх = новая_ширина - старая_ширина
  ПЕРЕМ ЧИСЛО: ду = новая_высота - старая_высота
  КнопкаОК.левый += дх
  КнопкаОК.верхний += ду
  КнопкаОтмена.левый += дх
  КнопкаОтмена.верхний += ду
  Список_опций1.ширина += дх
  Список_опций1.высота += ду
  РЕЗУЛЬТАТ = ДА
КОНЕЦ_ФУНКЦИИ

ФУНКЦИЯ ЛОГИКА: Диалог1.до_откр
  ПЕРЕМ ЧИСЛО:сохр_ширина
  ПЕРЕМ ЧИСЛО:сохр_высота
  ПЕРЕМ ЧИСЛО:сохр_левый
  ПЕРЕМ ЧИСЛО:сохр_верхний
  п.СЧИТАТЬ("ширина", сохр_ширина)
  п.СЧИТАТЬ("высота", сохр_высота)
  п.СЧИТАТЬ("левый", сохр_левый)
  п.СЧИТАТЬ("верхний", сохр_верхний)
  // для общего случая
  ЕСЛИ @размер ТО
    ПЕРЕМ обр = размер // нужно из-за неоднозначности синтаксиса вызова метода по ссылке
    САМ.обр(САМ, ширина, высота, сохр_ширина, сохр_высота)
  КОНЕЦ_ЕСЛИ

  // в частном случае можно проще:
  //изм_размер(САМ, ширина, высота, сохр_ширина, сохр_высота)

  ширина = сохр_ширина
  высота = сохр_высота
  левый = сохр_левый
  верхний = сохр_верхний
  ОБНОВИТЬ
  РЕЗУЛЬТАТ = ДА
КОНЕЦ_ФУНКЦИИ
ВЫЧИСЛИТЬ
  д.ПОКАЗАТЬ_МОДАЛЬНЫЙ
КОНЕЦ

См. также: