Визуальное сохранение свойств объектов
В процессе разработки графического интерфейса пользователя очень часто возникает ситуация, когда необходимо в промежутках между сеансами работы оператора сохранять введённые им данные в полях формы.
Классический подход к этой задаче подразумевает написание процедур для сохранения значений выбранных полей ввода при закрытии формы и процедур восстановления значений при повторном открытии окон.
В Delphi разработчики замечательной библиотеки RxLib в своё время реализовали механизм для визуальной автоматизации этого процесса.
В Lazarus эта хорошая мысль получила ожидаемое развитие — теперь механизмы такого сохранения/восстановления состояния компонентов встроены в саму LCL.
Данная статья — это обзор этой возможности и описание примера кода.
Во второй части находится обзор возможностей компонентов, их методов и свойств. В третей части — пошаговое описание создания примера работы.
2. Обзор
2.1. Абстрактно
Для работы с этой возможностью нам дано свойство TForm.SessionProperties. Именно в этом свойстве необходимо указывать список свойств, которые мы будем сохранять во время работы программы.
Формат перечисления — ИмяКомпоненты.ИмяСвойства. Друг от друга отделяются через точку с запятой.
Но чаще всего для заполнения этого списка используется встроенный редактор:

Иллюстрация 2.1: Общий вид проекта в разработке
Сам механизм сохранения реализован через другие компоненты — наследники от TFormPropertyStorage.
В стандартной поставке Lazarus идёт 2 таких компоненты.
- TIniPropStorage — сохраняет значения в формате Windows ini-файла;
- TXMLPropStorage — сохраняет значения в xml-файле.
2.2. Описание свойств компоненты TIniPropStorage
- Windows — в каталоге, рядом с исполняемым модулем программы. Имя файла будет равно имени файла исполняемной программы с расширением «.ini»;
- Unix-подобные системы — скрытый файл в домашней папке пользователя. Имя файла будет начинаться с точки и равняться имени исполняемого файла программы.
2.3. Описание свойств компоненты TXMLPropStorage
- Windows — в каталоге, рядом с исполняемым модулем программы. Имя файла будет равно имени файла исполняемой программы с расширением «.xml»;
- Unix-подобные системы — скрытый файл в домашней папке пользователя. Имя файла будет начинаться с точки и равняться имени исполняемого файла программы.
3. Пример
Для примера создадим программу, в которой будет находиться несколько визуальных элементов. Значения свойств этих элементов будут сохраняться между сеансами работы. В главном меню IDE Lazarus выбираем «Проект/Создать проект. ». В открывшемся окне выбора типа проекта выбираем «Приложение» — будет создан обычный проект для создания программы с графическим пользовательским интерфейсом. На форму программы положим компоненты TEdit — строки ввода текста, TLabel — подписи к строкам, TRadioGroup — компонент для выбора одного пункта из списка и несколько TCheckBox — для выбора состояний. Расположим элементы как указано на рисунке 3.1:

Иллюстрация 3.1: Форма во время разработки
После этого откроем редактор свойства SessionProperties главной формы программы (см. рисунок 3.2). Этот редактор состоит из трёх списков. В верхней части формы слева находится список компонентов, расположенных на форме. При выборе в этом списке компоненты (на рисунке CheckBox1) в правом списке отображается свойства данного компонента, которые мы можем сохранять. Для выбора свойства к сохранению достаточно щёлкнуть кнопку «Добавить» или просто двойной клик мышкой по данному свойству. В результате имя свойства будет перенесено в нижний список. Именно в нижнем списке находится полный список свойств, которые будут сохраняться между сеансами работы программы.

Иллюстрация 3.2: Редактор свойства SessionProperties
После перечисления всех свойств можно запускать программу на выполнение. Значение всех элементов ввода данных будут сохранены при завершении работы программы. Повторный запуск восстановит эти значения. Ниже приведён снимок экрана во время выполнения программы:

Иллюстрация 3.3: Вид программы во время работы
Дополнительно все наследники TFormPropertyStorage (в примере TIniPropStorage) обеспечивают функционал сохранения произвольных значений между сеансами работы. Обеспечивается это с помощью свойства StoredValues. В нём предварительно заводятся для каждого сохраняемого значения элемент. Само сохранение удобно делать с помощью события:
property OnSaveProperties. Восстановление значений можно делать с помощью события:
property OnRestoringProperties. Более подробно всё это расписано в примере, который идёт с данным руководством.
Свойства и характеристики формы (Form) в Дельфи (Delphi)
Как и любой другой визуальный компонент, форма имеет свойства, методы и события, общие для всех визуальных компонентов, многие из которых уже были рассмотрены в статье События Delphi (События визуальных компонентов), а так же в статьях, посвященных интерфейсным элементам.
Наряду с ними у формы есть и спефические свойства, методы и события, определяемые ее особым значением. Некоторые из них характеризуют форму как главный объект приложения, скажем, свойство BorderIcons, другие присущи форме как контейнеру других компонентов, например, свойства AutoScroll и ActiveControl.
Система Delphi при добавлении новой формы в проект автоматически создает один экземпляр класса (Form1, Form2 и т. д.), внося соответствующие изменения в файл проекта, например, добавляя строку кода:
Управлять процессом автоматического создания форм можно, непосредственно редактируя файл проекта (не рекомендуется делать неопытным программистам) или выполняя настройки в окне параметров проекта (список Auto-create forms на странице Form). Если форма переведена из этого списка в список Available forms доступных форм проекта, то инструкция ее создания исключается из файла проекта, и программист в ходе выполнения приложения должен динамически создать экземпляр этой формы.
На данном скринште мы видим, что Form1 будет создана при запуске программы, а Form2 необходимо будет создать динамически при выполнении программы.
Метод Сreate
Для создания экземпляров форм служит метод (конструктор) Сreate. Сам класс формы обычно предварительно описывается при конструировании приложения, и для формы уже существуют файлы формы (dfm) и программного модуля (pas).
В вышеуказанной процедуре создается форма Form2, принадлежащая объекту приложения и имеющая заголовок новая форма.
События формы (Form)
При создании и использовании формы генерируются следующие события типа TNotifyEvent, указанные в порядке их возникновения:
Событие OnCreate
Событие OnCreate генерируется только один раз— при создании формы, остальные события происходят при каждом отображении, активизации и каждой прорисовке формы соответственно.
В обработчик события OnCreate обычно включается код, устанавливающий начальные значения свойств формы, а также ее элементов управления, т. е. выполняющий начальную инициализацию формы в дополнение к установленным на этапе разработки приложения параметрам. Кроме того, в обработчик включаются дополнительные операции, которые должны происходить однократно при создании формы, например, чтение к из файла некоторой информации и загрузка ее в список.
Приведем в качестве примера процедуру, обрабатывающую событие OnCreate формы Form2:
При создании форма получает новый заголовок пример формы, в комбинированный список ComboBox2 загружаются данные из файла list.txt, кнопка Button3 блокируется, а фокус ввода устанавливается на редактор Edit1.
Свойство Visible
Из всех созданных форм Delphi при выполнении приложения автоматически делает видимой главную форму, для этого свойство Visible этой формы устанавливается в значение True. Для остальных форм значение данного свойства по умолчанию равно False, и после запуска приложения они на экране не отображаются. Если формы создаются вручную, то их отображение и скрытие в процессе работы приложения регулируется программистом через свойство Visible. Даже если форма невидима, ее компонентами можно управлять, например, из других форм.
Дочерние формы многодокументного приложения становятся видимыми на экране сразу после их создания.
В вышеуказанных процедурах нажатие кнопок btnShowForm2 и btnHideForm2, расположенных в форме Form1, приводит, соответственно, к отображению и скрытию формы Form2.
Методы Show и Hide
Управлять видимостью форм на экране можно также с помощью методов Show и Hide. Процедура Show отображает форму в немодальном режиме, при этом свойство Visible устанавливается в значение True, а сама форма переводится на передний план. Процедура Hide скрывает форму, устанавливая ее свойство Visible в значение False.
Если окно видимо, то вызов метода Show переводит форму на передний план и передает ей фокус ввода.
Пример отображения и скрытия формы:
Здесь нажатие кнопок btnShowForm3 и btnHideForm3, расположенных В форме Form1, приводит соответственно к отображению на экране и удалению с экрана формы Form3.
В момент отображения формы на экране ее свойство visible принимает значение True, и возникает событие OnShow. Соответственно при скрытии формы свойство visible принимает значение False, и возбуждается событие OnHide.
События OnActivate и OnDeActivate
При получении формой фокуса ввода, например при нажатии кнопки мыши в области формы, происходит ее активизация и возникает событие OnActivate, а при потере фокуса— событие OnDeActivate.
Событие OnPaint
Событие OnPaint генерируется при необходимости перерисовки формы, например, при активизации формы, если до этого часть ее была закрыта другими окнами.
Метод Сlose — закрывает форму
Для закрытия формы используется метод close, который, если это возможно, удаляет ее с экрана. В случае закрытия главной формы прекращается работа врего приложения.
В вышеуказанной процедуре кнопка btnClose закрывает форму Form2. Форма делается невидимой, но не уничтожается. Для этой кнопки полезно задать соответствующий заголовок (свойство Caption), например, Закрыть.
Процедура Close не уничтожает созданный экземпляр формы, и форма может быть снова вызвана на экран, в частности, с помощью методов Show или ShowModal.
Уничтожение формы (Release, Free или Destroy)
Уничтожение формы происходит с помощью методов Release, Free или Destroy, после чего работа с этой формой становится невозможна, и любая попытка обратиться к ней или ее компонентам вызовет исключение (ошибку). Необходимость уничтожения формы может возникнуть при оформлении заставок или при разработке больших приложений, требующих экономии оперативной памяти. Предпочтительным методом удаления формы считается метод Free, поскольку он предварительно проверяет возможность удаления. Например, в процедуре
В приведенной процедуре кнопка btnDestroy уничтожает форму Form3. Для этой кнопки полезно задать соответствующий заголовок, например Удалить.
События при закрытии и уничтожении формы
При закрытии и уничтожении формы генерируются следующие события, указанные в порядке их возникновения:
- OnCloseQuery;
- OnClose;
- OnDeActivate;
- OnHide;
- OnDestroy.
Событие OnCloseQuery
Событие OnCloseQuery типа TcloseQueryEvent возникает в ответ на попытку закрытия формы. Обработчик события получает логическую переменную-признак CanClose, определяющую, может ли быть закрыта данная форма. По умолчанию эта переменная имеет значение True, и форму можно закрыть. Если установить параметр CanClose в значение False, то форма остается открытой. Такую возможность стоит использовать, например, для подтверждения закрытия окна или проверки, сохранена ли редактируемая информация на диске. Событие OnCloseQuery вызывается всегда, независимо от способа закрытия формы.
Приведем в качестве примера процедуру закрытия формы:
Здесь при закрытии формы Form2 выдается запрос на подтверждение операции, который представляет собой модальное диалоговое окно с текстом и двумя кнопками — Yes и No. Нажатие кнопки Yes вызывает закрытие формы, при нажатии кнопки No закрытие формы не происходит.
Событие OnClose
Событие OnClose типа TCioseEvent возникает непосредственно перед закрытием формы. Обычно оно используется для изменения стандартного поведения формы при закрытии. Для этого обработчику события передается переменная Action типа TCloseAction, которая может принимать следующие значения:
- caNone (форму закрыть нельзя);
- caHide (форма делается невидимой);
- caFree (форма уничтожается, а связанная с ней память освобождается);
- caMinimize (окно формы сворачивается) — значение по умолчанию для MDI-форм.
При закрытии окна методом Close переменная Action по умолчанию получает значение caHide, и форма делается невидимой. При уничтожении формы, например, методом Destroy, переменная Action по умолчанию получает значение caFree, и форма уничтожается.
Событие OnClose возникает при закрытии формы щелчком мыши на кнопке закрытия системного меню или при вызове метода Close. Когда закрывается главная форма приложения, все остальные окна закрываются без вызова события OnClose.
В выше указанной процедуре при закрытии формы Form2 проверяется признак модификации содержимого редактора Memo1. Если информация в Memo1 была изменена, то форма не закрывается.
Событие onDestroy
Событие onDestroy типа TNotifyEvent возникает непосредственно перед уничтожением формы и обычно используется для освобождения ресурсов.
Событие onResize
При каждом изменении размеров формы в процессе выполнения приложения возникает событие onResize типа TNotifyEvent. В обработчике этого события может размещаться код, например, выполняющий изменение положения и размеров элементов управления окна, не имеющих свойства Align.
В форме Form1 находятся два компонента: сетка строк StringGrid1 и кнопка Button1. Эти компоненты расположены в форме следующим образом:
- сетка StringGrid1 занимает всю ширину клиентской области формы Form3, отступы слева и справа составляют 10 пикселов;
- кнопка Button1 (Закрыть) выровнена по правому краю сетки StringGrid1;
- расстояния между сеткой, кнопкой, верхним и нижним краями формы составляют 5 пикселов.
При изменении размеров формы Form1 выполняется пересчет параметров, задающих размеры и положение сетки строк, а также положение кнопки.
Cвойство FormStyle — стиль формы
Стиль формы определяется свойством FormStyle типа TFormstyle, принимающим следующие значения:
- fsNormal (стандартный стиль, используемый для большинства окон, в том числе и диалоговых);
- fsMDiChild (дочерняя форма в многодокументном приложении);
- fsMDiForm (родительская форма в многодокументном приложении);
- fsStayOnTop (форма, которая после запуска всегда отображается поверх других окон) — обычно используется при выводе системной информации или информационной панели программы.
Форма может изменять стиль динамически — в процессе выполнения программы, например, при выборе пункта меню. При изменении формой стиля возникает событие OnShow.
Пример динамического изменения стиля формы:
При выборе пункта меню mnuTop форма переключает свой стиль между значениями fsNormal и fsStayOnTop. Смена стиля отображается графически галочкой в заголовке этого пункта меню.
Cвойство BorderStyle — свойства рамки формы
Каждая форма имеет ограничивающую рамку. Вид и поведение рамки определяет свойство BorderStyle типа TFormBorderstyle. Оно может принимать следующие значения:
- bsDialog (диалоговая форма);
- bsSingle (форма с неизменяемыми размерами);
- bsNone (форма не имеет видимой рамки и заголовка и не может изменять свои размеры) — часто используется для заставок;
- bsSizeable (обычная форма с изменяемыми размерами) — по умолчанию, имеет строку заголовка и может содержать любой набор кнопок;
- bsToolwindow (форма панели инструментов);
- bsSizeToolwin (форма панели инструментов с изменяемыми размерами).
Визуальное отличие между диалоговой и обычной формами заключается в том, что диалоговая форма может содержать в своем заголовке только кнопки закрытия и справки. Кроме того, пользователь не может изменять размеры диалоговой формы.
Невозможность изменения размеров форм некоторых стилей относится только к пользователю — нельзя с помощью мыши передвинуть границу формы в ту или иную сторону. Программно при выполнении приложения для формы любого стиля можно устанавливать любые допустимые размеры окна, а также изменять их.
Пример программного изменения размеров формы:
При нажатии кнопки btnResizeForm ширина формы Form2 увеличивается на 100 пикселов, даже если ее свойство BorderStyle имеет значение, равное bsDialog, bsSingle или bsNone.
Метод ShowModal
Если установить диалоговый стиль формы, то она не становится модальной и позволяет пользователю переходить в другие окна приложения. Для запуска формы, в том числе любой диалоговой, в модальном режиме следует использовать метод ShowModal. Таким образом, стиль определяет внешний вид формы, но не ее поведение.
Cвойство BorderIcons
В области заголовка могут отображаться 4 вида кнопок. Реализуемый набор кнопок определяет свойство BorderIcons типа TBorderIcons, которое может принимать комбинации следующих значений:
- blSystemMenu (окно имеет системное меню и может содержать кнопки системного меню);
- blMinimize (окно содержит кнопку свертывания);
- blMaximize (окно содержит кнопку развертывания/восстановления);
- blHelp (окно содержит кнопку справки, которая отображает вопросительный знак и вызывает контекстно-зависимую справку).
Системное меню представляет собой набор общих для всех окон Windows команд, например, Свернуть или Закрыть. При наличии у окна системного меню в области заголовка слева отображается значок приложения, при щелчке на котором и появляются команды этого меню, а в области заголовка справа имеется кнопка закрытия формы (см. скриншот).
Различные значения свойства BorderIcons не являются независимыми друг от друга. Так, если отсутствует системное меню, то ни одна кнопка не отображается. Если имеются кнопки развертывания и свертывания, то не отображается кнопка справки. Возможность появления кнопок также зависит от стиля формы. Например, отображение кнопок развертывания и свертывания возможно только для обычной формы и формы панели инструментов с изменяемыми размерами.
Обычно стиль формы и набор кнопок заголовка задаются на этапе разработки приложения в окне Инспектора объектов. При этом в проектируемой форме всегда видны обычная рамка и три кнопки (развертывания, свертывания и закрытия формы), независимо от значения свойств FormStyle и BorderIcons. Заданные стиль формы и набор кнопок становятся видимыми при выполнении программы.
Форма включает в себя клиентскую и неклиентскую области. Неклиентская область занята рамкой, заголовком и строкой главного меню. Обычно эта область прорисовывается Windows и программистом не затрагивается. При необходимости изменить отображение в неклиентской области программист может перехватить и обработать сообщение WM_NCPaint.
Cвойства ClientWidth и ClientHeight
В клиентской области обычно размещаются различные элементы управления, выводится текст или отображается графика. Аналогично тому как свойства Width и Height определяют размеры всей формы, свойства ClientWidth и ClientHeight типа Integer задают ширину и высоту (в пикселах) клиентской части формы.
В вышеуказанной процедуре значения размеров клиентской области выводятся в заголовке формы.
Обычно форму перетаскивают мышью, указатель которой устанавливается в любом месте области заголовка. При необходимости можно переместить форму и при помещении указателя на ее клиентскую область, для чего требуется описать соответствующие операции программно. Одним из способов является перехват системного сообщения WM_NCHitTest. Для этого создается процедура FormMove, которая анализирует, в каком месте формы находится указатель мыши при нажатии кнопки. Код местоположения указателя мыши содержится в поле Result системного сообщения типа TMessage. Если значение Result равно 1, что соответствует нажатию кнопки мыши в клиентской области, то полю Result присваивается новое значение, равное 2, имитирующее нахождение указателя мыши в области заголовка. В процедуре FormMove первая инструкция inherited осуществляет вызов предопределенного обработчика перехватываемого события.
Чтобы указать среде Delphi, что процедура FormMove является обработчиком события WM_NCHitTest, при ее описании в классе формы TForm1 используется специальный синтаксис, включающий ключевое слово message. Как обработчик системного сообщения, процедура содержит один параметр типа TMessage.
Далее приводится код модуля формы Form1, которую можно перемещать мышью, поместив указатель мыши как в область заголовка, так и в клиентскую область.
Имена MoveForm и Msg процедуры и ее параметра могут быть изменены.
Свойство Menu
Отображаемое формой меню задается свойством Menu типа TMainMenu. При разработке приложения размещение компонента MainMenu главного меню в форме вызывает автоматическое присвоение значения MainMenu1 свойству Menu. Это самый простой способ ссылки на главное меню. Если в ходе выполнения приложения какая-либо форма должна отображать различные меню, то через свойство Menu можно указать другое главное меню, например, следующим образом: Form1.Menu := MainMenu2;
Свойство Icon
Каждая форма отображает в левой стороне области заголовка свой значок, определяемый свойством Icon типа Ticon. Если форма не является главной в приложении, то этот значок отображается при свертывании формы. Для любой формы свойство Icon можно задать с помощью Инспектора объектов или динамически (при выполнении приложения). Если значок не задан, то форма использует значок, указанный в свойстве Icon объекта Application. Последний выводится также при свертывании и отображении в панели задач Windows значка главной формы приложения.
В вышеуказанной процедуре значок динамически загружается из файла Picture1.ico при создании формы Form1.
Свойство Position
Размещение и размер формы при отображении определяет свойство Position типа TPosition. Оно может принимать значения, перечисленные далее:
- poDesigned (форма отображается в той позиции и с теми размерами, которые были установлены при ее конструировании) — значение по умолчанию. Положение и размеры формы определяются свойствами Left, Tор, Width и Height. Если приложение запускается на мониторе с более низким разрешением, чем у того, на котором оно разрабатывалось, часть формы может выйти за пределы экрана;
- poScreenCenter (форма выводится в центре экрана, ее высота и ширина— свойства Height и width— не изменяются);
- poDefault (Windows автоматически определяет начальную позицию и размеры формы) — при этом значении программист не имеет возможности управлять этими параметрами, поэтому оно не допускается для форм многодокументных приложений;
- poDefaultPosOnly (Windows определяет начальную позицию формы, ее размеры не изменяются);
- poDefaultSizeOnly (Windows определяет начальные ширину и высоту формы и помещает форму в позицию, определенную при разработке);
- PoDesktopCenter (форма выводится в центре экрана, ее высота и ширина не изменяются);
- PoMainFormCenter (форма выводится в центре главной формы приложения, ее высота и ширина не изменяются) — это значение используется для вторичных форм, при применении его для главной формы оно действует как значение poScreenCenter;
- PoOwnerFormCenter (форма выводится в центре формы, которая является ее владельцем, высота и ширина формы не изменяются) — если для формы не указан владелец (свойство Owner), то данное значение аналогично значению poMainFormCenter.
Приложение может запоминать расположение и размеры форм и при последующем выполнении правильно отображать формы на экране. Для этого программист должен записать соответствующие данные в инициализационный файл приложения или в системный реестр Windows, а при последующем выполнении приложения считать эти данные и установить их для форм.
Свойство Active
Свойство Active типа Boolean позволяет определить активность формы. В любой момент времени активной может быть только одна форма, при этом ее заголовок выделяется особым цветом (обычно синим). Если свойство Active имеет значение True, то форма активна (находится в фокусе ввода), если False — то неактивна. Это свойство доступно для чтения во время выполнения программы. Если требуется активизировать форму программно, следует использовать свойство WindowState или метод Show (showModal).
Cвойство ChildActiveForm
В многодокументном приложении родительское окно не может быть активным независимо от цвета заголовка. Для определения активного дочернего окна многодокументного приложения служит свойство ChildActiveForm типа TForm родительской формы.
В вышеуказанном примере процедура CheckFormActive модуля главной формы выполняет проверку активности для двух форм приложения и отображает соответствующую информацию в заголовках форм.
Свойство WindowState
Свойство WindowState типа TWindowstate определяет состояние отображения формы и может принимать одно из трех значений:
- wsNormal (обычное состояние) — по умолчанию;
- wsMinimized (свернута);
- wsMaximized (развернута).
Кнопки btnMiniForm и btnNormalForm в форме Form1 сворачивают и восстанавливают обычное состояние формы Form2 соответственно.
Форма, для которой изменяется состояние отображения на экране, предварительно должна быть создана методами CreateForm или Create. Если форма не создана, то при обращении к ней будет сгенерировано исключение, несмотря на то, что переменная формы объявлена в модуле. Если форма создана, но не отображается на экране, то изменения ее состояния (свойства windowstate) происходят, однако пользователь не видит этого до тех пор, пока форма не будет отображена на экране.
Свойство ActiveControl
Будучи контейнером, форма содержит другие элементы управления. Оконные элементы управления (потомки класса TWinControl) могут получать фокус ввода. Свойство ActiveControl типа TWinControl определяет, какой элемент формы находится в фокусе. Для выбора элемента, находящегося в фокусе ввода (активного элемента), можно устанавливать это свойство в нужное значение при выполнении программы:
Эту же операцию выполняет метод SetFocus, который устанавливает фокус ввода для оконного элемента управления:
Свойство AutoScroll
В случае, когда размеры окна недостаточны для отображения всех содержащихся в форме интерфейсных компонентов, у формы могут появляться полосы прокрутки. Свойство AutoScroll типа Boolean определяет, появляются ли они автоматически, Если свойство AutoScroll имеет значение True (по умолчанию), то полосы прокрутки появляются и исчезают автоматически, без каких-либо действий программиста. Необходимость в полосах прокрутки может возникнуть, например, в случае, если пользователь уменьшит размеры формы так, что не все элементы управления будут полностью видны. Если же свойство AutoScroll установлено в значение False, то программист реализует управление просмотром информации вручную через свойства HorzScrollBar (горизонтальная прокрутка) и VertScrollBar (вертикальная прокрутка) типа TControlScrollBar формы.
Метод ScrollInView
Для программного управления полосами прокрутки можно использовать метод ScrollInView. Процедура ScrollInView (AControl: TControl) автоматически изменяет позиции полос прокрутки так, чтобы заданный параметром AControl элемент управления стал виден в отображаемой области.
Свойство KeyPreview
Свойство KeyPreview типа Boolean определяет, будет ли форма обрабатывать события клавиатуры, прежде чем их обработают элементы управления формы. Если свойство имеет значение False (по умолчанию), то клавиатурные события поступают к активному элементу управления (имеющему фокус ввода). При установке свойства KeyPreview в значение True форма первой получает сообщения о нажатии клавиш и может на них реагировать, что обычно используется для обработки комбинаций клавиш, независимо от активности элементов управления формы.
В вышеуказанной процедуре форма Form1 обрабатывает нажатие алфавитно-цифровых клавиш, отображая введенный символ в диалоговом окне Information.
Форма не может обрабатывать нажатие клавиши в связи с ее особым назначением.
Cвойство MDichildCount и метод Cascade
У формы имеется ряд свойств и методов, например свойство MDichildCount и метод Cascade, предназначенных для организации многодокументных приложений.
Lazarus какие события возникают при открытии формы
IDE LAZARUS
Рассмотрим визуальную среду объектно-ориентированного программирования Lazarus .
Lazarus представляет собой объектно-ориентированную среду визуального программирования. Среда Lazarus визуально реализуется в виде нескольких одновременно раскрытых на экране монитора окон (рис. 1). Количество, расположение, размер и вид окон может меняться в зависимости от текущих нужд, что значительно повышает производительность работы.
Рабочее окно программы имеет следующий вид:

Главное окно (редактор Lazarus ) всегда присутствует на экране и предназначено для управления процессом создания программы. Оно расположено в верхней части экрана, содержит меню, панели инструментов и палитру компонентов.
Меню главного окна содержит стандартные для любой программы пункты. Меню — это самая верхняя строка главного окна (Файл, правка, поиск и т. д.). При помощи меню можно работать с файлами, проектами, формами, настраивать установки и выполнять многие другие действия. Меню главного окна позволяет устанавливать новые компоненты, а также вызывать другие инструменты разработки.
Панели инструментов обеспечивают быстрый доступ к наиболее часто используемым операциям и командам. Все операции, доступные из панели инструментов, дублируются в раскрывающихся меню.
Реализуемое кнопкой действие
Стандартная панель инструментов
Предназначена для создания нового проекта
Предназначена для открытия уже созданного проекта
Предназначена для сохранения текущих изменений в проекте
Предназначена для сохранения всего проекта и для всех изменений в проекте

Предназначена для открытия проекта из файла
Предназначена для добавления файла в проект
Предназначена для удаления файла из проекта
Панель инструментов просмотра
Предназначена для просмотра блока ( unit )
Предназначена для просмотра формы
Предназначена для перехода от формы к блоку
Предназначена для создания новой формы
Панель инструментов управления окнами
Предназначена для отображения имени сохранённой структуры окна

Предназначена для сохранения текущего окна

Предназначена для установления окна отладки
Панель инструментов отладки

Предназначена для запуска проекта

Предназначена для приостановки проекта (пауза)

Предназначена для запуска с заходом на процедуру

Предназначена для запуска без захода на процедуру
Если навести курсор на любую кнопку, то на экране появится всплывающая подсказка с описанием функции данной кнопки.
Палитра компонентов сразу после установки содержит вкладки, на которых расположены компоненты в виде значков. Каждая вкладка объединяет компоненты по назначению. Палитра компонентов состоит из следующих вкладок:
- Standard (содержит стандартные компоненты, такие как кнопки, надписи и т. д.);
- Dialogs (стандартные диалоги для открытия, сохранения и печати файлов. Диалоги вызываются с помощью метода Execute. Возвращаемые значения: True — если пользователь нажал ОК и False — если пользователь выбрал Cancel);
- Common Controls (содержит компоненты позволяющие осуществлять такие команды как просмотр древовидных структур, просмотр списков, панель состояния и т.д.);
- Additional (дополнительные компоненты, такие как рисунок, маска ввода и т. д.);
- System (компонент s для доступа к некоторым системным сервисам).
Рассмотрим компоненты, расположенные на основных закладках, и их назначение. (таблица 2)
Компоненты закладки Standard

Курсор — не компонент, просто пиктограмма для быстрой отмены выбора какого-либо объекта.

MainMenu позволяет поместить главное меню в программу. Данный компонент невидимый.

TPopupMenu позволяет создавать всплывающие меню. Этот тип меню появляется по щелчку правой кнопки мыши на объекте.

TLabel служит для отображения текста на экране. Является однострочным редактором.

TEdit — стандартный компонент для ввода. Используется для отображения короткого фрагмента текста и позволяет вводить текст во время выполнения программы.

TMemo — иная форма TEdit. Подразумевает работу с большими текстами.

TButton позволяет выполнить какие-либо действия при нажатии кнопки во время выполнения программы. (Не цветная)

TCheckBox – независимый переключатель, позволяет выбрать несколько опций из списка.

TRadioButton – зависимый переключатель, позволяет выбрать только одну опция из списка.

TListBox предназначен для показа прокручиваемого списка.

TComboBox – комбинированный список, т.е. список со строкой ввода.

TScrollbar — полоса прокрутки, появляется автоматически в объектах редактирования, предназначена для отображения невидимой информации.

TGroupBox – панель, служит для размещения компонентов на ней.

TRadioGroup– панель, служит для размещения зависимых переключателей.

TPanel – панель, предназначена для компонования компонентов на ней.
Компоненты закладки Dialogs

OpenDialog предназначен для открытия файла.

SaveDialog служит для сохранения файла.

FontDialog используется для настройки шрифта.

ColorDialog используется для выбора цвета.

PrintDialog используется для печати.

PrinterSetupDialog предназначен для настройки принтера.

FindDialog служит для поиска строки.

ReplaceDialog используется для поиска с заменой.
Компоненты закладки Additional

TBitBtn – кнопка, позволяющая выполнять действия во время выполнения программы. Является цветной, причём в неё можно поместить рисунок.

TSpeedButton — кнопка для создания панели быстрого доступа к командам.

TMaskEdit — аналог TEdit, но с возможностью форматированного ввода.

TStringGrid – компонент для создания таблицы, одновременно являясь безразмерным массивом. В ячейках может отражаться как текст, так и рисунок.

TDrawGrid служит для представления данных любого типа в виде таблицы.

TImage отображает графическое изображение на форме.

TShape служит для построения и отображения графических примитивов.

TBevel — элемент для рельефного оформления интерфейса. (Вид панели)

TScrollBox — позволяет создать на форме прокручиваемую область с размерами большими, нежели экран. (Вид панели)
Компоненты закладки Common Controls

TabControl – однострочный блокнот с закладками.

PageControl – многострочный блокнот с закладками.

ImageList – компонент для отображения схем рисунков.

RichEdit – многострочный редактор для ввода форматированного текста.

TrackBar – компонент, предназначенный для перемещения по информации.

ProgressBar – компонент определяющий процентное соотношение выполнения действий.

UpDawn – кнопки задания значений.

StatusBar – строка состояния.
Окно инспектора объектов (Object Inspector), вызывается c помощью клавиши F11. Предназначено для выполнения трёх основных функций: установки свойств компонентов, размещенных на форме; помощи в навигации и создании обработчиков событий; фильтрации свойств и событий. Инспектор объектов состоит из списка свойств и событий. Страница Properties (Свойства) предназначена для изменения необходимых свойств компонента, страница Events (События) – для определения реакции компонента на то или иное событие (например, нажатие определенной клавиши или щелчок “мышью ” по кнопке).
Конструктор форм (Form Designer) при первоначальном запуске представляет собой окно, не содержащее никаких элементов. Это окно называется формой (Form). Разработчик размещает на форме необходимые компоненты из палитры компонентов простым перетаскиванием. Компоненты, расположенные на вкладках панели компонентов, делятся на: визуальные и невизуальные. Визуальными называются компоненты, которые видны на форме во время выполнения приложения. Но они могут быть и невизуальными, если они перекрыты другими компонентами или свойство видимости компонента
(Visible) имеет значение False . Невизуальными называются компоненты, которые отображаются на форме во время создания приложения в виде небольших значков и не отображаются на форме во время выполнения приложения. С помощью мыши можно изменять размеры формы, а также ее положение на экране. Разрабатываемое приложение может содержать неограниченное число форм.
Редактор кода (Code Editor) — это полноценный текстовый редактор, который включает в себя дополнительные функции: стилевое редактирование, проверка синтаксиса и цветовая подсветка команд и многое другое. Он предназначен для просмотра, написания и редактирования текста программы. Когда разработчик начинает новый проект, добавляет новую страницу (модуль) в редакторе кода для главной формы. По умолчанию ей присваивается имя Unit1 .pas . Если в проекте присутствует несколько форм, то для каждой формы в редактор кода добавляется новый модуль (Unit2, Unit3 и т. д.).
Разработчик может сам добавлять новые модули (Unit) при помощи пункта меню главного окна Файл/Новый/Модуль. При этом важно помнить, что для каждой формы автоматически создает модуль, т. е. форма обязательно связана с каким-либо модулем проекта. Переключение между окном формы и модулем осуществляется с помощью клавиши F12. При первоначальной загрузке в окне текста программы находится текст, содержащий минимальный набор операторов для нормального функционирования пустой формы. При помещении некоторого компонента в окно формы текст программы автоматически дополняется описанием необходимых для его работы библиотек стандартных программ (раздел uses) и типов переменных (раздел type).
Программа в среде Lazarus составляется как описание алгоритмов, которые необходимо выполнить, если возникает определенное событие, связанное с формой (например щелчок “мыши” на кнопке – событие OnClick, создание формы – OnCreate). Для каждого обрабатываемого в форме события, с помощью страницы Events инспектора объектов в тексте программы организуется процедура (procedure), между ключевыми словами begin и end которой программист записывает на языке Object Pascal требуемый алгоритм.
Программа состоит из файла проекта, одного или нескольких файлов исходного текста, файлов с описанием окон формы.
В файле проекта находится информация о модулях, составляющих данный проект. Файл проекта автоматически создается и редактируется средой Lazarus и не предназначен для редактирования.
При компиляции программы Lazarus создает файл, содержащий в себе результат перевода в машинные коды содержимого файлов созданных ранее. Компоновщик преобразует файлы в единый загружаемый файл.
Рассмотрев окна программы, закладки с компонентами и сами компоненты, перейдём к размещению основных компонентов на форму. Начнём с закладки Standard.

Размещение компонента TEdit . Необходимо выбрать в меню компонентов Standard пиктограмму , щелкнуть мышью в том месте формы, где её надо поставить. Захватывая его “мышью” отрегулировать размеры окон и их
положение. В тексте программы появилось переменная Edit1. В этой переменной с расширением .Text будет содержаться строка символов (тип String) и отображаться в соответствующем окне Edit.

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

Размещение компонента TMemo . Для вывода результатов работы программы обычно используется текстовое окно, которое представлено компонентом (TMemo). Выбрать в меню компонентов пиктограмму и поместить компонент TMemo на форму. С помощью мыши отрегулировать его размеры и местоположение. В тексте программы появилась переменная Memo1 типа ТMemo. Информация, которая отображается построчно в окно типа Т M emo, находится в массиве строк Memo1.Lines. Каждая строка имеет тип String.

Размещение компонента TButton . Поместить на форму кнопку, которая описывается компонентом ТButton, для чего выберем в меню компонентов Standart пиктограмму. С помощью инспектора объектов можно изменить заголовок (Caption) – Button1 на любое слово. Затем отрегулировать

Размещение компонента T СheckBox. Выбрать пиктограмму и поместить её в нужное место формы. С помощью инспектора объектов изменить заголовок (Caption). В тексте программы появилась переменная CheckBox1 типа TСheckBox. Теперь в зависимости от того, нажата или нет кнопка, булевская переменная CheckBox1.Checked будет принимать значения true или false.
Размещение компонента T StringGrid. Данный компонент принадлежит закладке Additional.

Выбрать пиктограмму и поместить её в нужное место формы. Доступ к информации осуществляется с помощью свойства Cells[ACol, ARow: Integer]: string, где ACol, Arow — индекс элемента двумерного массива. Свойства ColCount и RowCount устанавливают количество строк и столбцов в таблице, а свойства FixedCols и FixedRows задают количество строк и столбцов фиксированной зоны. Фиксированная зона выделена другим цветом, и в нее запрещен ввод информации с клавиатуры.
После размещения компонентов в форме, необходимо установить их свойства и запрограммировать для них обработчики событий. Установка свойств компонента изменяет представление и поведение данного компонента в приложении. Если выбрать компонент из формы, то его свойства и события отобразятся в Инспекторе объектов.
учимся
программировать
Программированию нельзя научить, можно только научится
Главная » Уроки по ООП » Урок 42. Компоненты TDBGrid, TDBCtrlGrid
Урок 42. Компоненты TDBGrid, TDBCtrlGrid
Компонент TDBGrid
TDBGrid — таблица, в которой строки представляют собой записи, а столбцы — поля набора данных. Свойство DataSource содержит ссылку на выбранный набор данных.
Столбцы DBGrid
Столбцы – поля подключенного набора данных. Этими значениями можно манипулировать, показывая или скрывая поля НД, меняя их местами или добавляя новые столбцы. Требуемый набор полей можно составить при помощи специального Редактора столбцов (рис. 1), который открывается при двойном щелчке на компоненте, перенесенном на форму.
В верхней части окна вы видите четыре кнопки, слева — направо:
- Add New (Добавить новый столбец).
- Delete Selected (Удалить выделенный столбец).
- Add All Fields (Добавить все столбцы из набора данных).
- Restore Defaults (Восстановить значения по умолчанию для выделенного столбца).

Рис. 1. Редактор колонок компонента TDBGrid
Для выбранного в списке столбца доступные для редактирования свойства появляются в Инспекторе объектов. Столбцы в списке можно редактировать, удалять, менять местами.
Изменить параметры заголовка столбца можно в раскрывающемся свойстве Title, которое имеет ряд собственных свойств:
Alignment — свойство устанавливает выравнивание заголовка и может быть taCenter (по центру), taLeftJustify (по левому краю) и taRightJustify (по правому краю).
Caption — свойство содержит текст, который отображается в заголовке столбца.
Color — цвет заголовка.
Font — шрифт заголовка.
Свойства Font, Alignment и Color внутри свойства Title меняют шрифт, выравнивание и цвет фона только заголовка столбца, а не его содержимого. Но у столбца имеются эти же свойства, они меняют шрифт, выравнивание и цвет фона выводимых в столбце данных.
Свойство Visible разрешает или запрещает отображение столбца, а свойство Width позволяет изменить его ширину.

Задание 1. Работа с редактором полей компонента DBGrid
1. Установите на форму компонент ADOTable, свяжите его с таблицей Pers базы Сотрудники (свойства ConnectionString – связать с базой Сотрудники, TableName=Pers, Active=True).
2. Установите DataSource, свяжите его с ADOTable1. .
3. На форму добавьте и компонент DBGrid, который свяжите с DataSource1..
4. Нам нужны не все поля таблицы, а только некоторые из них. Дважды щелкните по компоненту DBGrid1 и в открывшемся редакторе столбцов нажмите кнопку Add New. Появится один пустой столбец. Для того, чтобы он показал данные нужного поля, выделите его и в инспекторе объектов в свойстве FieldName выберите поле Fam. .
5. Найдите свойство Title, раскройте его нажатием на кнопку «+». Настройте подсвойство Alignment=taCenter, Caption=”Фамилия”, Font установите полужирным. Найдите свойство Width, установите его равным 150. .
6.Аналогично добавьте и настройте свойства полей Nam, Par, Sex, Dep.
.
Рисунок 2. Форма к заданию 1.
Пустые столбцы
Если добавить в редактор столбцов сетки DBGrid новый столбец, но в свойстве FieldName не выбирать поле БД, а оставить его пустым, мы получим пустой столбец. Для чего нужны пустые столбцы в сетке? В них можно выводить обработанные данные из других столбцов.
Задание 2. К примеру, пользователю неудобно просматривать три столбца «Фамилия», «Имя» и «Отчество» из таблицы Pers базы данных Сотрудники. Ему было бы удобней просмотреть один сборный столбец в формате «Фамилия И.О.». .
1. Это и все последующие задания выполнять в программе из задания 1..
2. Создайте новый столбец, но не назначайте ему поле из НД. Выделите этот столбец, и в его свойстве Title.Caption впишите «Фамилия И.О.», а в свойстве Width укажите ширину в 200 пикселей. .
3. Столбцы «Фамилия», «Имя» и «Отчество» нам уже не нужны, скройте их, установив их свойство Visible в False. А новый столбец перетащите мышью наверх, его индекс будет равен 0..
4. Для компонента DBGrid1 создайте обработчик события OnDrawColumnCell. Это событие наступает при прорисовке каждой ячейки столбца. В него внесите код:.
var s: String;
begin
if Column.Index = 0 then //если это пустой столбец
begin
if ADOTable1[‘Fam’]<>Null then s:=ADOTable1[‘Fam’] + ‘ ‘;
if ADOTable1[‘Nam’]<>Null then s:=s + Copy(ADOTable1[‘Nam’], 1, 1)+ ‘.’;
if ADOTable1[‘Par’] <>Null then s:=s + Copy(ADOTable1[‘Par’], 1, 1) + ‘.’;
DBGrid1.Canvas.TextOut(Rect.Left, Rect.Top, s);
end;
end;

Здесь мы вначале проверяем — наш ли это столбец (равен ли индекс нулю)? Если наш, то в переменную s начинаем собирать нужный текст. При этом имеем в виду, что пользователь мог и не заполнить некоторые поля. Чтобы у нас не произошло ошибки, вначале убеждаемся, что поле не равно Null (то есть, текст есть). Если текст есть, добавляем его в переменную s. Причем если это имя или отчество, с помощью функции Copy() получаем только первую букву и добавляем к ней точку. Когда s сформирована, добавляем этот текст в наш столбец с помощью метода TextOut() свойства Canvas сетки. В метод передаются три параметра: координаты левой позиции, верхней позиции и сам текст. Эти координаты мы берем из параметра события OnDrawColumnCell — Rect, который имеет такие свойства, как Left и Top, показывающие, соответственно, левую и верхнюю позиции текущей ячейки.
В результате программа будет иметь вид:
Рисунок 3. Заполнение пустого столбца

Задание 3. Использовать пустой столбец для вывода информации по требованию пользователя. В DBGrid нам нужна кнопка, нажатие на которую привело бы к выводу сообщения об отделе, в котором работает сотрудник.
1. Откройте редактор столбцов и удалите столбец Dep.
2. Создайте новый пустой столбец. Перетаскивать его не нужно, пусть будет последним. Свойство Width (ширина) установите в 20 пикселей. Название столбца (Title.Caption) пусть будет пустым. В свойстве ButtonStyle выберите значение cbsEllipsis. Это приведет к тому, что при попытке редактировать этот столбец образуется кнопка с тремя точками:
Рисунок 4. Кнопка в пустом столбце
3. Создайте обработчик события OnEditButtonClick() компонента DBGrid. Это событие происходит всякий раз, когда пользователь нажимает на кнопку «…».
4. Теперь, когда пользователь нажмет на эту кнопку, ему будет выведено сообщение с текстом об отделе, в котором работает сотрудник.
Список выбора в столбце — PickList
DBGrid позволяет устроить список, аналогичный ComboBox в одном из своих столбцов без использования каких-либо других компонентов.

Задание 4. Создать для поля «Sex» список выбора значений (муж, жен).
1. Откройте редактор столбцов сетки и выделите столбец «Sex». Обратите внимание на свойство PickList в Инспекторе объектов. Это свойство имеет тип TStrings, то есть представляет собой набор строк. Щелкните дважды по PickList, чтобы открыть редактор, и впишите туда
муж
жен
именно так, каждое значение на своей строке.
2. Запустите программу и попробуйте редактировать этот столбец. При попытке редактирования в ячейке покажется похожий на ComboBox список, в котором можно будет выбрать одно из указанных значений:
Рисунок 5. Список выбора в сетке
Наличие такого списка не препятствует пользователю ввести какое-то иное значение. Этот список нужен не для контроля, а только для облегчения пользователю ввода данных. Если же вы не желаете, чтобы пользователь имел возможность вводить другие данные, контроль следует организовать иным способом.
В практике программирования список чаще формируется во время работы программы, а строки списка берутся, как правило, из другой связанной таблицы. Добавить в список новую строку очень просто: DBGrid1.Columns.Items[4].PickList.Add(‘абв’);
Список свойства PickList автоматически заполняется для поля синхронного просмотра (lookup-поле).
Выделение отдельных строк
Очень часто в практике приходится выделять какие-то строки, изменяя их фон или цвет шрифта. Например, в бухгалтерии обычно выделяют строки, в которых значение меньше нуля. Допустим, ваша программа показывает клиентов, а какой-то столбец содержит их баланс на счету вашей компании. Если этот баланс меньше 0, значит, клиент имеет задолженность перед вашей фирмой. Бухгалтеру будет очень удобно, если дебиторы (должники) будут выделяться в общем списке красным цветом.
Способ прорисовки данных в DBGrid зависит от значения его свойства DefaultDrawing. По умолчанию свойство равно True, то есть данные прорисовываются автоматически. Если свойство содержит False, то прорисовку придется кодировать самостоятельно в свойстве OnDrawColumnCell.
Если мы написали алгоритм прорисовки, но свойство DefaultDrawing содержит True, то вначале сетка заполнится данными автоматически, а затем будет выполнен наш алгоритм. Другими словами, прорисовка некоторых частей сетки будет выполнена дважды. Это не очень хорошо для быстродействия программы, однако нам придется поступать именно так: ведь мы не все строки и столбцы собираемся выводить другим способом, а только некоторые. Остальные будут заполнены данными по умолчанию.
Разберем этот метод подробней. Если найти его в справке Delphi, то увидим:
property OnDrawColumnCell: TDrawColumnCellEvent;
То есть, этот метод имеет тип TDrawColumnCellEvent. Описание типа такое:
type TDrawColumnCellEvent = procedure (Sender:TObject; const Rect:TRect;
DataCol:Integer; Column:TColumn; State:TGridDrawState) of object;
Разберемся с параметрами.
Rect — координаты прорисовки.
DataCol — порядковый номер текущего столбца (начиная с 0).
Column — данные текущего столбца.
State — состояние ячейки. Может быть:

- gdSelected — ячейка выделена
- gdFocused — фокус ввода в ячейке
- gdFixed — ячейка — заголовок столбца. Задание 5. Изменение цвета шрифта записей сотрудников, относящихся к отделу Бухгалтерия, на красный.
Рисунок 6. Выделение строк
Заметим сразу, что наличие пустых столбцов создает дополнительные, но решаемые проблемы. Код события OnDrawColumnCell придется переделать, он будет таким: var s: String;
begin - Инструкционная карта
- Лекция
- Дополнительный материал