Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование Часть 2 - Delphi

.pdf
Скачиваний:
24
Добавлен:
16.03.2015
Размер:
734 Кб
Скачать

51

В приведѐнном примере в обработчике события OnFormCreate задаются начальные размеры формы, которые затем меняются по таймеру.

procedure TForm1.FormCreate(Sender: TObject);

begin

Form1.Height:=28; Form1.Width:=124;

Timer1.Enabled:=true;

end;

procedure TForm1.Timer1Timer(Sender: TObject);

begin

with Form1 do

begin

if Width<574 then Width:=Width+50 else

if Height<308 then Height:=Height+40 else Timer1.Enabled:=false;

end;

end;

3.5.Создание окон диалога 3.5.1. Процедуры и функции, реализующие диалоги

ВDelphi имеются процедуры и функции для отображения диалоговых окон общего

назначения. Для вывода сообщений используются процедура ShowMessage и функции

MessageDlg, MessageDlgPos. Для ввода данных применяются окна диалога, отображаемые функциями InputBox и InputQuery.

Процедура ShowMessage (const Msg : String) выводит окно сообщения с кнопкой ОК.

Заголовок содержит название исполняемого файла приложения, а строка Msg содержит текст сообщения. Например:

ShowMessage('Повторите ввод целого числа');

Функция MessageDlg (const Msg: String; AType: TMsgDlgType; AButtons: TMsgDlgButtons; HelpCtx: Longint):Word отображает окно сообщений и позволяет получить ответ пользователя. Параметр Msg содержит выводимое сообщение. Параметр

AType задаѐт тип окна (Warning, Error, Information и др.). Параметр AButtons определяет набор кнопок окна (Yes, No, OK, Cancel, Cancel, Help, Abort, Retry, Ignore). Для этого параметра имеются две константы, задающие предопределенные наборы кнопок:

mbYesNoCancel = [mbYes, mbNo, mbCancel] mbOKCancel = [mbOK, mbCancel]

Параметр HelpCtx определяет тему справки, появляющейся при нажатии пользователем клавиши F1. Обычно значение этого параметра равно нулю.

52

Щелчок по любой кнопке, кроме Help, закрывает окно диалога. При этом функция

MessageDlg возвращает модальный результат, проанализировав который, можно управлять выполнением приложения.

Функция MessageDlgPos отличается от функции MessageDlg наличием параметров х и y, управляющих положением окна на экране.

Функция InputBox(const ACaption, APrompt, ADefault: String):String отображает в центре экрана диалоговое окно, служащее для ввода строки текста. В окне имеется поле ввода, а также кнопки ОК и Cancel. Параметр ACaption задает заголовок окна, параметр

APrompt содержит поясняющий текст к полю ввода. Параметр ADefault определяет строку,

возвращаемую функцией при отказе пользователя от ввода информации нажатием кнопки

Cancel или клавиши Esc. Пример использования функции InputBox: st:=InputBox('Студент', 'Введите фамилию', 'Неизвестный');

Функция InputQuery(const ACaption, APrompt:String; var Value:String):Boolean

отличается от функции InputBox тем, что вместо строки по умолчанию используется параметр Value, который при подтверждении ввода содержит введенную пользователем строку. Например:

InputQuery('Студент', 'Введите фамилию', st);

Возвращаемое функцией InputQuery логическое значение позволяет определить,

каким образом завершен диалог (ОК соответствует true).

3.5.2.Стандартные диалоговые панели

На странице Dialogs Палитры компонентов расположены компоненты, реализующие диалоговые окна общего назначения. Использование стандартных окон диалога выполняется по единому сценарию, приведѐнному ниже.

Поместить на форму компонент и настроить его свойства в Инспекторе объектов или программно.

Вызвать метод Execute, который создаѐт и выводит окно на экран. Вызов этого метода обычно располагается в обработчике какого-либо события. Так как окно диалога модальное, то после применения метода Execute выполнение программы приостанавливается до тех пор, пока пользователь не закроет окно. Функция Execute

возвращает true, если результат диалога успешный (OK).

Проанализировав результат диалога, можно выполнить третий этап: использование введѐнных с помощью диалогового окна данных.

Рассмотрим более подробно диалоговые окна открытия и сохранения файла. Так как окна похожи, то компоненты OpenDialog и SaveDialog, предназначенные для их создания,

имеют идентичный набор свойств и методов. Свойство FileName строкового типа задаѐт

53

имя и полный путь файла, выбранного в диалоге. Для удобства дальнейшего использования рекомендуется задавать каталог, открываемый при первом появлении диалога (свойство InitialDir), и формировать фильтр имени файла.

Свойство Filter можно задать в Инспекторе объектов или программно. На этапе проектирования следует щѐлкнуть по кнопке в строке Filter и в открывшемся редакторе записать название типа файла (слева) и маску (справа). Если требуется отображать файлы нескольких типов, то придѐтся сформировать соответствующее количество строк. При задании фильтра программно все сведения записывают одной строкой, в которой в качестве разделителя между фильтрами, описанием файла и маской используется вертикальная черта. Если для одного описания приводится несколько масок, то они разделяются символом «;».

У компонента SaveDialog следует задать свойство DefaultExt, определяющее расширение, добавляемое по умолчанию к имени файла. Иногда целесообразно в свойстве

FileName записать имя файла. Например:

OpenDialog1.Filter:='Текстовые txt|*.txt|Файлы Pas|*.pas';

SaveDialog1.DefaultExt:='txt'; SaveDialog1.Filter:= OpenDialog1.Filter; if SaveDialog1.Execute

then Memo1.Lines.SaveToFile(SaveDialog1.FileName);

if OpenDialog1.Execute

then begin

st:= OpenDialog1.FileName;

Memo2.Lines.LoadFromFile(st);

Memo3.Lines.SaveToFile(st);

end;

Для тонкой настройки параметров и внешнего вида окна используется составное свойство Options. По умолчанию все параметры имеют значение False. Для ввода имени с клавиатуры предусмотрен компонент Edit, который можно заменить на ComboBox,

присвоив свойству FileEditStyle значение fsComboBox вместо fsEdit. Если используется комбинированный список, то с ним можно связать протокол выбора имѐн (свойство

HistoryList). Пополнять этот список надо программно.

Специализированные диалоги открытия и сохранения графических файлов

OpenPictureDialog и SavePictureDialog отличаются от OpenDialog и SaveDialog удобной возможностью просматривать изображения и заданным значением свойства Filter. Причѐм в фильтре по умолчанию перечислены все разрешѐнные форматы. При необходимости

54

откорректировать фильтр на этапе проектирования очень просто: достаточно удалить

лишние строки.

OpenPictureDialog1.Filter:='Графические файлы bmp|*.bmp|'+

'Все файлы|*.bmp;*.jpg;*.jpeg;*.ico;*.emf;*.wmf';

OpenPictureDialog1.InitialDir:= 'F:\A_Slide';

if OpenPictureDialog1.Execute then

Image1.Picture.LoadFromFile(OpenPictureDialog1.fileName);

3.5.3.Использование модального окна

Поведение модальной формы определяется свойством ModalResult. Это свойство доступно только во время выполнения приложения. При открытии формы методом

ShowModal свойство ModalResult приобретает значение, равное нулю. Как только это свойство получит положительное значение – модальное окно будет закрыто.

Требуемое значение ModalResult можно задать программно в обработчиках событий для компонентов модальной формы. Однако проще воспользоваться свойством

ModalResult кнопок Button и BitBtn. В кнопках BitBtn это свойство имеет значение,

соответствующее назначению кнопки. Для кнопки Button свойству ModalResult можно задать нужное значение. При использовании кнопки для закрытия окна еѐ свойство

ModalResult определяет, какое значение будет иметь одноимѐнное свойство формы.

Для облегчения трактовки результата в Delphi объявлены именованные константы

(см. таблицу 1). Чаще требуемые значения свойства ModalResult для кнопок задаются на этапе проектирования. Однако в некоторых случаях целесообразно установить значения во время работы приложения. Например, чтобы запретить закрытие модального окна.

Таблица 1

Значения свойства ModalResult

Число

Константа

Значение

 

Примечание

 

 

 

 

 

 

 

0

mrNone

 

 

 

 

 

 

 

 

 

1

mrOk

idOk

 

Закрытие кнопкой OK

 

 

 

 

 

 

2

mrCancel

idCancel

 

Закрытие

кнопкой

 

 

 

Cancel или методом Close

 

 

 

или

кнопкой в

строке

 

 

 

заголовка окна

 

 

 

 

 

 

 

3

mrAbort

idAbort

 

Закрытие

кнопкой

 

 

 

Abort

 

 

 

 

 

 

 

4

mrRetry

idRetry

 

Закрытие

кнопкой

 

 

 

 

 

 

55

 

 

 

Retry

 

 

 

 

 

 

5

mrIgnor

idIgnor

Закрытие

кнопкой

 

 

 

Ignor

 

 

 

 

 

6

mrYes

idYes

Закрытие кнопкой Yes

 

 

 

 

7

mrNo

idNo

Закрытие кнопкой No

 

 

 

 

8

mrAll

mrNo+1

Закрытие кнопкой All

 

 

 

 

 

9

mrNoToAll

mrAll+1

Закрытие

кнопкой

 

 

 

NoToAll

 

 

 

 

 

 

10

mrYesToAll

NoToAll+1

Закрытие

кнопкой

 

 

 

YesToAll

 

 

 

 

 

 

При закрытии модального окна функция ShowModal возвращает значение свойства

ModalResult. Таким образом, для оценки действия пользователя можно прочитать значение свойства формы ModalResult или воспользоваться результатом, возвращаемым функцией ShowModal.

При разработке приложения следует учитывать, что закрытию формы методом Close

соответствует значение mrCancel свойства ModalResult. Скрытие формы методом Hide не изменяет значения ModalResult.

Последовательность действий при создании окна диалога:

1)создать новую форму, присвоить ей имя (например, MyDlg), задать значения свойств и сохранить в файле;

2)используя команду File|Use Unit, связать с нужной формой приложения;

3)в обработчик события для пункта меню или кнопки включить команду,

выводящую окно на экран: MyDlg.ShowModal;

4) проанализировать результат диалога. Например, применить конструкцию if MyDlg.ModalResult=mrOk then <операторы> else <операторы>;

Альтернативный вариант предполагает совмещение пунктов 3 и 4 путѐм использования конструкции:

if MyDlg.ShowModal then <операторы> else <операторы>;

Метод ShowModal выводит на экран модальное окно, а при его закрытии возвращает результат диалога.

if MyDlg.ShowModal=mrOk

then begin

label1.Caption:=MyDlg.Edit1.Text;

label2.Caption:=MyDlg.Edit2.Text;

56

end

else begin

MyDlg.Edit1.Text:=st1;

MyDlg.Edit2.Text:=st2;

end;

3.5.4.Использование заготовок

Применение имеющихся в репозитории заготовок позволяет ускорить разработку

приложений. Чтобы воспользоваться заготовкой (шаблоном), необходимо:

выполнить команду File|New|Other, перейти на страницу Dialogs;

выбрать подходящую заготовку, установить переключатель в положение Copy и

нажать кнопку OK. Появится соответствующая форма, и сведения о ней система Delphi

включит в файл проекта;

при необходимости разместить на форме дополнительные компоненты и изменить значения свойств имеющихся;

сохранить форму;

подсоединить диалоговую панель к нужной форме приложения;

вывести окно диалога на экран командой ShowModal;

обработать результат диалога.

Следует иметь в виду, что самостоятельно написать обработку кнопок, имеющихся в заготовке, нельзя. Кнопки можно использовать только по назначению, то есть в соответствии с расположенной на них надписью.

Например, добавим в проект окно диалога для ввода пароля PasswordDlg. Пароль будем запрашивать при попытке выполнить одну из команд меню.

procedure TForm1.Dialog1Click(Sender: TObject); begin

if PasswordDlg.ShowModal=mrok then

if PasswordDlg.Password.Text='Shaker' then Form3.Show; end;

3.6. Графика

3.6.1.Поддержка графики в Windows

Вывод графики в Windows осуществляется с помощью функций Graphics Device Interface (GDI). Функции GDI используют как сама операционная система, так и программы, функционирующие под управлением Windows.

Функции, реализованные в GDI, являются аппаратно-независимыми. Они взаимодействуют с устройством через специальную программу, называемую драйвером

57

устройства. Такой подход позволяет приложению и операционной системе работать на компьютерах с различным периферийным оборудованием. При появлении новых моделей видеокарт, принтеров, плоттеров необходимо подключить новый драйвер. Функции GDI

взаимодействуют с драйвером устройства через специальную структуру данных,

называемую контекстом устройства. Эта структура содержит основные характеристики устройства и ссылки на различные средства отображения (кисти, карандаши, цвета и т.п.).

Драйвер устройства преобразует аппаратно-независимые функции GDI в команды конкретного устройства. Прежде чем вызвать какую-либо функцию для отображения информации, приложение должно получить ссылку на контекст устройства вывода, а

после завершения действия – освободить полученный контекст.

3.6.2.Восстановление изображений

Windows-приложение делит экран компьютера с другими приложениями.

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

Операционная система не хранит копий выводимых на экран окон, но запоминает координаты разрушаемых частей окна в системной области, называемой областью обновления. Периодически у каждого окна проверяется область обновления, и если она оказывается не пустой, то приложению-владельцу посылается сообщение с требованием перерисовать окно. Приложение передаѐт соответствующее сообщение форме. Форма восстанавливает утраченные части окна собственными средствами. С точки зрения формы сообщение о перерисовке – это системное событие, а формирование изображения – реакция на него. Для ускорения графического вывода Windows реализует отсечение. В

результате при перерисовке отображаются только те части формы, которые были не видны. Рисование за границами области отсечения не выполняется. Принятый подход приводит к нарушению изображений, размеры которых зависят от размеров формы. Для таких изображений необходимо в форме определить обработчик события OnResize,

поместив в него вызов метода Invalidate.

Метод Invalidate определяет всю рабочую область формы как подлежащую обновлению. После вызова метода Invalidate форма не будет перерисована сразу.

Перерисовка произойдѐт при очередном событии OnPaint. Если надо перерисовать форму немедленно, то следует вызвать метод Refresh.

58

3.6.3.Вывод графической информации в Delphi

Для построения изображений в Delphi была введена иерархия графических классов и разработаны компоненты. Средства Delphi избавляют программиста от непродуктивных потерь времени на управление ресурсами графической системы и облегчают вывод графической информации. Однако сохранена возможность работы непосредственно с функциями GDI и разрешено комбинировать использование компонентов с процедурами и функциями графической системы Windows. Для обращения к функциям GDI все графические объекты имеют целочисленное свойство Handle.

Средства Delphi позволяют выводить заранее подготовленные изображения и рисовать из программы. Первый способ не требует программирования и прекрасно подходит для вывода статических изображений. Он основан на использовании компонентов Image и Shape. Второй способ требует определѐнных навыков программирования, но предоставляет больше возможностей для динамического создания изображений. Он основан на использовании доступного программно свойства Canvas.

Построение изображения выполняется в обработчике события OnPaint.

3.6.4.Классы и компоненты для работы с графикой

Для работы с графикой определены классы TGraphic, TPicture, TGraphicObject, TCanvas.

TGraphic – это абстрактный класс для инкапсуляции различных графических форматов, поддерживаемых Windows. Наследниками этого класса являются TBitmap, TIcon, TMetafile.

Класс TPicture представляет собой полнофункциональный класс, содержащий всѐ необходимое для работы с готовыми изображениями, является контейнером для класса

TGraphic, позволяет загружать различные графические изображения, не заботясь о формате. Методы класса определяют тип изображения по расширению имени файла.

Свойство Graphic класса TPicture указывает на тип используемого графического изображения.

Классы TGraphic и TPicture содержат ограниченное количество поддерживаемых ими форматов, однако на базе TGraphic можно создавать новые классы, которые будут поддерживать другие графические форматы.

Абстрактный класс TGraphicObject является родительским по отношению к классам

TFont, TBrush, TPen. Классы TFont, TBrush, TPen используются только в качестве свойств других классов.

Компонент TPaintBox используется в тех случаях, когда необходимо иметь прямоугольную область для выполнения графических операций. Использование этого

59

компонента может быть альтернативой рисованию по канве формы, но TPaintBox не позволяет загружать готовые изображения.

3.6.5.Программное рисование

Класс TCanvas инкапсулирует основные операции модуля GDI. Canvas – это поверхность рисования (холст, канва). Форма и все визуальные управляющие компоненты

Delphi обладают свойством Canvas. Конструктор Create создаѐт экземпляр класса TCanvas

со свойствами: Brush, Pen, Font, CopyMode, ClipRect, PenPos, Pixels.

Brush, Pen и Font называютcя инструментами для рисования.

Свойство ClipRect (только для чтения) задаѐт координаты отсекающего прямоугольника. За пределами этой прямоугольной области изображение не строится.

Свойство CopyMode устанавливает режим копирования. Значение свойства cmSrcCopy

определяет обычное копирование, то есть замену текущего изображения.

Свойство PenPos – это текущая позиция карандаша – невидимый маркер, который задаѐтся горизонтальной PenPos.x и вертикальной PenPos.y координатами. Pixels[X,Y: integer]:color представляет собой массив, содержащий цвета пикселей. Для доступа к отдельному пикселю достаточно указать его координаты.

При построении графических изображений часто используются классы TPoint и TRect, задающие координаты точки и прямоугольную область:

TPoint=record

x:Longint;

y: Longint; end;

TRect=record

Case integer of

0:(Left,Top,Right,Bottom:integer); 1:(TopLeft, BottomRight: TPoint);

end;

Одним из приѐмов построения изображения является использование рекурсии. На рисунке 3 приведены деревья, полученные многократным построением двух отрезков,

выходящих из одной точки.

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

60

Рис.3. Построение изображения с использованием рекурсии У «регулярного» дерева на каждом шаге длины отрезков и углы одинаковы. Во

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

Фрагмент кода, реализующего «регулярное» дерево, приведѐн ниже. Процедура

Branch1 строит отрезки. В теле процедуры на каждом шаге вычисляются координаты концов отрезков, и для каждого из них выполняется вызов процедуры Branch1.

procedure Branch1(x,y,l,f,df,l_min:integer; r:real); const u=0.01745;

var

x1,x2,y1,y2,f1,f2:integer;

t1,t2:real;

begin

t1:=f-df;

x1:=x+round(l*cos(t1*u));

y1:=y+round(l*sin(t1*u));

t2:=f+df;

x2:=x+round(l*cos(t2*u));

y2:=y+round(l*sin(t2*u));

with Form1.PaintBox1 do

begin

canvas.moveTo(x1,y1);

canvas.lineTo(x,y);