Лабораторная работа № 8 Записная книжка 2


Работа с диалоговыми окнами

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

Создайте новый проект на Delphi, добавьте на форму компонент MainMenu, в редакторе меню добавьте пункт меню Tools и подпункт для него Options. Для меню Options создайте обработчик. Для добавления еще одного окна в программу нажмите на кнопку New Form на панели инструментов View (четвертая кнопка слева):

Появится форма с именем Form2 по умолчанию.

Теперь добавьте в новую форму edit и две кнопки и задайте для кнопок надписи OK и Cancel. В обработчики для этих кнопок добавьте следующий код:

procedure TForm2.Button1Click(Sender: TObject);

begin

  Close;

  ModalResult:=mrOK;

end;

procedure TForm2.Button2Click(Sender: TObject);

begin

  Close;

  ModalResult:=mrCancel;

end;

Код тут достаточно прозрачен - Close закрывает форму, а в ModalResult записывается результат (mrOK для кнопки OK и mrCancel для кнопки Cancel).

Теперь возвращаемся к коду основной формы.

Пишем для обработчика нашего меню следующий код:

procedure TForm1.Options1Click(Sender: TObject);

var

  res : TModalResult;

begin

  res := Form2.ShowModal;

  if res=mrOK then //Если нажата кнопка OK

НЕ нашли? Не то? Что вы ищете?

  Form1.Caption:=Form2.Edit1.Text;

end;

Смысл этого кода следующий: переменная res служит для сохранения результата выполнения второго диалога (т. е. нажал ли пользователь OK или Cancel). И если пользователь нажал OK, то введенную пользователем строку мы показываем в заголовке нашего основного окна.

Теперь остается еще одна проблема. Дело в том, что мы в нашем основном окне (Form1) используем Form2. Но Form2 пока не видна. Для исправления этого добавьте в код Form1 ссылку на Form2:

...

implementation

uses

  Unit2;

Все! Теперь можно запускать программу и передавать данные из второго диалогового окна в заголовок первого

Диалог с вкладками (компонент PageControl)

Для диалога со вкладками используется компонент PageControl со вкладки Win32:

Поместите его на форму. Для добавления вкладок на наш компонент просто щелкните на нем правой кнопкой мыши, из контекстного меню выберите New Page. Таким способом можно добавить требуемое число вкладок. Удаляются они аналогично - из контекстного меню нужной вкладки выбираем Delete Page (для того, чтобы выделить нужную вкладку, просто щелкните на ней (но не на ее ярлычке - в этом случае выделится весь PageControl)).

После того, как вы добавите пару-тройку вкладок, они появятся в окне Object TreeView, так что для задания свойств конкретной вкладки просто щелкните на соответствующей строке в окне Object TreeView:

Теперь можно размещать на вкладках разные элементы управления (как и на обычной форме). Добираться до размещенных элементов управления можно, например, так:

procedure TForm1.Button1Click(Sender: TObject);

begin

  CheckBox1.Enabled:=false;

end;

Обратите внимание, что несмотря на то, что наш checkbox расположен на вкладке (и если вы попытаетесь перетащить его мышкой за ее пределы, то у вас ничего не получится), добраться до него мы можем через форму (в данном примере по нажатии на кнопку). Если вы расположите на второй вкладке другой checkbox, то он получит имя CheckBox2, а не CheckBox1.

Посмотрим теперь, как могут располагаться вкладки если их слишком много, чтобы умещаться в один ряд. Если свойство MultiLine для нашего компонента PageControl установлено в true, то они распологаются в несколько рядов:

А если MultiLine установлено в false (по умолчанию), то в один ряд, причем справа появляются две кнопки для перемещения (совсем как в палитре компонент Delphi):

Свойство TabIndex определяет активную в данный момент вкладку (нумерация с нуля). Это свойство доступно только для чтения.

Из полезных свойств отметим также TabPosition. Возможные значения для него - tpTop, tpBottom, tpLeft, tpRight. При этих значениях ярлыки ко вкладкам располагаются наверху, внизу, слева и справа соответственно). По умолчанию это свойство равно tpTop.

Для получения количества вкладок служит свойство PageCount объекта PageControl. Оно, естественно, доступно только для чтения.

Из модных нововведений интерфейса отметим также свойство HotTrack. Если его установить в true, то при наведении мышки заголовок вкладки будет подсвечиваться.

Вкладки можно добавлять во время выполнения программы. Вот пример такого кода (у нас он выполняется при нажатии кнопки):

procedure TForm1.Button1Click(Sender: TObject);

var

  tab : TTabSheet; //Заводим новую вкладку

begin

  tab:=TTabSheet. Create(Form1); //Задаем родителя

  tab. PageControl:=PageControl1;

  tab. Caption:='New'; //Задаем заголовок

end;

При щелчке на кнопке Button1 на нашей форме появится новая вкладка с заголовком new

Строка состояния

Компонент StatusBar расположен на вкладке Win32 палитры компонентов:

На строке состояния может располагаться одна или несколько панелей. За это отвечает свойство SimplePanel. Если оно установлено в true, то панель - одна, если в false - то несколько. В первом случае за текст в строке состояния отвечает свойство SimpleText. Оно доступно и на этапе разработки, и на этапе выполнения. Если же панелей несколько (SimplePanel равно false), то до их свойств можно добраться через свойство Panels. Для добавления панелей к строке состояния просто щелкните на многоточии рядом со свойством Panels в Инспекторе объектов (или просто сделайте двойной щелчок на самой строке состояния на форме):

После добавления панелей можно редактировать их свойства. Основное свойство для них - это text. Естественно, что оно задает текст в сответствующей панели. Это свойство доступно для чтения и записи (в том числе и во время работы программы). Вот так, например, можно задать некотрую надпись в первой панели строки состояния:

...

  StatusBar1.Panels[0].Text:='сохранение';

  ...

Обратите внимание, что нумерация панелей идет с нуля.

Количество панелей в строке состояния возвращает следующее выражение:

  ...

  StatusBar1.Panels. Count

  ...

Вот так, например, можно обнулить строки во всех панелях строки состояния:

...

for i:=0 to StatusBar1.Panels. Count-1 do

  StatusBar1.Panels[i].test:='';

  ...

Работаем с таймером

Таймер - это компонент, имеющий только одно одноименное событие. Это событие таймер генерирует через определенные промежутки времени. С технической же точки зрения таймер просто посылает окну сообщение WM_TIMER. Этот компонент расположен на вкладке System Палитры компонентов:

Перенесите его на форму. Основое свойство для таймера - это Interval. Оно определяет (в миллисекундах), как часто наш компонент будет генерировать событие Timer. Например, если мы установим его значение в 1000, то событие Timer будет генерироваться раз в секунду, а если установим в 500 - то 2 раза в секунду. Если же это свойство установить в 0, то наше событие вообще генерироваться не будет.

Для примера рассмотрим, как наша программа раз в секунду может издавать звуковой сигнал. Для этого установите Interval в 1000, затем в заготовке для события таймера (для ее получения перейдите на вкладку Events Инспектора объектов и сделайте двойной щелчок в строке OnTimer) внесите следующий код:

procedure TForm1.Timer1Timer(Sender: TObject);

begin

  MessageBeep(0); //Звуковой сигнал

end;

Запускайте программу. Раз в секунду будет раздаваться стандартный звуковой сигнал.

А вот как можно заставить таймер выполнить некоторое действие однократно:

procedure TForm1.Timer1Timer(Sender: TObject);

begin

  Timer1.Interval:=0; //Отключаем таймер

  ... //Некоторое действие

end;

Разумеется, в этом случае необходимо установить для свойства Interval таймера некоторое первоначальное значение.


Компонент StringGrid

Компонент StringGrid предназначен для отображения и хранения текстовой информации в виде таблицы. Расположен он на вкладке Additional Палитры компонентов:

Размер таблицы определяется свойствами ColCount и RowCount. Они задат количество столбцов и строк соответственно. При необходимости эти свойства можно менять и программно. Размеры же ячеек в пикселах задают свойства DefaultColWidth и DefaultRowHeight. Если же надо задать размер некоторого столбца или некоторой строки отдельно, то надо воспользоваться свойствами ColWidths или RowHeights соответственно. Вот пример, в котором мы задаем для первого столбца ширину в 40 пикселов:

StringGrid1.ColWidths[0]:=40;

Как видно, нумерация идет с нуля.

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

Для того, чтобы получить доступ к некоторой ячейке, надо использовать свойство Cells. Вот пример, в котором мы записываем во сторую строчку второго столбца значение abcd:

StringGrid1.Cells[1,1]:='abcd';

При необходимости можно работать и со строками или столбцами целиком. Для работы со строками надо использовать свойство Rows, а со столбцами - Cols. Скажем, вот так можно целиком скопировать вторую строки в третью (помните, что нумерация идет с нуля):

StringGrid1.Rows[2]:=StringGrid1.Rows[1];

Например, это может понадобиться при удалении некоторой строки из таблицы - в этом случае следующие за ней строки должны "подняться" наверх на один ряд каждая.

Множество важных параметров компонента StringGrid являются подсвойствами свойства Options:

Вот некоторые из них. Подсвойство goEditing отвечает за возможность редактирования ячеек таблицы. Если это свойство установить в true, то редактирование возможно (путем двойного щелчка на нужной ячейке). Подсвойство goRowSelect. Если оно установлено в true, то при щелчке на ячейке выделяеся весь ряд. Установленное в true подсвойство goTabs позволяет перемещаться между ячейками посредством клавиши TAB. Если вы хотите позволить пользователю изменять размеры столбцов путем перетаскивания границ у заголовков, то установите значение подсвойства goColSizing в true.

Одна из частых задач - это получение информации, в какую из ячеек пользователь внес изменения. Для определения этого надо воспользоваться обработчиком события OnSetEditText для StringGrid:

procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol,

  ARow: Integer; const Value: String);

begin

  Form1.Caption:=IntToStr(ACol) + ' ' + IntToStr(ARow);

end;

Как видно, номера строки и столбца измененной ячейки передаются в параметрах ACol и ARow.

Задание

Создать приложение – электронную записную книжку.

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

Основная форма приложения должна содержать PageControl c единственной вкладкой “Все записи”, на которой расположен компонент StringGrid. Вся информация (фамилия, имя, адрес, телефон) хранится в  StringGrid.

Кроме этого на форме должны располагаться кнопки “Добавить запись” и “В алфавитном порядке”.

При нажатии на кнопку “Добавить запись” открывается еще одно диалоговое окно, на котором расположены поля для ввода информации.

При нажатии на кнопку “В алфавитном порядке” компоненту PageControl динамически добавляются 4 вкладки: “А-Ж”, “З-O”, “П-Ц”, ”Ч-Я” каждая из которых содержит  StringGrid с записями о людях, первые буквы фамилий которых попадают в данный диапазоне. Причем, если в записной книжке нет записей о людях, чья фамилия начинается, например, с букв Ч-Я, соответствующая вкладка не создается.