- •Windows -приложение
- •Среда программирования
- •Встроенный отладчик
- •Использование графики
- •Графические данные и палитра
- •Сохранение проекта
- •Структура приложения
- •Структура модуля
- •Простые типы
- •Символьные типы
- •Логические типы
- •Тип перечень
- •Составной оператор
- •Оператор if
- •Оператор цикла for
- •Оператор цикла while
- •Оператор цикла repeat
- •Пример приложения 6
- •Пример приложения 7
- •Статические массивы
- •Динамические массивы
- •Оператор with
- •Идентичность типов
- •Совместимость типов
- •Преобразование типов
- •Операторы обработки исключительных ситуаций
- •Рекурсия
- •Процедура exit
- •Директивы подпрограммы
- •Класс как объектный тип
- •Наследование
- •Операции is и as
- •Типы ссылки на класс
- •Типизированные файлы
- •Файлы без типа
- •Пример приложения 17
- •Компонент tmainmenii
- •Двунаправленные списки
- •Потоки данных
- •Пример приложения 22
- •Интерфейс drag and drop
- •Пример приложения 24
- •С файлами
- •Пример приложения 26
- •Программные потоки
- •Приоритеты потоков
- •Класс tthread
- •Проблемы синхронизации потоков
Потоки данных
Потоки - достаточно мощное средство при реализации операций ввода или вывода данных, располагающихся на различных носителях. Потоки представляют собой специальные объекты, которые строятся с помощью наследников абстрактного класса TStream. Этот класс содержит методы, в которых заложены операции чтения, записи, изменения текущего положения указателя данных, открытия и закрытия потока. Поскольку для разных носи-
170
телей реализация указанных выше операций зависит от конкретной реализации устройства, построено несколько специальных классов. Наиболее часто используются потоки TFileStream, THandleStream для работы с файлами на диске и TMemoryStream для работы с памятью. TFileStream используется, когда необходимо работать с именем файла, THandleStream используется, например, с файлами Windows, когда определяется дескриптор файла.
Любая работа с файловым потоком начинается с его построения. При этом используется стандартный конструктор Create(const Filename:string; Mode:Word). Параметр Filename задает имя файла, а параметр Mode - режимы создания (fmCreate), чтения (fmOpenRead), записи (fmOpenWrite) или одновременного чтения и записи (fmOpenReadWrite) файла. С помощью операции логического или (or) к указанному параметру можно добавить режим совместного использования, например fmShareExclusive - файл недоступен для открытия другими приложениями. При этом поток работает с файлом без учета типа хранящихся в нем данных.
Для чтения и записи данных при работе с потоком используются методы Read и Write, содержащие по два параметра: переменная, куда считываются байты и количество байтов.
ПРИМЕР ПРИЛОЖЕНИЯ 21
Пусть заданы некоторые совокупности целых чисел. Требуется построить, используя эти данные, диаграммы (или графики). Данные берутся из файлов. С помощью, например, StringGrid можно вводить новые данные или корректировать значения точек и записывать в файлы. Работу с файлами необходимо реализовать с помощью потоков.
В данном примере нам понадобятся три новых компонента. Для визуализации данных воспользуемся диаграммами, которые можно построить с помощью компонента TChart со страницы Additional палитры компонентов. Данный компонент имеет множество настроек и позволяет представлять одновременно несколько диаграмм. В данном случае из множества настроек выберем минимум. Представляемые данные в виде серий задаются с помощью рядов целых чисел (Series). Для создания таких рядов необходимо после размещения компонента на форме щелкнуть на нем правой кнопкой мыши. В появившемся выпадающем меню выбрать пункт Edit Chart - откроется редактор с двумя вкладками. Щелкнуть мышкой на вкладке Chart. С помощью кнопки Add построим, например, три ряда (Series) точек и для каждого ряда выберем вариант графика, цвет и подпись. На форме появятся объекты типа TBarSeries. Далее на вкладке Series выбрать страницу Data Source и установить Random Values (для построения графиков с помощью случайных точек). Все свойства можно редактировать в инспекторе объектов.
171
Для демонстрации возможностей файловых потоков нам понадобятся два диалоговых стандартных компонента со страницы Dialogs: OpenDialog-выбор открываемого файла и SaveDialog - выбор сохраняемого файла. Основная настройка этих элементов заключается в задании расширения выбираемых файлов (DefaultExt - задать CHR - тип файлов, с которыми работает компонент TChart) и фильтра (Filter). Чтобы задать фильтр в файловых диалогах, из инспектора объектов необходимо выйти в FilterEditor и набрать в каждом компоненте по-две строчки (табл. 15).
Таблииа 15
Filter Name |
Filter |
Chart files(*.chr) |
*.ctr |
Any files(*.*) |
*.* |
Для открытия диалога вызывается метод Execute, а при выходе возвращается имя файла в свойстве FileName.
Изменить ;| ■ Метки
Вариант решения примера 21 приводится на рис. 49.
Рис. 49
В примере используется ряд обработчиков событий. Обработчик Form-Create задает первоначальные значения для исходных данных, которые при необходимости можно записать в файл (кнопка "Запись", обработчик Save-ButtonClick) или проигнорировать, загрузив данные из файла (кнопка "Файл", обработчик OpenButtonClick). Кроме того, запоминаются в массиве 172
ge (объявлен в секции формы private) настройки цвета диаграмм и вызывается обработчик (UpdateButtonClick, кнопка "Изменить"), который строит эти диаграммы. С помощью свернутых списков Combos запоминаются варианты графиков (или диаграмм). Использование обработчиков ComboChange и ChBoxMarksCIick позволяет выбрать соответственно желаемый вид диаграммы или промаркировать их (при необходимости можно записать в файл свой выбор). Из всего многообразия графиков в данном случае выбраны четыре: линейный, столбиковый, поверхность, точки (занесены в списки используемых трех элементов TComboBox). Для удобства коррекции данных в строковой таблице подключается маска ввода в виде обработчика StringGrid1GetEditMask. Ниже приводится текст программы.
unit Prim21; interface
uses SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, Dialogs, Grids, StdCtrls, TeEngine, Series, ExtCtrls, TeeProcs, Chart, Menus, Buttons; type
TForm1 = class(TForm)
Chartl: TChart;
Seriesl: TBarSeries;
Series2: TBarSeries;
Series3: TBarSeries;
Panel1: TPanel;
ChBoxMarks: TCheckBox;
OpdateButton: TButton;
StringGrid1: TStringGrid;
ComboBox1: TComboBox;
ComboBox2: TComboBox;
СотЬоВохЗ: TComboBox;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
OpenButton: TButton;
SaveButton: TButton;
BitBtnl: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure OpdateButtonClick(Sender: TObject);
procedure StringGrid1GetEditMask(Sender: TObject; ACol, ARow: Longint; var Value: string);
procedure ChBoxMarksCIick(Sender: TObject);
procedure ComboChange(Sender: TObject);
procedure OpenButtonClick(Sender: TObject);
procedure SaveButtonClick(Sender: TObject); private
Combos: array [ 0..2] of TComboBox;
CurrentFile: s tring;
Se:array [1..3] of TColor;
173
end;
var Form1: TForm1;
implementation
{$R *.DFM}
Procedure TForm1.FormCreate(Sender:TObject);
var I, J: Integer;
begin
with StringGrid1 do begin
for I:=l to 5 do Cells[I,0]:= Format('Группа %d', [I]);
for J:=l to 3 do Cells[0,J]:= Format('Серия %d', [J]); Randomize;
for I := 1 to 5 do
for J := 1 to 3 do
Cells [I,J] :=IntToStr(Random(100));
end;
Combos [0]:= ComboBox1;
Combos [1] := ComboBox2;
Combos [2] := СоmbоВохЗ;
for I := 0 to 2 do begin Combos[I].Itemlndex := 1; Se[I+l]:=Chartl.Series[I].SeriesColor; end;
UpdateButtonClick(self);
end;
procedure TForm1.OpdateButtonCliek(Sender: TObject); var I, J: Integer;
begin
for I := 1 to 3 do begin Chart1.Series[I-1].Clear;
for J:=1 to 5 do Chartl.Series [I-l].Add(
StrToInt(StringGrid1.Cells[J,I]), ' ', Se[I]); end; end;
Procedure TForm1.StringGrid1GetEditMask(Sender: TObject; ACol, ARow: Longint; var Value: string); begin
Value:= ’09:0’; end;
procedure TForm1.ChBoxMarksClick(Sender: TObject);
var I: Integer;
begin
for I := 1 to 3 do
Chartl.Series[I-l].Marks.Visible:= ChBoxMarks.Checked; end;
procedure TForm1.ComboChange(Sender: TObject);
var I: Integer;
SeriesClass: TChartSeriesClass;
NewSeries: TChartSeries;
174
begin
for I := 2 downto 0 do Chartl.Series[I].Free;
for I := 0 to 2 do begin
case Combos [I].Itemlndex of
0: SeriesClass := TLineSeries; 1: SeriesClass := TBarSeries; 2: SeriesClass := TAreaSeries;
else SeriesClass := TPointSeries;
end;
NewSeries:=SeriesClass.Create(self); NewSeries.ParentChart := Chartl;
NewSeries.Title :=Format('Серия %d', [1+1]);
end;
ChBoxMarksClick(self); UpdateButtonClick(self); end;
procedure TForm1.OpenButtonClick(Sender: TObject);
var ReadStream: TFileStream;
I, J, Value: Integer; begin
if OpenDialog1.Execute then begin CurrentFile := OpenDialog1.Filename;
Caption :=' ПРИМЕР 20 (Данные файла '+ CurrentFile+')'; try
ReadStream:= TFileStream.Create(CurrentFile,fmOpenRead);
for I := 1 to 5 do
for J := 1 to 3 do begin
ReadStream.Read(Value, SizeOf(Integer)); StringGrid1.Cells[I, J] := IntToStr(Value);
end;
ReadStream.Read(Value, SizeOf(Integer)); ChBoxMarks.Checked := Boolean(Value);
for I := 0 to 2 do begin
ReadStream.Read(Value, SizeOf(Integer)); Combos[I].Itemlndex := Value; ReadStream.Read(Value, SizeOf(Integer)); Se[i+1] := Value;
end;
finally
ReadStream.Free; end;
ChBoxMarksClick(self) ; ComboChange(self ); UpdateButtonClick(self) ; end; end;
procedure TForm1.SaveButtonClick(Sender: TObject); var SaveStream: TFileStream;
175
177
if SaveDialog1.Execute then begin CurrentFile := SaveDialog1.Filename;
Caption :=' ПРИМЕР 20 (Данные файла ' + CurrentFile+')'; try Savestream := TFileStream.Create(CurrentFile,
fmOpenWrite or fmCreate); for I := 1 to 5 do
for J := 1 to 3 do begin Value := StrToIntDef(
Trim(StringGrid1.Cells[I, J]), 0) ; SaveStream.Write(Value,SizeOf(Integer)); end;
Value := Integer(ChBoxMarks.Checked); SaveStream.Write(Value,SizeOf(Integer)); for I := 0 to 2 do begin
Value := Combos [I].Itemlndex; SaveStream. Write(Value,SizeOf(Integer)); SaveStream.Write(Se[i+l],SizeOf(Integer)); end; finally
SaveStream.Free; end;
end;
end; .
end.
Работа с потоками реализована в обработчиках OpenButtonclick и SaveButtonClick, в которых соответственно выполняется чтение файла в поток Readstream и запись потока SaveStream в файл. Компонент TChart работает с собственным типом бинарных файлов. Потоки Readstream и SaveStream корректно записывают и воспроизводят информацию. В данном случае информация складывается из целых чисел в следующей последовательности: точки графиков, признак меток (преобразуется в булевый тип из числа), виды графиков и их цвета.