Компоненты этой страницы (рис. 44) обеспечивают средства связи программы с глобальной компьютерной сетью Internet.
Рис. 44. Панель Internet
Компоненты доступа к базам данных
В Delphi развиты средства построения клиент-серверных приложений, рассчитанных на работу с базами данных. Эти компоненты собраны на странице Data Access. Панель содержит невизуальные компоненты.
На панели DataControls расположены компоненты, представляющие собой расширения стандартных интерфейсных элементов Windows, предназначенные для совместного использования с компонентами для управления базами данных.
На панели QReport расположены компоненты, обеспечивающие простой способ создания отчетов по результатам выборки данных из базы данных.
Визуальные компоненты стандартных диалогов Windows-интерфейса
В состав Delphi 3 входит десять компонентов, реализующих стандартные диалоговые панели, используемые многими Windows-приложениями (рис. 45).
Рис. 45. Панель Dialogs
Компоненты панели:
TOpenDialog – диалоговая панель выбора открываемого файла по шаблону.
TSaveDialog – диалоговая панель создания файла.
TFontDialog – диалоговая панель выбора шрифта и его характеристик.
TColorDialog – диалоговая панель выбора цвета.
TPrintDialog – диалоговая панель вывода на устройство печати.
TPrinterSetupDialog – диалоговая панель настройки устройства печати.
TFindDialog – диалоговая панель поиска.
TReplaceDialog – диалоговая панель замены.
TOpenPictureDialog – диалоговая панель выбора графического изображения с просмотром.
TSavePictureDialog – диалоговая панель сохранения графического изображения с просмотром.
Основные правила использования диалоговых панелей:
После того как компонент помещен на форму, необходимо связать отображение этой панели с каким-либо событием. Чаще всего таким событием является выбор команды меню или нажатие определенной кнопки. В обработчике события необходимо использовать метод Execute. При обращении к Execute на экране появляется соответствующее диалоговое окно. Окно диалога является модальным. Модальное окно, как известно, приостанавливает выполнение программы до тех пор, пока пользователь не закроет окно. Execute – логическая функция. Проанализировав результат Execute, программа может присвоить возвращаемые значения свойствам тех компонентов, на которые они влияют.
Например,
Procedure TForm1.Button1Click(Sender: TОbject);
Begin
If ColorDialog1.Execute then
Form1.Color:= ColorDialog1.Color;
End;
В первой строке этого метода вызывается стандартная диалоговая панель выбора цвета (рис. 46), а во второй – значение, возвращенное этой диалоговой панелью, присваивается свойству Color формы.
Компоненты TOpenDialog (рис. 47) и TSaveDialog имеют идентичные свойства.
Свойство FileName содержит маршрут поиска и выбранный файл при успешном завершении диалога. Программа может использовать это свойство для доступа к файлу с целью читать из него данные или записывать в него. Свойство Filter используется для фильтрации файлов, показываемых в диалоговом окне. Это свойство можно устанавливать с помощью специального редактора или программно. При программном вводе фильтры задаются одной длинной строкой, в которой символы “|” служат для разделения фильтров друг от друга, а также для разделения описания фильтруемых файлов от соответствующей маски выбора. Для того чтобы отобразить в диалоговой панели все файлы с расширением.TXT, необходимо указать значение этого свойства как
Filter:= ‘*.TXT’;
или
Filter:= ‘Текстовые файлы|.TXT|DOC-файлы|.DOC|Wri-файлы|*.WRI;’
Установить начальный каталог позволяет свойство InitialDir.
Создадим простую программу для просмотра содержимого текстового файла. Для этого на пустую форму помещаем компонент ТOpenDialog, кнопку ТButton и редактор ТMemo. При работе программы щелчок по кнопке будет сигналом о необходимости загрузить в редактор новый файл.
Обработчик события.
Prоcedure TForm1.Button1Click(Sender:TObject);
Var S: String; F: TextFile;
Begin
OpenDialog1.Filter:= ‘Текстовые файлы|*.TXT|Файлы Паскаля|*.PAS’;
If OpenDialog1.Execute and FileExists(OpenDialog1.FileName) Then
Begin
AssignFile(F, OpenDialog1.FileName);
Reset(F);
Memo1.Lines.Clear;
While not EOF(f) Do
Begin
ReadLn(F, S);
Memo1.Lines.Add(S)
End;
CloseFile(F)
End;
End;
Компонент FontDialog (рис. 48) имеет свойство Device, которое позволяет указать тип устройства. Свойство может иметь следующие значения: fdScreen – экран, fdPrinter – принтер, fdBoth – экран и принтер.
В следующем примере показано, как отобразить панель выбора шрифтов для принтера.
Procedure TForm1.Button1Click(Sender: TObject);
Var FontName: TFont;
Begin
FontDialog1.Device:= fdPrinter;
FontDialog1.Execute;
FontName:= FontDialog1.Font;
End;
Компоненты ActiveX
Компоненты ActiveX являются чужими для Delphi. Они создаются другими инструментальными средствами разработки программ и внедряются в Delphi с помощью технологии OLE.
Списки и коллекции
В процессе разработки программного кода приложения часто бывает необходимо хранить наборы различных констант или переменных. Это может быть список дней недели или группа вспомогательных объектов, созданных в процессе работы приложения для хранения промежуточных результатов расчета. Для работы со строковыми списками предназначены классы TStrings и TStringList. Компоненты VCL TCombobox, TList, TDBComboBox представляют собой оболочки для списков строк. В других компонентах (TМemo, TStringGrid) списки обеспечивают представление данных. Любые типы данных можно заносить в список указателей, который реализован в классе TList. Использование наборов объектов, которые называются коллекциями, осуществляется при помощи классов TСollection и TСоllectionItem.
Класс TStrings является базовым абстрактным классом, который обеспечивает потомков основными свойствами и методами, позволяющими создавать работоспособные списки строк. Его прямым предком является класс TPersistent.
Основой механизма списка является свойство, предназначенное для хранения элементов списка:
Strings [Index: Integer]: String;
Обращение к отдельному элементу списка может осуществляться через это свойство:
SomeStrings.Strings[i]:= Edit1.Text; или SomeStrings [i]:= Edit1.Text
С каждым элементом списка можно связать любой объект. Для этого используется свойство
Objects [Index: Integer]: TObject
Чаще всего объекты нужны, чтобы хранить для каждого элемента дополнительную информацию. Например, в списке городов для каждого элемента можно дополнительно хранить население, площадь, административный статус и т.д. Для этого можно создать такой класс:
TSityProps = Class (TObject)
Square: LongInt;
Population: LongInt;
Status: String;
End;
Для добавления к строке объекта из списка используется метод AddObject, например:
SomeStrings.AddObject (‘SomeItem’, TSityProps.Create);
Вспомогательные свойства класса содержат информацию о состоянии списка. Дополнительные методы осуществляют поиск в списке и взаимодействие с файлами и потоками.
Класс TStrings является абстрактным, и большинство его методов перекрыты в потомке TStringList, а реального механизма заполнения списка не существует вообще.
Класс TSringList обеспечивает реальное использование списков строк в приложении. Свойства и методы класса можно посмотреть в справочной литературе, здесь рассмотрим только некоторые из них.
Помимо свойства Strings, содержимое списка можно получить при помощи свойств Text и CommaText. Они представляют все строки списка в виде одной длинной строки. Во втором свойстве строки заключены в кавычки и разделены запятыми или пробелами.
Добавление новых строк осуществляется при помощи методов Add и Insert. Первый метод добавляет строку в конец списка, а второй вставляет ее в указанное место.
В список можно добавить сразу несколько записей. Для этого применяются методы AddStrings и Assign. Причем второй метод вместе со строками добавляет и связанные с ними объекты.
Для добавления одного объекта можно использовать метод AddObject. Для того чтобы добавить объект к уже существующей строке, необходимо сначала создать объект, а затем присвоить его свойству Object.
Для поиска необходимой строки созданы методы, осуществляющие поиск по разным параметрам:
IndexOf – поиск по значению строки;
IndexOfName – поиск левой части равества;
IndexOfObject – поиск по объекту.
Строки списка можно отсортировать в порядке возрастания при помощи свойства Sorted или метода Sort.
Список можно загрузить из файла или потока. Для этого используются методы LoadFromFile и LoadFromStream. Сохранение списка выполняется методами SaveToFile и SaveToStream.
В качестве примера использования списков рассмотрим следующую учебную задачу. Необходимо разработать приложение, представляющее собой фрагмент работы с базой данных. База данных состоит из списка товаров. В самом списке хранится только номер товара по порядку. С каждой строкой связан объект, в котором содержится более полная информация о товаре: наименование, стоимость, страна-импортер, объем партии. Список можно редактировать, сохранять списки в файлах, загружать из файлов.
Рис. 49. Форма приложения, демонстрирующего работу со списками
Проектирование окна приложения:
Для формирования главного меню окна используем компонент TМainMenu, в котором определим три пункта с заголовками “Открыть”, “Записать”, “Выход” и названиями N1, N2, N3. Четыре редактора Edit1... Edit4 предназначены для ввода и вывода информации. В редакторе Edit5 организован вывод номера строки списка. Кнопки Bitbtn1 и BitBtn2 осуществляют перемещение по элементам списка. Для организации взаимодействия программы с файлами на дисках используются диалоговые панели OpenDialog1 и SaveDialog1.
Добавляем описание:
Type TTovar = Class // Объявляем новый класс.
Name, Cost, Country, Volume: String[20];
Constructor Create (a: String);
End; // Объекты этого класса будут связаны с элементами списка.
var
Form1: TForm1; Num, Numk: Integer;
List1: TStringList; Tovar: TTovar;
Конструктор для создания нового объекта:
Constructor TTovar.Create;
Begin
Inherited Create;
Name:= a;
End;
Процедура для добавления элемента списка:
Procedure Mem;
Begin
List1.add(IntToStr(Num));
Tovar:= TTovar.Create(‘ ‘); // Выделяем память под объект
List1.Objects[Num]:= Tovar;
End;
Обработчики событий:
procedure TForm1.FormCreate(Sender: TObject);
begin
List1:=TStringList.Create; // Создаем список
Num:= 0; Mem; Edit5.Text:= ‘0’; // Создали 0-ой элемент списка
end;
procedure TForm1. BitBtn1Click (Sender: TObject);
Begin
Edit5.Text:= IntTostr(Num);
With List1.Objects[Num] as TTovar do
Begin // Записали информацию в список
Name:= edit1.text;
Cost:= edit2.text;
Country:= edit3.Text;
Volume:= edit4.text;
End;
If (Sender AS TBitBtn).Name = ‘BitBtn1’Then
Begin // Перемещение к началу списка
If Num = 0 Then exit;
Num:= Num - 1;
End;
If (Sender AS TBitBtn).Name = ‘BitBtn2’ Then
Begin // Перемещение к концу списка
Num:= Num + 1;
If Num > List1.Count Then Mem;
End;
// Считываем информацию из списка
With List1.Objects [Num] as TTovar do
Begin
edit1.text:= Name;
edit2.text:= Cost;
edit3.Text:= Country;
edit4.text:= Volume;
End;
End;
// Считываем информацию из файла.
procedure TForm1.N1Click(Sender: TObject);
Var F: TextFile;
begin
Try
With OpenDialog1 Do
Begin
If Not Execute Then Exit;
List1.LoadFromFile (FileName); // Загружаем список из файла
// Подготавливаем файл для чтения информации в объект Tovar.
AssignFile(F,Copy(FileName,1,Length(FileName)-4)+’.ооo’);
Reset(F);
Num:= 0
While Not Eof(F) Do // Цикл для чтения информации полей объекта Tovar
With List1 Do
Begin
If List1.Objects[Num] = Nil Then
Begin
Tovar:= TTovar.Create(‘ ‘);
List1.Objects[Num]:= Tovar;
End;
Readln(F,(Objects[Num] AS TTovar).Name);
Readln(F,(Objects[Num] AS TTovar).Cost);
Readln(F,(Objects[Num] AS TTovar).Country);
Readln(F,(Objects[Num] AS TTovar).Volume);
Inc(Num);
End;
CloseFile(F);
End;
Except
ShowMessage(‘Ошибка открытия файла’);
End;
Num:= 0; // Выводим информацию в окна приложения
With List1.Objects [Num] as TTovar do
Begin
edit1.text:= Name;
edit2.text:= Cost;
edit3.Text:= Country;
edit4.text:= Volume;
End;
Edit5.Text:= IntToStr(Num);
end;
// Записываем информацию в файл.
procedure TForm1.N2Click(Sender: TObject);
Var F: TextFile; i: Integer;
begin
Try
With SaveDialog1, List1 Do
Begin
If Not Execute Then Exit;
SaveToFile (FileName); // Записали элементы списка
AssignFile(F,Copy(FileName,1,Length(FileName)-4)+’.ооo’);
Rewrite(F);
For i:= 0 To Count - 1 Do // Цикл по количеству записей
Begin
If Objects[i] <> Nil Then
Writeln(F,(Objects[i] AS TTovar).Name);
Writeln(F,(Objects[i] AS TTovar).Cost);
Writeln(F,(Objects[i] AS TTovar).Country);
Writeln(F,(Objects[i] AS TTovar).Volume);
End;
CloseFile(F);
End;
Except
ShowMessage(‘Ошибка открытия файла’);
End;
End;
Объект Tovar обеспечивает хранение для каждого элемента списка дополнительных атрибутов. В простейшем конструкторе объекта задается значение для свойства Name.
Обработчик BitBtn1Click осуществляет перемещение по строкам списка в двух направлениях, вывод информации в окна редакторов Edit и записывает те изменения, которые могут производиться в этих окнах. BitBtn1Click обрабатывает события, которые возникают при нажатии двух кнопок BitBtn1 и BitBtn2. Идентификация нажатой кнопки происходит по параметру Sender.
Сохранение и загрузка элементов списка осуществляется использованием методов SaveToFile и LoadFromFile. Для хранения информации из объектов организован вспомогательный файл с расширением.ooo.
Основой класса TList является список указателей. Сам список представляет собой динамический массив указателей, к которому можно обратиться через индексированное свойство
Items [Index: Integer]: Pointer;
Свойство Itemindex определяет индекс текущего элемента списка.
Реализованные в классе TList операции со списком обеспечивают потребности разработчика и совпадают с операциями списка строк.
Для добавления к концу списка нового указателя используется метод
Add (Item: Point): Integer;
Прямое присваивание значения элементу, который еще не создан при помощи метода Add, вызовет ошибку времени выполнения.
Новый указатель можно добавить в нужное место списка. Для этого используется метод
Insert (Index: Integer; Item: Pointer);
Можно поменять местами два элемента, определяемые параметрами Index1 и Index2:
Exchange (Index1, Index2);
Для удаления указателей из списка используются два метода. Если известен индекс, используется метод
Delete (Index: Integer);
Если известен сам указатель, используется метод
Remove (Item: Pointer): Integer;
Полностью все методы и свойства класса TList можно посмотреть в справочной литературе и справочной системе Delphi.
Коллекция представляет собой разновидность списка указателей, оптимизированную для работы с объектами определенного вида. Сама коллекция инкапсулирована в классе TСollection. Элемент коллекции должен быть экземпляром класса, унаследованного от класса TСollectionItem. Это облегчает программирование и позволяет обращаться к свойствам и методам объектов напрямую. Например, панели компонента TСoolBar объединены в коллекцию. Класс TСoolBands, объединяющий панели, является наследником класса TСollection. Отдельная панель является экземпляром класса TСoolBar, происходящего от класса TСollectionItem.
Графический интерфейс
В состав VCL Delphi входят объектно-ориентированные надстройки над объектами GUI (Graphic User Interface), назначением которых является обеспечение удобного доступа к свойствам инструментов и прозрачная для программиста обработка всех их изменений.
Класс TСanvas
Класс TСanvas еще называют канвой. Он объединяет в себе и “холст”, “рабочие инструменты” (перо, кисть, шрифт) и “подмастерьев” – набор функций по рисованию типовых геометрических фигур.
Канва не является компонентом, но она входит в качестве свойства в те из них, которые должны уметь нарисовать себя и отобразить какую-либо информацию. На канве компонента можно рисовать геометрические фигуры, тексты, составлять из отдельных точек разнообразные узоры и отображать растровые изображения.
Свойство Canvas имеют многие компоненты VCL и форма в том числе.
Для рисования канва включает в себя свойства – шрифт, перо и кисть:
Font: TFont;
Pen: TPen;
Brush: TBrush.
На канве можно рисовать и поточечно, получив доступ к каждому пикселю: свойство Pixels [X, Y: Integer]: TСolor.
Начало координат канвы расположено в левом верхнем углу. Координата Х отсчитывается по горизонтали слева направо. Координата Y отсчитывается по вертикали сверху вниз.
Свойство PenPos: TPoint содержит координаты текущей точки пера канвы.
Канва содержит методы рисования геометрических фигур и закрашивания их с помощью текущей кисти. Вот несколько из них:
Arc (X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer) чертит дугу эллипса в охватывающем прямоугольнике (X1, Y1) – (X2, Y2).
Ellipse(X1, Y1, X2, Y2: Integer) чертит эллипс в охватывающем прямоугольнике (X1, Y1) – (X2, Y2).
LineTo (X, Y: Integer) чертит линию от текущего положения пера до точки (X, Y).
FrameRect (const Rect: TRect) очерчивает границы прямоугольника Rect текущей кистью толщиной в 1 пиксель без заполнения внутренней части прямоугольника.
MoveTo (X, Y: Integer) перемещает перо в положение (X, Y) без вычерчивания линий.
Polygon (Points: array of TPoint) вычерчивает пером многоугольник по точкам, заданным в массиве Points.
Rectangle (X1, Y1, X2, Y2: Integer) вычерчивает и заполняет прямоугольник (X1, Y1) – (X2, Y2).
FloodFill (X, Y,: Integer; Color: TColor; FillStyle: TFillStyle) производит заливку канвы текущей кистью.
TextOut (X, Y: Integer; const Text: String) выводит текстовую строку Text так, чтобы левый верхний угол прямоугольника, охватывающего текст, располагался в точке (X, Y).
Draw (X, Y: Integer; Graphic: TGraphic) осуществляет прорисовку графического объекта Graphic.
StretchDraw (const Rect: TRect: Graphic: TGraphic) осуществляет рисование объекта Graphic в заданном прямоугольнике Rect. Если их размеры не совпадают, Graphic масштабируется.
CopyRect (Dest: TRect; Canvas: TCanvas; Source: TRect); копирует изображение Source канвы Canvas в участок Dest текущей канвы.
В качестве примера построим изображение, представленное на рис. 51.
Рис. 51. Пример использования свойства Canvas
Обработчик события:
procedure TForm1.Button1Click(Sender: TObject);
const pi = 3.14159;
Var x, y: Real; px, py, offset, halfheight: LongInt;
begin
// Определяются координаты половины стороны внизу формы
halfheight:= Form1.Height div 2;
offset:=0;
For offset:= -10 To 10 Do
Begin
px:= 0;
While px < Form1.Width Do
Begin
//Масштаб х приводится к 2 ПИ,
//чтобы сделать одну полную синусоиду
x:= px * (2 * pi/Form1.Width);
y:= Sin(x);
py:= Trunc(0.7 * y * halfheight) + halfheight + (offset * 10);
If (px = 0) Then Canvas.LineTo (px, py);
Canvas.LineTo (px, py);
py:= Trunc(0.7 * y * halfheight) + halfheight + ((offset-1) * 10);
Canvas.LineTo (px, py);
px:= px +15;
End;
End;
end;
Класс TFont
С помощью этого класса создается объект-шрифт для любого графического устройства.
Свойство Color: TColor задает цвет шрифта.
Свойство Size: Integer – высота шрифта в пунктах (1/72 дюйма).
Свойство Style: TFontStyles – стиль шрифта. fsBold – жирный, fsItalic – курсив, fsUnderline – подчеркнутый, fsStrikeOut – перечеркнутый.
Установка свойств класса вручную осуществляется в основном на этапе проектирования. Чтобы изменить шрифт для какого-то компонента во время выполнения, используют компонент ТFontDialog.
Пример использования свойств TFont:
Var F: TFont;
Begin
F:= TFont.Create;
With F Do
Begin
Name:= ‘Arial’; Height:= 40;
Color:= clBlue; Size:= 40;
Style:= [fsBold];
End;
Canvas.Font:= F;
Canvas.TextOut(10, 10, ‘Шрифт’);
F.Free;
End;
Класс TPen
Этот класс инкапсулирует свойство пера. В конструкторе по умолчанию создается непрерывное черное перо шириной в один пиксель. Класс TPen содержит свойства:
Color: TColor – цвет вычерчиваемых пером линий;
Style: TPenStyle определяет стиль линий (psSolid – сплошная, psDash – пунктирная и т.д.);
Width: Integer – толщина линий в пикселях;
Mode: TPenMode определяет способ взаимодействия линий с фоном (перечисляемый тип TPenMode см. в справочной системе Delphi).
Класс TBrush
Объекты этого класса служат для заполнения внутреннего пространства замкнутых фигур.
Свойства:
Bitmap: TBitmap содержит растровое изображение, которое будет использоваться кистью для заполнения;
Color: TСolor – цвет кисти;
Style: TВrushStyle – стиль кисти (bsSolid – сплошная, bsBDiagonal –заштрихованная по диагонали, bsCross – заштрихованная в клетку, bsVertical – заштрихованная вертикальными линиями и т. д).
Пример построения заштрихованного объекта на компоненте TРaintBox:
procedure TForm1.Button1Click(Sender: TObject);
Var w, h: Integer;
begin
With PaintBox1 Do
Begin
W:=Width Div 6; h:= Height Div 6;
Canvas.Brush.Style:= bsCross;
Canvas.Pen.Color:=clBlue;
Canvas.Ellipse(w, h, 5 * w, 5 * h);
End;
end;