Implementation. ТrackBar устанавливает интервал для таймера, задавая тем самым скорость визуализации
usesControlUnit;
{&r *.DFM}
ТrackBar устанавливает интервал для таймера, задавая тем самым скорость визуализации. А кнопка редактирования переключает режим редактирования, останавливая и включая таймер.
procedureTLifeForm.FillBtnClick(Sender: TObject);
begin
RandomCells;
DrawCells;
end;
procedure TLifeForm.SpeedTrkBarChange(Sender: TObject); {Меняет скорость «жизни»}
begin
MainForm.LifeTimer.Interval := SpeedTrkBar.Position;
end;
procedure TLifeForm.EditSpBtnClick(Sender: TObject);{включает/выключает режим редактирования}
begin
MainForm.LifeTimer.Enabled := not EditSpBtn.Down;
end;
Само редактирование клеток происходит в главном модуле, в обработчике OnMouseDown компонента LifeImg.
procedure TMainForm.LifeImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if LifeForm.EditSpBtn.Downthen
A[X div 10, Y div 10] := not A[X div 10, Y div 10];
DrawCells;
end;
В uses нужно описать ссылку на LifeUnit.
При запуске программы получается примерно такая картинка.
|
Теперь можно редактировать позиции.
16. Вначале при загрузке и сохранении картинок и прочих файлов использовались специальные методы объектов, в которые происходила загрузка. Теперь произведем эти операции вручную, пользуясь процедурами работы с типизированными файлами.
Типизированные файлы содержат записи определенного типа. К примеру, file of integer может хранить произвольное количество переменных integer; file of TLifeCells – произвольное количество переменных типа TLifeCells. Однако для наших целей достаточно только одной записи. При работе с типизированными файлами используются следующие процедуры.
AssignFile(var F; FileName: string) – связывает файловую переменную F с текстовым именем файла. Это действие необходимо сделать перед всеми последующими операциями.
Reset(F) – открывает существующий файл, связанный с переменной F, и устанавливает позицию чтения-записи в начало.
Rewrite(F) – создает файл, соответствующий файловой переменной F.
Read(F, V) – читает из файла, связанного с F, данные в типизированную переменную V. Позиция файла увеличивается на один файловый компонент, байтовый размер которого равен размеру типа переменной (для integer это 4 байта).
Write(F, V) – записывает в файл, связанный с F, типизированную переменную V. Позиция файла увеличивается на один файловый компонент.
Seek(F, N: LongInt) – перемещает позицию файла к номеру N, начальная позиция при N = 0.
CloseFile(var F) – закрывает файл F.
В главном модуле описан тип TFileCells:
{Private declaration}
Public
{Public declaration}
End;
Const
XSize = 40;
YSize = 25;
Type
TFileCells = array [0 .. XSize – 1, 0 .. YSize – 1] of boolean;
Var
MainForm: TMainForm;
A: TFileCells;
В обработчике OnClick кнопки LifeOpen определяем файл такого же типа. Если файл выбран в диалоге, ассоциируем имя файла с переменной, устанавливаем позицию для чтения в начало и считываем из файла данные в переменную A, описанную в MainUnit и хранящую положения клеток.
procedure TLifeForm.LifeOpenBtnClick(Sender: TObject);
var
F: file of TLifeCells;
begin
if LifeOpenDlg.Execute then
if FileExists(LifeOpenDlg.FileName)then
begin
AssignFile(F, LifeOpenDlg.FileName);
Reset(F);
Read(F, A);
CloseFile(F);
DrawCells;
end;
end;
Подобное чтение корректно, поскольку типы файла и переменной A совпадают.
При записи в файл ситуация похожая, только вдобавок проводится проверка, существует ли файл. Если нет, то он создается; если да, то должны спросить, действительно ли пользователь хочет его перезаписать. Если он просто ошибся, то закрываем файл и выходим из обработчика; если нужно переписать, открываем его и устанавливаем позицию записи в начало. Затем производится запись переменной и закрытие файла.
procedure TLifeForm.LifeSaveBtnClick(Sender: TObject);
var
F:file of TLifeCells;
begin
if LifeSaveDlg.Execute then
begin
AssignFile(F, LifeSaveDlg.FileName);
if not FileExists(LifeSaveDlg.FileName) then
Rewrite(F)
else if MessageDlg('Перезаписать?', mtWarning, [mbYes, mbNo], 0) = mrYes then
Reset(F)
else begin
CloseFile(F);
exit;
end;
Write(F, A);
CloseFile(F);
end;
end;
Работа с нетипизированными файлами похожа на работу с типизированными. Отличия в том, что объявляются такие файлы просто var F: file; (без of …), при открытии – Reset(F, 1) – нужно указать размер блока записи (который по умолчанию равен 128), чтение и запись происходят с помощью процедур BlockRead, BlockWirite(var F: File; var Buf; Count: Integer), где Buf – переменная, в которую (или из которой) идет запись, Count – число блоков записи (размер блока был определен в Reset). Если надо писать произвольные данные (к примеру, a: integer; b: boolean; c: TLifeCells; d: string[20]), сделайте следующее.
При записи:
Rewrite(F, 1);
BlockWrite(F, a, SizeOf(a));
BlockWrite(F, b, SizeOf(b));
BlockWrite(F, c, SizeOf(c));
BlockWrite(F, d, SizeOf(d));
CloseFile(F);
При чтении, соответственно:
Reset(F, 1);
BlockRead(F, a, SizeOf(a));
BlockRead(F, b, SizeOf(b));
BlockRead(F, c, SizeOf(c));
BlockRead(F, d, SizeOf(d));
CloseFile(F);
17. Чтобы решить проблему цвета, необходимо сделать специальное собственное диалоговое окно, позволяющее выбрать цвет. Раньше мы вызывали стандартные диалоги.
Диалог – это обычная форма, которая, однако, вызывается специальным методом ShowModal и возвращает модальный результат. Модальный вызов приводит к тому, что при выведенном диалоге нельзя переключиться ни к одной другой форме приложения, пока не будет нажата одна из модальных кнопок диалога, после чего диалог закроется и управление вернется в приложение. Модальным кнопкам даже не надо описывать обработчики. Просто надо установить свойство ModalResult не равным mrNone.
Создайте новую форму, сохраните модуль как ColorUnit. Добавьте на нее две фигуры Shape (CellShape: TShape, FieldShape: TShape), кнопку «Утвердить» (ModalResult = mrOk), кнопку «Отмена» (ModalResult = mrCancel).
|
Настройте форму. В частности, задайте ее позицию и определите модальный результат для кнопок.
ColorForm: TColorForm
BorderStyle = bsToolWindoiw
Caption = выберите цвета
Position = poScreenCenter
В обработчике нажатия на фигуры Shape опишите вызов диалогов. Обработчики для кнопок можете не описывать.
В модуле ColorUnit – обработчики нажатия на FieldShape и CellShape:
procedure TColorForm.FieldShapeMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
MainForm.FieldColorDlg.Execute;
FieldShape.Brush.Color := MainForm.FieldColorDlg.Color;
end;
procedure TColorForm.CellShapeMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
MainForm.CellColorDlg.Execute;
CellShape.Brush.Color := MainForm.CellColorDlg.Color;
end;
В обработчике кнопки "задать цвета" на форме визуализации опишите модальный вызов этого нового диалога.
В модуле LifeUnit описываем обработчик SetColorBtn:
procedure TLifeForm.ColorBtnClick(Sender: TObject);
var
C1, C2: TColor;
begin
C1 := MainForm.FieldColorDlg.Color;
C2 := MainForm.CellColorDlg.Color;
ColorForm.FieldShape.Brush.Color := C1;
ColorForm.CellShape.Brush.Color := C2;
if ColorForm.ShowModal = mrCancelthen
begin
MainForm.FieldColorDlg.Color := C1;
MainForm.CellColorDlg.Color := C2;
end;
end;
В данном случае вызывается форма ColorForm – диалог установки цвета. Если в нем нажата кнопка "Отмена", то значения цветов восстанавливаются. Они специально для этого перед вызовом сохраняются в C1 и C2.
18. Пользователь проигрывателя может случайно закрыть окно формы управления. Следователь, придется перезапускать программу.
Можно решить эту проблему следующим образом. При попытке закрытия спросить пользователя, хочет ли он совсем выйти из программы. И если хочет – закрыть главную форму.
procedure TControlForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if MessageDlg('Выйти из программы?', mtWarning,
[mbYes, mbNo], 0) = mrYes then MainForm.Close
else CanClose := false;
end;
Этой конструкцией закрывается главная форма из формы управления. То же событие можно обработать и в главной форме, каждый раз спрашивая о желании выйти.
Запустите программу.
|
19. Подведем итоги. Для создания многооконности необходимо:
- Создать очередную форму.
- Модули, предназначенные пользователю, поместить в interface, а модули, предназначенные программистуто, поместить в uses.
- Необходимо помнить о круговых ссылкахи и избегать ignotum per ignotius. В интерфейс поместить только необходимое.
- В OnCreate делать описание, не забывая о порядке создания форм в файле проекта.
- Программа заканчивается, когда закрывается главная форма. Остальные формы приложения могут закрываться сколько угодно.
- Диалоги: вызов ShowModal, результат – ModalResult нажатой кнопки.
- Выбрать нужную форму или модуль для редактирования можно с помощью кнопок панели инструментов или клавишами Ctrl-F12 и Shift-F12. Переключение модуль-форма – просто клавишей F12.
ПРИЛОЖЕНИЕ 1
Дата добавления: 2014-12-02; просмотров: 758;