Учебное пособие для студентов Авторы А. Н. Вальвачев, К. А. Сурков, Д. А. Сурков, Ю. М. Четырько Содержание Содержание 1
Скачать 2.61 Mb.
|
Label? А тем, что может получать фокус ввода. Кроме того, текст в поле ввода можно выделить и поместить в Буфер Обмена. Компонент Edit легко приспособить для ввода паролей. Для этого достаточно установить в свойстве PasswordChar вместо символа #0 какой-нибудь другой символ, обычно символ звездочки (*). Символ, заданный в свойстве PasswordChar отображается вместо реально вводимых символов, что мешает подсмотреть пароль посторонним. Шаг 15. В форме SettingsForm компонент Edit применяется для ввода текстового сообщения будильника. Выберите его в окне свойств и в значении свойства Text впишите "Reminder !" (рисунок 9.33). Этот текст будет появляться в редакторе при появлении окна диалога. Рисунок 9.33. Компонент Edit используется для ввода текстового сообщения будильника Шаг 16. Изменение текста во время работы программы приводит к возникновению в компоненте Edit события OnChange. Обрабатывая это событие, можно, например, устроить работу окна диалога таким образом, что кнопка OK будет недоступна, если в редакторе нет текста. Чтобы реализовать такое поведение нашего диалога, определите для компонента MessageEdit следующий обработчик события OnChange: procedure TAlarmDetailsForm.MessageEditChange(Sender: TObject); begin OkButton.Enabled := Length(MessageEdit.Text) <> 0; end; Выполните компиляцию программы и проверьте ее работу. Прежде чем продолжить обсуждение примера Alarms, сделаем несколько замечаний по поводу редактирования многострочного текста. Редактор многострочного текста представлен компонентом Memo (рисунок 9.34). Рисунок 9.34. Компонент Memo Характерные свойства компонента Memo описаны в таблице 9.10.
Таблица 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.
Таблица 9.11. Важнейшие свойства компонента ComboBox Раскрывающийся список умеет отображать себя по-разному в зависимости от значения свойства Style (см. таблицу 9.12).
Таблица 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.
Таблица 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); // Раскодировать текущее время будильника DecodeTime(DateTime, Hour2, Min2, Sec2, MSec2); // Проверить, что текущее время совпадает с временем будильника case Recurring of 0: // для ежедневной периодичности Match := (Hour1 = Hour2) and (Min1 = Min2); 1..7: // для еженедельной периодичности Match := (Hour1 = Hour2) and (Min1 = Min2) and (Recurring = DayOfWeek(Date)); 8: // для конкретной даты Match := (Hour1 = Hour2) and (Min1 = Min2) and (Int(DateTime) = Date); else Match := False; end; // Решить вопрос о выдаче сигнала будильником if Match then begin if not Handled then // сигнал! begin Handled := True; // предотвратить повторные срабатывания if PlaySound then Beep; MessageDlg(GetAlarmStr, mtWarning, [mbOk], 0); end; end else Handled := False; // обеспечить будущие срабатывания end; Для правильной работы будильника метод CheckTime должен вызываться не реже одного раза в минуту. Чем чаще вызывается метод, тем меньше инерционность будильника, но тем больше пустых опросов, а значит выше загруженность операционной системы. Компромиссная частота — два раза в секунду. Так как в одну и ту же минуту метод CheckTime будет вызван несколько раз, то для избежания повторных срабатываний используется флаг Handled. Будильник выдает сообщение только в том случае, если текущее время совпадает с временем, на которое будильник установлен и при условии, что в данную минуту он еще не звенел. Шаг 24. Давайте теперь позаботимся о передаче данных в окно диалога перед его запуском и о приеме данных после завершения. Удобнее всего, чтобы за это отвечало само окно диалога, т.е. форма AlarmDetailsForm. С этой целью определите в классе TAlarmDetilasForm два метода — GetData и SetData. Методы следует поместить в секцию public: type TAlarmDetailsForm = class(TForm) ... public procedure GetData(Alarm: TAlarm); procedure SetData(Alarm: TAlarm); end; В разделе implementation наберите программный текст методов: procedure TAlarmDetailsForm.GetData(Alarm: TAlarm); begin with Alarm do begin // Получить из диалога текст сообщения будильника MsgText := MessageEdit.Text; // Получить из диалога время срабатывания будильника DateTime := StrToTime(TimeMaskEdit.Text); // Получить из диалога состояние переключателя звука PlaySound := SoundCheckBox.Checked; // Получить из диалога периодичность срабатывания будильника if EverydayRadioButton.Checked then Recurring := 0 else if WeeklyRadioButton.Checked then Recurring := WeeklyComboBox.ItemIndex + 1 else { DateRadioButton.Checked } begin Recurring := 8; DateTime := DatePicker.Date + DateTime; end; end; end; procedure TAlarmDetailsForm.SetData(Alarm: TAlarm); begin with Alarm do begin // Установить в окне диалога текст сообщения будильника MessageEdit.Text := MsgText; // Установить в окне диалога время будильника TimeMaskEdit.Text := FormatDateTime('hh:mm', DateTime); // Установить в окне диалога состояние переключателя звука SoundCheckBox.Checked := PlaySound; // Установить в окне диалога периодичность будильника case Recurring of 0: // ежедневно EverydayRadioButton.Checked := True; 1..7: // еженедельно begin WeeklyRadioButton.Checked := True; WeeklyComboBox.ItemIndex := Recurring - 1; end; 8: // в конкретный день begin DateRadioButton.Checked := True; DatePicker.Date := Int(DateTime); end; end; end; end; Метод GetData просто заполняет поля переданного в параметре объекта Alarm значениями, которые установлены в компонентах окна диалога. Метод SetData выполняет обратные действия, заполняя компоненты окна диалога значениями, которые содержатся в полях объекта Alarm. На этом с разработкой модуля AlarmDetails покончено и окно диалога Alarm Details полностью готово к использованию. Дальше необходимо обеспечить формирование, редактирование и визуализацию списка будильников. Эта задача решается с помощью компонента ListBox. 9.3.10. Список Компонент ListBox отображает список элементов, которые пользователь может просматривать и выбирать, но не может непосредственно модифицировать. По умолчанию элементами списка являются строки, но могут быть и графические объекты. Элементы могут располагаться в одну или несколько колонок и автоматически сортироваться. При необходимости обеспечивается возможность прокрутки списка. Компонент ListBox находится в палитре компонентов на вкладке Standard (рисунок 9.44). Рисунок 9.44. Компонент ListBox Его характерные свойства собраны в таблице 9.14.
Таблица 9.14. Важнейшие свойства и события компонента ListBox Особенности хранения и отображения элементов списка определяются свойством Style, возможные значения которого описаны в таблице 9.15.
Таблица 9.15. Значения свойства Style компонента ListBox Шаг 25. Давайте воспользуемся компонентом ListBox для организации списка будильников. Активизируйте форму MainForm, а затем опустите на нее компонент ListBox. Переименуйте компонент в AlarmListBox и скорректируйте его местоположение и размеры. Затем установите свойство TabOrder в значение 0, чтобы при отображении формы список первым получил фокус ввода (рисунок 9.45). Рисунок 9.45. Компонент ListBox применяется для организации списка будильников Решим теперь вопрос хранения будильников в компоненте AlarmListBox. Для хранения элементов служит свойство Items. Свойство Items — это объект класса TStrings, в нем свойство-массив Strings хранит отображаемые строки, а свойство-массив Objects — ассоциированные со строками объекты. В нашем примере массив Strings будет хранить выдаваемые по сигналу сообщения, а массив Objects — соответствующие им объекты класса TAlarm. Теоретически все понятно, осталось реализовать все это практически. Создание, редактирование и удаление будильника осуществляется по щелчкам на кнопках NewButton, EditButton и DeleteButton соответственно. Поэтому в них требуется создать обработчики события OnClick. Шаг 26. В кнопке New... обработчик события OnClick уже существует, но его необходимо доработать: procedure TMainForm.NewButtonClick(Sender: TObject); var Alarm: TAlarm; begin AlarmDetailsForm := TAlarmDetailsForm.Create(Self); try // Выполнить диалог if AlarmDetailsForm.ShowModal = mrOK then begin // Создать новый объект будильника Alarm := TAlarm.Create; // Получить параметры будильника из диалога AlarmDetailsForm.GetData(Alarm); // Добавить будильник в список и выбрать его AlarmListBox.ItemIndex := AlarmListBox.Items.AddObject( Alarm.GetAlarmStr, Alarm); end; finally AlarmDetailsForm.Free; end; end; Метод NewButtonClick создает окно диалога Alarm Details и выполняет его в монопольном режиме. Если диалог завершается щелчком кнопки OK, создается новый объект будильника и в него переносятся данные из окна диалога. Затем этот объект добавляется в список AlarmList и его номер присваивается свойству списка ItemIndex. В результате новый элемент становится выделенным. Вы, разумеется, хотите проверить работу новоиспеченного метода. Сейчас мы так и сделаем, но прежде нужно решить небольшой вопрос. Дело в том, что при уничтожении блока списка освобождаются только строки, но не освобождаются ассоциированные с ними объекты. Хотя память объектов так или иначе освобождается при завершении приложения, мы рекомендуем всегда освобождать память явно. Это считается "хорошим тоном" программирования и иногда позволяет выявить скрытые ошибки. Освобождение использованных в форме динамических данных осуществляется в обработчике события OnDestroy. Для формы MainForm он должен быть таким: procedure TMainForm.FormDestroy(Sender: TObject); var I: Integer; begin for I := 0 to AlarmListBox.Items.Count - 1 do AlarmListBox.Items.Objects[I].Free; end; После того как вы написали этот обработчик, выполните компиляцию программы и запустите ее. Попытайтесь добавить в список несколько будильников. Если это у вас получилось, перейдем к следующему шагу — программированию реакции на нажатия кнопок Edit... и Delete. Шаг 27. Создайте в компоненте EditButton обработчик события OnClick: procedure TMainForm.EditButtonClick(Sender: TObject); var Alarm: TAlarm; SavedIndex: Integer; begin AlarmDetailsForm := TAlarmDetailsForm.Create(Self); try // Получить выбранный будильник with AlarmListBox do Alarm := TAlarm(Items.Objects[ItemIndex]); // Установить управляющие элементы диалога в соответствии с // параметрами будильника AlarmDetailsForm.SetData(Alarm); // Выполнить диалог if AlarmDetailsForm.ShowModal = mrOK then begin // Получить из диалога новые параметры будильника AlarmDetailsForm.GetData(Alarm); with AlarmListBox do begin // Запомнить номер выбранного в списке элемента SavedIndex := ItemIndex; // Изменить текст элемента // При этом элемент перестает быть выбранным Items.Strings[ItemIndex] := Alarm.GetAlarmStr; // Восстановить номер выбранного в списке элемента ItemIndex := SavedIndex; end; end; finally AlarmDetailsForm.Free; end; end; Этот метод создает окно диалога Alarm Details, инициализирует его компоненты данными из выбранного в списке объекта будильника, а затем выполняет диалог в монопольном режиме. Если диалог завершился щелчком на кнопке OK, то данные из окна диалога переносятся обратно в объект будильника и соответственно изменяется отображаемая в блоке списка строка. Так как в результате последнего действия в списке пропадает полоса выбора (свойство ItemIndex получает значение -1), номер выделенного элемента предварительно сохраняется в локальной переменной SavedIndex, а затем восстанавливается. Шаг 28. Осталось создать обработчик события OnClick в компоненте DeleteButton: procedure TMainForm.DeleteButtonClick(Sender: TObject); begin with AlarmListBox do begin // Разрушить объект будильника Items.Objects[ItemIndex].Free; // Удалить из списка соответствующую объекту строку Items.Delete(ItemIndex); end; end; Метод DeleteButtonClick удаляет объект будильника и соответствующую ему строку в списке. Обработчики событий для всех кнопок заданы, однако не спешите запускать приложение. Необходимо позаботиться о том, чтобы кнопки Edit... и Delete были доступны или недоступны в зависимости от того, выделен в списке элемент или нет. Как бы это сделать попроще? Первое решение, которое напрашивается — это вставить необходимые проверки в обработчики событий кнопок. Это неплохое решение, но оно больше подходит тем, кто привык решать задачу в лоб. Мы пойдем другим путем, воспользовавшись событием OnIdle объекта Application. В объекте Application происходит событие OnIdle в период простоя программы, например во время ожидания пользовательского ввода. Благодаря этому событию программа может выполнять некоторую фоновую работу, которая в нашем случае заключается в управлении состоянием кнопок. Для создания обработчика события OnIdle объекта Application воспользуемся уже знакомым вам компонентом ApplicationEvents (см. главу 8). Шаг 29. Поместите в форму компонент ApplicationEvents, дайте ему одноименный идентификатор и создайте обработчик события OnIdle: procedure TMainForm.ApplicationEventsIdle(Sender: TObject; var Done: Boolean); begin EditButton.Enabled := AlarmListBox.ItemIndex <> -1; DeleteButton.Enabled := AlarmListBox.ItemIndex <> -1; Done := True; // предотвращает непрерывную генерацию события OnIdle end; В передаваемом по ссылке параметре Done метод возвращает результат своей работы. Значение True показывает, что метод нужно вызывать не постоянно в течении простоя приложения, а только по одному разу в начале каждого периода простоя. А сейчас выполните компиляцию, запустите программу и тщательно протестируйте работу главной формы (рисунок 9.46). Рисунок 9.46. В этом окне создается список будильников Будильники можно создавать, добавлять, удалять. Нам осталось сделать последний шаг — заставить будильники "звонить". Для этого нужно периодически вызывать метод CheckTime у каждого помещенного в список объекта TAlarm. Периодические по времени действия выполняются с помощью таймера, о котором мы дальше и поговорим. 9.4. Законченное приложение для выдачи сигналов в заданные моменты времени 9.4.1. Таймер Таймер — это системный генератор событий, который периодически сообщает программе о завершении заданного промежутка времени. Интервал времени между событиями таймера может устанавливаться в диапазоне от 1 до 65535 миллисекунд. Используя таймер, учитывайте, что интервалы между этими событиями оказываются неточными из-за накладных расходов механизма обработки событий Windows. В библиотеке VCL прием событий таймера обеспечивает компонент Timer. Он расположен в палитре компонентов на вкладке System (рисунок 9.47). Им мы и воспользуемся для "оживления" будильников в приложении Alarms. Рисунок 9.47. Компонент Timer Шаг 30. Активизируйте форму MainForm. Затем поместите в нее компонент Timer (рисунок 9.48). Если хотите, дайте ему любое имя. Рисунок 9.48. Компонент Timer — на форме Шаг 31. Интервал времени между событиями таймера задается в миллисекундах как значение свойства Interval. Изначально интервал равен 1000 миллисекунд (1 секунда). Частота контроля будильников должна быть два раза в секунду, поэтому установите свойство Interval в значение 500. Шаг 32. Через заданные в свойстве Interval промежутки времени в компоненте Timer происходит событие OnTimer (единственное событие этого компонента). Для контроля за будильниками нам нужно создать обработчик этого события: procedure TMainForm.TimerTimer(Sender: TObject); var I: Integer; begin for I := 0 to AlarmListBox.Items.Count - 1 do with AlarmListBox.Items.Objects[I] as TAlarm do CheckTime; end; Смысл выполняемых действий очевиден: у каждого объекта в списке будильников вызывается метод CheckTime. Таким образом, каждый будильник периодически проверяет свое время и, если нужно, выдает предупреждение (рисунок 9.49). Рисунок 9.49. Когда будильник срабатывает, звучит сигнал и на экран выдается сообщение Выполните компиляцию и запустите программу, чтобы проверить работу всех элементов программы. Ура! Все работает, терпение и упорство вознаграждены. 9.4.2. Файлы настроек Программа Alarms имеет один существенный недостаток: после его завершения все установленные будильники теряются, так что при следующем запуске программы их приходится создавать снова. Для решения этой проблемы необходимо, чтобы между сеансами работы программы будильники хранились в конфигурационном файле на диске. Сохранение и восстановление конфигурации осуществляется в Windows с помощью так называемых файлов настроек. Файл настроек (initialization file) — это текстовый файл, состоящий из секций. Секция начинается с имени, заключенного в квадратные скобки. В каждой секции содержатся определения некоторых связанных по смыслу параметров, представленные в виде пар Имя=Значение. Примером файла настроек может служить файл настроек проекта в системе Delphi. В нашем проекте это файл Alarms.dof. Структуру файла настроек для программы Alarms выберем так, чтобы каждому будильнику соответствовала отдельная секция. Число секций, т.е. будильников, будем хранить в параметре AlarmCount секции Global Options. Вот как могло бы выглядеть содержимое файла: [Global Options] AlarmCount=3 [Alarm1] Message=Dinner ! Time=13:00 PlaySound=1 Recurring=0 [Alarm2] Message=Tennis training Time=16:00 PlaySound=1 Recurring=1 [Alarm3] Message=My favourite TV-show... Time=22:30 PlaySound=0 Recurring=8 Date=02/25/96 Чтение и запись файла настроек осуществляется с помощью объектов TIniFile (заметьте, они не являются компонентами). Класс TIniFile описан в модуле IniFiles. Этот модуль необходимо самостоятельно добавить в вызывающий модуль с помощью оператора uses. При создании объекта TIniFile ему в конструктор передается имя INI-файла. Позже это имя можно узнать, обратившись к свойству FileName. Если в имени файла маршрут не был указан, считается что INI-файл находится в каталоге системы Windows. Чтение переменных из INI-файла выполняется с помощью описанных ниже методов. В этих методах название секции передается в параметре Section, имя переменной – в параметре Ident, а значение по умолчанию – в параметре Default. |