Файл: Учебное пособие для студентов Авторы А. Н. Вальвачев, К. А. Сурков, Д. А. Сурков, Ю. М. Четырько Содержание Содержание 1.doc
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 04.05.2024
Просмотров: 126
Скачиваний: 4
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Таблица 9.10. Важнейшие свойства и события компонента Memo
Компонент Memo похож на Edit, но в отличие от него хранит не одну строку текста, а множество строк. Доступ к строкам обеспечивает свойство Lines, представляющее собой объект класса TStrings (см. главу 3). С помощью свойства Lines строки можно добавлять, вставлять, удалять и т.д. Свойство Lines доступно в окне свойств, поэтому на стадии проектирования вы можете заполнить компонент Memo некоторым исходным текстом (рисунок 9.35). Этот текст увидит пользователь при появлении формы на экране. Ввод исходного текста осуществляется в специальном редакторе текста (String list editor), которое вызывается нажатием кнопки с многоточием в поле значения свойства Lines.
Рисунок 9.35. Окно для ввода многострочного текста, отображаемого компонентом Memo
Компонент Memo часто имеет одну или две полосы прокрутки (вертикальную и горизонтальную). Их появление зависит от значения свойства ScrollBars.
В нашем приложении Alarms компонент Memo не нужен, но вам он безусловно пригодится в других программах.
9.3.7. Редактор с шаблоном
Поскольку компонент Edit не проверяет, что вводит пользователь, он не удобен для ввода данных строго определенного формата, например телефонных номеров, времени и др. На этот случай разработчики среды Delphi предусмотрительно создали компонент MaskEdit. Он находится в палитре компонентов на вкладке Additional (рисунок 9.36).
Рисунок 9.36. Компонент MaskEdit
Компонент MaskEdit представляет собой поле ввода, которое вынуждает пользователя вводить данные в строго заданном формате. Во многом аналогичный компоненту Edit, он отличается от последнего тем, что имеет свойство EditMask и не имеет свойств HideSelection и OEMConvert.
Свойство EditMask задает шаблон (маску) для ввода символов текста. Шаблон имеет вид текстовой строки, его символы называются форматными и управляют тем, что вводит пользователь: буквы или цифры, в каком порядке, сколько и т.д. Мы не будем утомлять вас подробным описанием форматных символов, при необходимости обратитесь к справочному руководству. Нас интересует только шаблон для ввода времени с точностью до минуты.
Шаг 17. Выберите компонент TimeMaskEdit, затем в окне свойств перейдите к свойству EditMask и щелчком кнопки с многоточием откройте специальный редактор для этого свойства — Input Mask Editor (рисунок 9.37):
Рисунок 9.37. Выбор шаблона для компонента MaskEdit
В этом окне вы можете ввести шаблон и проверить его работу. Часто используемые шаблоны, например шаблоны телефонных номеров, даты, времени и некоторые другие, можно просто выбрать среди уже имеющихся образцов. Этой возможностью мы и воспользуемся. Выберите в списке Sample Masks пункт Short Time и щелкните на кнопке OK. Шаблон для ввода времени задан и имеет вид !90:00;1;_ . Обратите внимание, как при этом изменился компонент TimeMaskEdit (рисунок 9.38):
Рисунок 9.38. Компонент MaskEdit настроен для ввода времени
Шаг 18. Теперь давайте сделаем так, чтобы при появлении окна диалога поле ввода TimeMaskEdit не было пустым, а содержало текущее время. Для этого создайте у формы обработчик события OnCreate:
procedure TAlarmDetailsForm.FormCreate(Sender: TObject);
begin
TimeMaskEdit.Text := FormatDateTime('hh:mm', Time);
end;
Готово. Запустите программу и убедитесь, что она работает, как вы того ожидаете.
9.3.8. Раскрывающийся список
Раскрывающийся список (combo box) позволяет пользователю выбрать значение из большого множества альтернатив. Он представляет собой поле ввода, к которому прикреплен раскрывающийся список значений. Редактор служит для ввода нового значения, а список — для выбора существующего значения. Количество элементов в списке может быть произвольным, причем элементы можно динамически добавлять, удалять, заменять и т.д. Элементами списка обычно служат текстовые строки, но могут быть и графические рисунки (в последнем случае их редактирование невозможно).
Раскрывающийся список представлен компонентом ComboBox, который находится в палитре компонентов на вкладке Standard (рисунок 9.39):
Рисунок 9.39. Компонент ComboBox
Характерные свойства компонента ComboBox собраны в таблице 9.11.
Свойство | Описание |
AutoCloseUp | Если равно True, то при вводе пользователем текста, который уже существует в списке Items, раскрытый список значений автоматически закрывается. |
AutoComplete | Если равно True, то компонент предугадывает вводимый пользователем текст на основе списка Items. |
AutoDropDown | Если равно True, то при вводе текста автоматически раскрывается список существующих значений. |
BevelEdges | Вложенные свойства beLeft, beTop, beRight и beBottom определяют видимость соответственно левой, верхней, правой и нижней сторон рельефной рамки. |
BevelInner | Внутренний скос рельефной рамки: bvNone — скос отсутствует, bvLowered — скос внутрь, bvRaised — скос наружу; bvSpace — скос заменяется отступом. |
BevelKind | Вид рельефной рамки: bkNone — рамки нет, bkTile — рамка с четкими скосами, bkSoft — рамка со сглаженными скосами, bkFlat — плоская рамка (без скосов). |
BevelOuter | Внешний скос рельефной рамки: bvNone — скос отсутствует, bvLowered — скос внутрь, bvRaised — скос наружу; bvSpace — скос заменяется отступом. |
CharCase | Автоматическое преобразование регистра букв: ecLowerCase — к строчным буквам, ecUpperCase — к заглавным буквам, ecNormal — без преобразования. |
DropDownCount | Количество одновременно видимых элементов раскрывающегося списка. |
ItemHeight | Высота отдельного элемента списка, когда значение свойства Style равно csOwnerDrawFixed. |
ItemIndex | Порядковый номер выбранного в списке элемента, начиная с нуля. |
Items | Элементы раскрывающегося списка. |
MaxLength | Максимальное количество символов, которое пользователь может ввести в строке редактора. Если оно равно 0, то пользователь может ввести текст неограниченной длины. |
Sorted | Если равно True, то элементы списка сортируются в алфавитном порядке. |
Style | Стиль отображения выпадающего списка (см. табл. 7.12). |
Text | Текст в строке редактора. |
OnChange | Происходит при вводе текста или выборе значения из списка. Не происходит при программном изменении свойства Text. |
OnCloseUp | Происходит при закрытии списка значений. |
OnDrawItem | Происходит при рисовании элемента раскрывающего списка, но только в том случае, если свойство Style содержит значение csOwnerDrawFixed или csOwnerDrawVariable. |
OnDropDown | Происходит при раскрытии списка значений. |
OnMeasureItem | Происходит перед рисованием элемента раскрывающего списка для расчета его высоты. Требует, чтобы свойство Style содержало значение csOwnerDrawVariable. |
OnSelect | Происходит при выборе значения в раскрывающемся списке. |
Таблица 9.11. Важнейшие свойства компонента ComboBox
Раскрывающийся список умеет отображать себя по-разному в зависимости от значения свойства Style (см. таблицу 9.12).
Значение | Описание |
csSimple | Редактор и постоянно отображаемый список. |
csDropDown | Редактор и ассоциированный с ним раскрывающийся список. |
csDropDownList | Раскрывающийся список без редактора. Все элементы списка имеют одинаковую высоту, которая рассчитывается автоматически. |
csOwnerDrawFixed | Раскрывающийся список без редактора. Все элементы списка имеют одинаковую высоту, заданную в свойстве ItemHeight. |
csOwnerDrawVariable | Раскрывающийся список без редактора. Элементы списка имеют разную высоту. |
Таблица 9.12. Значения свойства Style компонента ComboBox
В двух последних случаях в компоненте ComboBox происходит событие OnDrawItem. Вы можете его перехватить и рисовать каждый элемент выпадающего списка как вам вздумается. Если элементы списка имеют разную высоту (стиль csOwnerDrawVariable), то компонент генерирует событие OnMeasureItem, чтобы узнать высоту каждого элемента. Стили csOwnerDrawFixed и csOwnerDrawVariable применяются в тех случаях, когда элементы списка должны быть рисунками.
Шаг 19. Раскрывающиеся списки пригодились нам в диалоге Alarm Details для выбора дня недели (компонент WeeklyComboBox). Поскольку все дни недели заранее известны, выберите в свойстве Style значение csDropDownList (рисунок 9.40).
Рисунок 9.40. Для выбора дня недели применяется компонент ComboBox в стиле csDropDownList
Шаг 20. Теперь компонент WeeklyComboBox нужно заполнить списком исходных значений. Выберите его в форме, затем в окне свойств перейдите к свойству Items и нажмите кнопку с многоточием в поле значения. В появившемся окне введите список строк, как показано на рисунке 9.41.
Рисунок 9.41. В этом окне вводятся элементы списка — дни недели
Щелкните кнопку OK — список значений компонента WeeklyComboBox задан.
Шаг 21. Выбранный элемент раскрывающегося списка определяется значением свойства ItemIndex
. Начальное значение свойства равно -1, что означает — ни один элемент не выбран. Однако в компоненте WeeklyComboBox должно быть выбрано то значение, которое соответствуют текущей дате. С этой целью нужно доработать у формы обработчик события OnCreate. В итоге он будет иметь следующий вид:
procedure TAlarmDetailsForm.FormCreate(Sender: TObject);
begin
// Установка текущего времени
TimeMaskEdit.Text := FormatDateTime('hh:mm', Time);
// Установка текущего дня недели
WeeklyComboBox.ItemIndex := DayOfWeek(DatePicker.Date) - 1;
end;
Реализация метода основана на том, что компонент DatePicker при создании формы сразу содержит текущую дату.
На этом с визуальной частью диалога Alarm Details покончено. Правда, мы ничего не сказали о компоненте DateTimePicker (рисунок 9.42).
Рисунок 9.42. Компонент DateTimePicker
Впрочем, он уже работает так, как требуется. В нем нет ничего сложного, и мы надеемся, что вы разберетесь с ним по таблице 9.13.
Свойство | Описание |
BevelEdges | Вложенные свойства beLeft, beTop, beRight и beBottom определяют видимость соответственно левой, верхней, правой и нижней сторон рельефной рамки. |
BevelInner | Внутренний скос рельефной рамки: bvNone — скос отсутствует, bvLowered — скос внутрь, bvRaised — скос наружу; bvSpace — скос заменяется отступом. |
BevelKind | Вид рельефной рамки: bkNone — рамки нет, bkTile — рамка с четкими скосами, bkSoft — рамка со сглаженными скосами, bkFlat — плоская рамка (без скосов). |
BevelOuter | Внешний скос рельефной рамки: bvNone — скос отсутствует, bvLowered — скос внутрь, bvRaised — скос наружу; bvSpace — скос заменяется отступом. |
BevelWidth | Ширина скосов рельефной рамки. |
CalAlignment | Способ выравнивания раскрывающегося диалога: dtaLeft — по левому краю, dtaRight — по правому краю. |
CalColors | Цвета: BackColor — ни на что не влияет, существует для унификации настройки цвета с другими компонентами; MonthBackColor — цвет фона раскрывающего диалога; TextColor — цвет текста; TitleBackColor — цвет фона заголовка; TitleTextColor — цвет текста заголовка; TrailingTextColor — цвет текста дат, не принадлежащих текущему месяцу. |
Checked | Значение переключателя, который отображается, если свойство ShowCheckbox содержит значение True. |
Date | Выбранная дата. |
DateFormat | Формат даты: dfShort — короткий, dfLong — длинный. |
DateMode | Режим работы компонента: dmComboBox — по щелчку кнопки со стрелкой раскрывается окно с месячным календарем, dmUpDown — вместо кнопки со стрелкой показывается пара кнопок со стрелками вверх и вниз, щелчки на которых прокручивают день, месяц или год. |
Format | Формат даты и времени. |
Kind | Если равно значению dtkDate, то компонент предназначен для выбора даты, а если значению dtkTime, то для выбора времени. |
MaxDate | Максимальное значение даты, которое может выбрать пользователь. |
MinDate | Минимальное значение даты, которое может выбрать пользователь. |
ParseInput | Если равно значению True, то по мере ввода значения пользователем происходит событие OnUserInput. |
ShowCheckbox | Показывает переключатель (флажок). Значение переключателя определяется свойством Checked. |
Time | Выбранное время. |
OnChange | Происходит при изменении значения даты и времени. |
OnCloseUp | Происходит при сворачивании раскрывающегося диалога. |
OnUserInput | Происходит по мере ввода данных пользователем. |
Таблица 9.13. Важнейшие свойства и события компонента DateTimePicker
В очередной раз выполните компиляцию программы и запустите ее. Откройте окно диалога Alarm Details и хорошенько его потестируйте (рисунок 9.43).
Рисунок 9.43. Тестирование окна AlarmDetails
Все компоненты работают правильно. Можете поздравить себя с очередным достижением. Вы создали важную часть приложения Alarms — окно диалога, а заодно разобрались с множеством новых компонентов.
9.3.9. Установка и получение данных
Окно диалога есть, но пользы от него пока нет. Все дело в том, что мы научились устанавливать параметры будильника, но не научились их принимать и хранить.
Шаг 22. Для хранения параметров будильника нам нужна новая структура данных, очевидно класс объектов. Немного поразмыслив, приходим к следующему описанию:
type
TAlarm = class
private
Handled: Boolean;
public
MsgText: string;
DateTime: TDateTime;
PlaySound: Boolean;
Recurring: Integer;
function GetAlarmStr: string;
procedure CheckTime;
end;
Поясним назначение полей и методов. Поле MsgText предназначено для хранения текстового сообщения. В поле DateTime записывается время и дата сигнала. Значение поля PlaySound показывает, требуется ли звуковое сопровождение сообщения. Поле Recurring определяет периодичность работы будильника и принимает следующие значения:
-
0 – ежедневно; -
1..7 – в заданный день недели (1 — Пн, 2 — Вт, ..., 7 — Вс); -
8 – однажды в заданный день.
В первых двух случаях поле DateTime хранит только время, а в последнем еще и дату. Такое ухищрение позволяет организовать компактное хранение данных. Флаг Handled, объявленный в секции private, является служебным и позволит избежать повторных срабатываний, когда будильник уже прозвенел. Метод GetAlarmStr мы определили для удобства. Он будет формировать строку сообщения, содержащую время и текст напоминания. Метод CheckTime проверит, пора ли выдать сигнал и если да, то сделает это.
Шаг 23. Поместите описание класса TAlarm в раздел interface модуля AlarmDetails. Затем в разделе implementation наберите текст методов GetAlarmStr и CheckTime:
function TAlarm.GetAlarmStr: string;
begin
Result := FormatDateTime('hh:mm ', DateTime) + MsgText;
end;
procedure TAlarm.CheckTime;
var
Hour1, Min1, Sec1, MSec1: Word;
Hour2, Min2, Sec2, MSec2: Word;
Match: Boolean;
begin
// Декодировать текущее время
DecodeTime(Time, Hour1, Min1, Sec1, MSec1);
// Раскодировать текущее время будильника