Прежде чем продолжить обсуждение примера Alarms, сделаем несколько замечаний по поводу редактирования многострочного текста. Многострочный редактор представлен компонентом Memo (рис. 7. 31).
Характерные свойства компонента Memo описаны в таблице:
Свойство |
Описание |
Align |
Способ выравнивания многострочного редактора в пределах владельца. |
Alignment |
Расположение текста в пределах редактора: taleftJustify - прижат к левой границе, taRightJustify – прижат к правой границе, taCenter - центрирован. |
HideSelection |
Если равно True, то при потере редактором активности выделение текста снимается. |
Lines |
Строки текста в многострочном редакторе. |
Maxlength |
Максимальное количество символов, которое пользователь может ввести. Если оно равно 0, то пользователь может ввести текст неограниченной длины. |
OEMConvert |
Если равно True, то символы текста преобразуются в кодовую таблицу OEM. |
ReadОnly |
Если равно True, то пользователь не сможет изменить текст в редактор. |
ScrollBars |
Управляет видимостью полос прокрутки: ssNone - полосы прокрутки скрыты, ssBoth - полосы прокрутки видны, ssHorizontal - видна лишь горизонтальная полоса прокрутки, ssVertical - видна лишь вертикальная полоса прокрутки. |
WantReturns |
Если равно True, то клавиша Enter начинает в редакторе новую строку. |
WantTabs |
Если равно True, то клавиша Tab вставляет в текст символ табуляции вместо того чтобы передать фокус ввода следующему управляющему элементу. |
Wordwrap |
Если равно True, то работает перенос слов. |
Компонент Memo похож на Edit, но в отличие от него хранит не одну строку текста, а множество строк. Доступ к строкам обеспечивает свойство Lines, представляющее собой объект класса TStrings. С помощью объекта Lines строки можно добавлять. вставлять, удалять и т. д. Свойство Lines доступно из Инспектора Объектов, поэтому на стадии проектирования вы можете заполнить компонент Memo некоторым исходным текстом. Этот текст увидит пользователь при появлении формы на экране. Ввод исходного текста осуществляется в Редакторе Строк (String list editor), который вызывается щелчком мыши на многоточии в поле значения свойства Lines (рис. 7. 32).
Компонент Memo часто имеет одну или две полосы прокрутки (вертикальную и горизонтальную). Их появление зависит от значения свойства ScrollBars.
В нашем приложении Alarms компонент Memo не нужен, но вам он безусловно пригодится.
РЕДАКТОР С ШАБЛОНОМ
Поскольку управляющий элемент Edit не проверяет, что вводит пользователь, он неудобен для ввода данных строго определенного формата, например телефонных номеров, времени и др. На этот случай разработчики Delphi предусмотрительно поместили в Палитру Компонентов компонент MaskEdit. Он находится на странице Additional (рис. 7. 33).
Компонент MaskEdit представляет собой однострочный редактор, который вынуждает пользователя вводить разрешенные символы в разрешенных позициях. Во многом аналогичный компоненту Edit, он отличается от последнего тем, что имеет свойство EditMask и не имеет свойств HideSelection и OEMConvert.
Свойство EditMask задает шаблон (маску) для ввода символов текста. Шаблон имеет вид текстовой строки, его символы называются форматными и управляют тем, что вводит пользователь: буквы или цифры, в каком порядке, сколько и т. д. Мы не будем утомлять вас подробным описанием форматных символов, при необходимости обратитесь к справочному руководству. Нас интересует только шаблон для ввода времени с точностью до минуты.
Шаг 15. Выберите компонент TimeMaskEdit, затем активизируйте в Инспекторе Объектов свойство EditMask и щелчком на кнопке с многоточием откройте Редактор Шаблона (Input Mask Editor) (рис. 7. 34):
В этом окне вы можете ввести шаблон и проверить его работу. Часто используемые шаблоны, например шаблоны телефонных номеров, даты, времени и некоторые другие, можно просто выбрать среди уже имеющихся образцов. Этой возможностью мы и воспользуемся. Выберите в списке Sample Masks пункт Short Time и щелкните на кнопке ОК. Шаблон для ввода времени задан и имеет вид! 90: 00; 1; _. Обратите внимание, как при этом изменился компонент TimeMaskEdit (рис. 7. 35);
Шаг 16. Теперь давайте сделаем так, чтобы при появлении окна диалога редактор TimeMaskEdit не был пустой, а содержал текущее время. Для этого определите для формы SettingsForm следующий обработчик события OnCreate:
procedure TSettingsForm. FormCreate (Sender: TObject);
begin
TimeMaskEdit. Text: = FormatDateTime ('hh: mm', Time);
end;
Готово. Запустите программу и убедитесь, что она работает так, как вы ожидаете.
КНОПКИ ДЛЯ УВЕЛИЧЕНИЯ И УМЕНЬШЕНИЯ ЧИСЛОВЫХ ЗНАЧЕНИЙ
Отдельный интерес представляет собой ввод целых чисел. Мы встретились с ним при вводе года в окне диалога Alarm Settings. Ввод чисел может быть значительно упрощен для пользователя при использовании пары кнопок с противоположно направленными стрелками (рис. 7. 36).
Согласитесь, что перебирать года, щелкая по двум таким кнопкам, значительно проще, чем нажимать цифровые клавиши на клавиатуре. Мы советуем никогда не пренебрегать этими удобными “мелочами”, тем более, что они очень легко реализуются.
Управляющий элемент в виде пары кнопок с противоположно направленными стрелками называется UpDown. Это стандартный компонент Windows 95, поэтому он находится в Палитре Компонентов на странице Win95 (рис. 7. 37).
Характерные свойства компонента UpDown описаны в таблице:
Свойство |
Описание |
AlignButton |
Положение пары кнопок относительно ассоциированного компонента: udleft - кнопки слева, udRight - кнопки справа. |
Associate |
Указывает на ассоциированный компонент, в области которого отображается значение свойства Position (обычно это строка редактора). При установке свойства Associate пара кнопок автоматически располагается слева или справа от ассоциированного компонента в зависимости от значения свойства AlignButton. |
ArrowKeys |
Если равно True, то нажатия на клавиатуре клавиш со стрелками “вверх” и “вниз” обрабатываются так же, как и щелчки на кнопках управляющего элемента. |
Increment |
Величина, на которую увеличивается или уменьшается свойство Position в результате щелчков на кнопках со стрелками. |
Min, Max |
Минимальное и максимальное значения свойства Position. |
Orientation |
Ориентация стрелок: udHorizontal - горизонтально, udVertical -вертикально. |
Position |
Числовое значение, корректируемое в области ассоциированного компонента. |
Thousands |
Если равно True, то после каждых трех цифр десятичного числа вставляется разделитель разрядов. |
Wrap |
Если равно True, то превышение максимального значения Мах приво-дит к сбрасыванию свойства Position в минимальное значение Min. |
Компонент UpDown наиболее часто применяется в сочетании с компонентом Edit. На форме SettingsForm компоненты этих типов называются YearUpDown и YearEdit. Давайте приспособим их для ввода года.
Шаг 17. Сначала выберите компонент YearUpDown и установите его свойства в следующие значения:
Associate = YearEdit; Min =1; Мах = 9999
Вы увидите, что компонент YearUpDown автоматически прижмется к правой границе компонента YearEdit и отобразит в нем значение Position.
Шаг 18. Теперь выберите компонент YearEdit и установите его свойство Readonly в True. Это самый простой и эффективный способ, чтобы избавиться от ошибочной установки года пользователем (например, ввода букв вместо цифр). Как же тогда вводить год с клавиатуры? Очень просто, нажимая клавиши со стрелками “вверх” и “вниз”. Эта возможность обеспечивается компонентом UpDown по умолчанию (если ее нужно отключить, установите свойство ArrowKeys в значение False).
Шаг 19. В нашей задаче недостаточно просто привязать компонент YearUpDown к компоненту YearEdit. По щелчкам на кнопках со стрелками необходимо корректировать год в календаре (компоненте Calendar) и возвращать фокус ввода редактору года. Для этого определите в компоненте YearUpDown следующий обработчик события OnClick:
procedure TSettingsForm. YearUpDownClick (Sender: TObject;
Button: TUDBtnType);
begin
case Button of
btNext: Calendar. NextYear;
btPrev: Calendar. PrevYear;
end;
YearEdit. SetFocus;
end;
Шаг 22. Теперь компоненты WeeklyCombo и MonthCombo нужно заполнить списками исходных значений. Начнем с компонента WeeklyCombo. Выберите его на форме, затем активизируйте в Инспекторе Объектов свойство Items и щелкните на кнопке с многоточием в поле значения. В появившемся окне введите список строк, как показано на рисунке (рис. 7. 40).
Щелкните по кнопке OK — список строк компонента WeeklyCombo задан. Аналогичным образом задайте список строк для компонента MonthCombo (рис. 7. 41):
Шаг 23. Количество одновременно видимых элементов выпадающего списка определяется значением свойства DropDownCount и по умолчанию равно 8. Если число элементов списка больше указанного значения, выполняется прокрутка. Число месяцев в году всегда равно 12, т. е. величина константная, поэтому желательно, чтобы пользователь видел названия всех месяцев сразу, без всякой прокрутки. Для этого в компоненте MonthCombo установите свойство DropDownCount в значение 12. Кстати, с компонентом WeeklyCombo такой проблемы не возникло, потому что количество его элементов равно 7, т. е. меньше 8.
Шаг 24. Выбранный элемент выпадающего списка определяется значением свойства
Itemlndex.
Обратите внимание, что оно доступно только из программы. Начальное значение
свойства равно —1, что означает — ни один элемент не выбран. Однако в
компонентах WeeklyCombo и MonthCombo должны быть выбраны те значения,
которые соответствуют текущей дате. С этой целью нужно доработать у формы
обработчик события OnCreate. В итоге он будет иметь следующий вид:
procedure TSettingsForm. FormCreate (Sender: TObject);
begin
{ Установка текущего времени}
TimeMaskEdit. Text: = FormatDateTime ('hh: mm', Time);
{ Установка текущего года}
YearUpDown. Position: = Calendar. Year;
{ Установка текущего дня недели}
WeeklyCombo. Itemlndex: = DayOfWeek (Calendar. CalendarDate) - 1;
{ Установка текущего месяца}
MonthCombo. Itemlndex: = Calendar. Month - 1;
end;
Реализация метода основана на том, что компонент Calendar при создании формы имеет текущую дату (так оно и есть на самом деле).
Шаг 25. Да, мы чуть было не забыли об одной важной вещи! При выборе месяца^нужно менять содержимое календаря. С этой целью определите в компоненте MonthCombo обработчик события OnChange.
procedure TSettingsForm. MonthComboChange (Sender:
TObject);
begin
if Calendar. Month <> MonthCombo. Itemlndex+ 1
then begin
Calendar. Day: = 1;
Calendar. Month: = MonthCombo. Itemlndex+ 1;
end;
end;
На этом с визуальной частью диалога Alarm Settings покончено. Правда, мы ничего не сказали о компоненте Calendar. Впрочем, он уже работает так, как надо. В нем нет ничего сложного и мы надеемся, что вы сможете разобраться с ним самостоятельно.
В очередной раз скомпилируйте проект и запустите приложение. Откройте окно диалога Alarm Settings и хорошенько его протестируйте. Все управляющие элементы работают правильно. Можете поздравить себя с очередным достижением. Вы создали важную часть приложения Alarms — окно диалога, а заодно разобрались с множеством новых компонентов.