Департамент образования Ярославской области
государственное образовательное учреждение
среднего профессионального образования
Ярославской области
ЯРОСЛАВСКИЙ АВТОМЕХАНИЧЕСКИЙ ТЕХНИКУМ
ИНСТРУКЦИИ К ПРАКТИЧЕСКИМ РАБОТАМ
(базовый уровень среднего профессионального образования)
для специальности
230115 Программирование в компьютерных системах
2013
Инструкции к практическим работам учебной дисциплины МДК 01.02 «Прикладное программирования». - Ярославль: Информационный центр, 2013. – 61 с.
одобрено предметно-цикловой комиссией информатики, вычислительной техники и автоматизации Протокол № от « » _____________ 2013 г
Председатель ПЦК Информатики, вычислительной техники и автоматизации
___________________ М.Е. Слепцова
| Соответствуют государственным требованиям к минимуму содержания и уровню подготовки выпускников для специальности 230115 Программирование в компьютерных системах одобрено методическим советом техникума Протокол № от «___» _____________ 2013 г Зам. директора по учебной работе _______________ А.Н. Апполонова
|
Составитель: Новиков., преподаватель ГОУ СПО ЯО Ярославский
автомеханический техникум
© ГОУ СПО ЯО Ярославский автомеханический техникум, 2013
© А.В. Новиков
150054 г. Ярославль, ул. Автозаводская, 1-а,
тел/факс (0852) 73-28-04; Е-mail: avtomeh@bk.ru
Содержание.- Практическая работа № 12 Создание прикладного приложения под Windows..………...4
- Практическая работа № 13 Создание прикладного приложения с окнами ввода данных…………………………………………………………………………………………….7
- Практическая работа № 14 Создание прикладного приложения с окнами сообщения…8
- Практическая работа № 15 Создание собственных классов и компонентов………..….10
Практическая работа № 16 Реализация прикладных вычислительных алгоритмов…...18
- Практическая работа № 17 Работа с строками и символами……………………………19
- Практическая работа № 18 Обработка табличных данных………………………...…….21
- Практическая работа № 19 Создание прикладного приложения с переключателям….22
- Практическая работа № 20 Создание прикладного приложения с ограничением по вводу данных…………………………………………………………………………………...24
- Практическая работа № 21 Создание прикладного приложения с информацией о файловой системе...……………………………………… ………………………………..…..27
- Практическая работа № 22 Создание прикладного приложения с обработкой даты и времени ……………………………………………………………………………………29
- Практическая работа № 23 Создание прикладного приложения с логическими выражениями ………………………………………………………………………………………31
- Практическая работа № 24 Создание изображений. Анимация и мультимедиа возможности ………………………………………………………………………………………..33
- Практическая работа № 25 Разработка приложения “Графический редактор” .……….35
- Практическая работа № 26 Разработка приложения “Графический редактор” ……….36
- Практическая работа № 27 Управление приложениями……………………….….…….38
- Практическая работа № 28 Вызов внешних приложений. …………..…….…………….40
- Практическая работа № 29 Многодокументные приложения. ………………………….42
Практическая работа № 30 Консольные приложения……………………………………44
Практическая работа № 31 Создание прикладного приложения с элементами интерфейса…………………………………………………………………………………………46
Практическая работа № 32 Создание прикладного приложения с отсчетом времени и линейками прокрутки………………………………………………………………………51
Практическая работа № 33 Создание прикладного приложения с панелями инструментов и строки состояния…………………………………………………………………….53
Практическая работа № 34 Разработка приложения “Текстовый редактор”…………..57
Практическая работа № 35 Разработка приложения “Текстовый редактор”…………..59
Тема: Создание прикладного приложения под Windows
Цель работы: Изучение основных принципов создания приложения с помощью стандартных компонентов, использование стандартных свойств компонетов.
Программное обеспечение: Borland Delphi 7
Задание: Разработка прикладного приложения “Светофор”
Когда указатель мыши наведен на лампочку, она меняет свой цвет.
Для выхода из программы необходимо щелкнуть мышью на закрывающей кнопке в строке заголовка.
Описание плана разработки программы
1. Открыть новый проект.
2. Разместить на форме экземпляры компонентов: фигура Shape.
3. Выполнить следующие действия:
Таблица
Выделенный объект | Вкладка окна Object Inspector | Имя свойства/ имя события | Действие |
Form1 | Properties | Caption | Установка имени формы "Светофор" |
Height | Присвоить значение 300 | ||
Width | Присвоить значение 120 | ||
BorderIcons (Служебные кнопки) | Выбрать для подсвойства biMinimize (Сворачивание) и biMaximize (Разворачивание) значение False | ||
Color | Задать стандартный серый цвет | ||
BorderStyle (Стиль рамки) | Выбрать значение bsSingle | ||
Events | OnMouseMove | В процедуру передаются дополнительные параметры: Shift - указывает, не была ли при перемещении нажата клавиша SHIFT, CTRL или ALT; X -горизонтальная координата указателя мыши; Y -вертикальная координата указателя. |
Выделенный объект | Вкладка окна Object Inspector | Имя свойства/ имя события | Действие |
Shape1 (Вкладка Additional) | Properties | Height | Присвоить значение 6l |
Width | Присвоить значение 6l | ||
Shape (Форма) | Выбрать значение stCircle (Круг) | ||
Pen (Контур) | Выбрать для подсвойства Color (Цвет) значение clRed (красный цвет) | ||
Brush (Кисть) | Выбрать для подсвойства Style (стиль) значение bsClear (прозрачный) | ||
| Enabled (Включен) Выбрать значение False (Нет) | ||
Shape2 (Вкладка Additional) | Properties | Height Присвоить значение 6l | |
Width Присвоить значение 6l | |||
Shape Выбрать значение stCircle (Круг) | |||
| Pen | Выбрать для подсвойства Color (Цвет) значение clYellow (желтый цвет) | |
Brush | Выбрать для подсвойства Style значение bsClear | ||
Enabled (Включен) | Выбрать значение False (Нет) | ||
Shape3 (Вкладка Additional) | Properties | Height | Присвоить значение 6l |
Width | Присвоить значение 6l | ||
Shape | Выбрать значение stCircle (Круг) | ||
Pen | Выбрать для подсвойства Color (Цвет) значение clLime (ярко-зеленый цвет) | ||
Brush | Выбрать для подсвойства Style значение bsClear | ||
|
| Enabled (Включен) | Выбрать значение False (Нет) |
Написать функцию OnShape, которая вызывается из процедуры FormMouseMove.
Работа функции определяет следующие события:
Если указатель мыши не наведен на лампочку, то ее цвет будет прозрачным.
Если указатель мыши наведен на лампочку, то ее цвет будет соответствовать цветам светофора. r := sh.Width div 2; {r - радиус фигуры} cx := sh.Left + r; {cx, cy - координаты центра фигуры} cy := sh.Top + r;
d2 := (X - cx) * (X - cx) + (Y - cy) * (Y - cy); {d2 - квадрат расстояния от центра} OnShape := bsClear; {указатель мыши не наведен на лампочку, т.е. находиться за пределами фигуры}
if d2 r*r then ObShape := bsSolid; {указатель мыши наведен на лампочку, т.е.
находиться внутри фигуры}
Выравнивание элементов:
1) Выделить все три фигуры.
2) Выбрать команду Edit — Align (Правка — Выровнить).
3) Откроется диалоговое окно Alignment (Выравнивание).
4) Установить слева переключатель Center in Window (Центрировать в окне).
5) Установить справа переключатель Space Equally (С равными промежутками).
6) Щелкнуть на кнопке OK.
Сохраните проект, запустите и протестируйте его.
Листинг подпрограммы
Function OnShape (sh: TShape: X, Y: Integer): TBrushStyle; var r, cx, cy, d2: Integer; begin
r := sh.Width div 2; cx := sh.Left + r; cy := sh.Top + r;
d2 := (X - cx) * (X - cx) + (Y - cy) * (Y - cy); OnShape := bsClear; if d2 r*r then ObShape := bsSolid; end;
procedure TForm1.FormMouseMove (Sender: TObject, Shift: TShiftState; X, Y: Integer);); begin
Shape1.Brush.Color := clRed; Shape1.Brush.Style := OnShape (Shape1, X, Y); Shape2.Brush.Color := clYellow; Shape2.Brush.Style := OnShape (Shape2, X, Y); Shape3.Brush.Color := clLime; Shape.Brush.Style := OnShape (Shape3, X, Y);
end;
Показать результат преподавателю
Тема: Создание прикладного приложения с окнами ввода данных
Цель работы: Изучить работу компонента окна ввода данных Edit.
Программное обеспечение: Borland Delphi 7
Задача:
Ход выполнения
Откройте Delphi 7. Путь: С:/Program Files/Borland/Delphi7/Bin/delphi32.exe
Создайте на созданной форме компоненты:
Button1 - кнопка расчета задачи, Button2 – очистка всех элементов ввода и вывода, Button3 – выход из программы.
Edit1 – начальное значение в диапазоне чисел x.
Edit2 - конечное значение в диапазоне чисел x.
Edit3 - шаг в диапазоне чисел.
Memo1 - компонент вывода значений P и X
Lаbel N –метки
Составьте математическую модель решения задачи
Составьте блок-схему по данной задачи
В кнопке Button1 напишите код программы, который будет решать данную задачу. Примечание: Ввод значений в Edit осуществляется по следующей структуре:
переменная:=Strtofloat(EditN.Text);
Вывод элементов в Memo осуществляется следующим действием для действительных чисел:
memoN.Lines.Add(FloattoStrf(,fffixed,8,2)+#9+FloattoStrf((,fffixed,8,4));
В кнопке Button2 пишется код очистки, используя свойство компонента Clear.
В кнопке Button3 пишется код закрытия программы.
При успешном запуске программы, покажите код программы и ее работоспособность преподавателю.
Записать код программы в тетрадь.
Тема: Создание прикладного приложения с окнами сообщения
Цель работы: Изучить работу функции MessageDLG.Научиться создавать простые диалоговые окна.
Программное обеспечение: Borland Delphi 7
Давайте рассмотрим процедуру и пару функций Delphi для создания простых диалоговых окон вывода сообщений.
Это процедура ShowMessage, функции MessageDlgPos и MessageDlg, они показывают панель (окно) вывода сообщений.
ShowMessage(const Msg: String) - эта процедура выводит окно с сообщением и кнопкой Ok. В заголовке содержится название исполняемого файла, если в опциях приложения не задан параметр Title, если задан то выводиться будет он. Строка Msg - будет выводиться как текст сообщения.
MessageDlg(const Msg: String; AType: TMsgDlgType; Abuttons: TMsgButtons; HelpCtx: Longint): Word - функция показывающая диалоговое окно сообщения в центре экрана и дает возможность пользователю ответить на сообщение. Msg - параметр отвечающий за выводимый текст сообщения.
Тип выводимого окна сообщения зависит от параметра AType, список возможных значений которого следующий:
mtErrore - на фоне красного круга расположен белый косой крест и заголовок окна - Error;
mtWarning - на фоне желтого треугольника расположен черный восклицательный знак -"!" и заголовок окна - Warning;
mtConfirmation на фоне белого круга расположен синий знак "?" и заголовок окна - Confimation;
mtInformation - на фоне белого круга расположена синия буква "i" и заголовок окна - Information;
mtCustom - диалоговое окно не содержит рисунка, в заголовке выводиться имя исполняемого файла приложения или Title свойства Application приложения.
AButtons - параметр, который задает набор кнопок на диалоговой форме и может принимать произвольные комбинации из значений:
кнопка Yes - mbYes,
кнопка Ok - mbOk,
кнопка No - mbNo,
кнопка Cancel - mbCancel,
кнопка Abort - mbAbort,
кнопка Retry - mbRetry,
кнопка Ignore - mbIgnore,
кнопка All - mbAll,
кнопка Help - mbHelp.
Список из необходимых, перечисленных кнопок должен быть заключен в квадратные скобки.
MessageDlg('Большое значение', mtConfirmation, [mbYes,mbNo],0 );
Кроме перечисления отдельных кнопок, есть возможность задать часто используемым сочетаниям кнопок значениями специальных констант:
кнопки OK и Cancel - mbOkCancel,
кнопки Yes, No и Cancel - mbYesNoCancel,
кнопки Abort, Retry и Ignore - mbAbortRetryIgnore.
Эти константы не надо брать в скобки, так как они являются предопределенными множествами.
Если мы внутри скобок не объявим список, то в диалоговом окне не будет ни одной кнопки и пользователю придется закрывать окно системными кнопками Windows.
MessageDlg('Большое значение', mtConfirmation,mbAbortRetryIgnore,0 );
При щелчке на любой кнопке (кроме Help) результат возвращается функцией MessageDlg (свойство ModalResult), а сама форма закрывается. Результат может быть одним из значений списка:
mrOk mrRetry mrNo
mrNone mrAbort mrYes
mrCancel mrIgnore mrAll
Параметр HelpCtx задает тему справки. Ее можно вызвать во время показа диалогового окна клавишей F1. Обычно этот параметр устанавливается равным нулю и справка не выводиться.
Данная функция полезна для быстрого создания приложения, но у нее есть один большой минус в надписях и заголовках на кнопках тексты английские, так что при выводе русских сообщений получается смесь русского с английским.
Задание:
Создайте простое приложение, которое вызывает диалоговое окно, состоящее из трех кнопок Yes, No, Cansel. При нажатии на Yes выдает сообщение о правильности выбора, при No выдает новое диалоговое сообщение с новым запросом, при Cancel выходит из программы.
Тема: Создание собственных классов и компонентов
Цель работы: Ознакомиться с процессом создания новых классов и компонентов в среде Borland Delphi 7
Программное обеспечение: Borland Delphi 7
Создание модуля компонента. Рекомендации по проектированию.Первым шагом, независимо от используемого метода, является создание отдельной папки для файлов компонента. Конечно, можно хранить файлы всех компонентов в одной папке, но через некоторое время она превратится просто в свалку.
Начнем с последнего способа, как наиболее часто применяемого.
Рисунок 1.
Эксперт (рисунок 1) вызывается с помощью пункта меню Component/New Component в IDE Delphi. Диалоговое окно эксперта содержит следующие поля:
Ancestor type: родительский класс создаваемого компонента. Для выбора родительского класса придерживайтесь простого правила: выбирайте существующий класс компонента, реализующий наибольшую часть требуемой функциональности.
Class Name: имя класса создаваемого компонента. Старайтесь подобрать простое и понятное имя класса, выражающее назначение компонента.
Palette Page: закладка, на которой будет установлен компонент. Можно выбрать из выпадающего списка набор существующих страниц или ввести новое наименование.
UnitFileName: имя модуля, в котором будет размещен исходный текст компонента.
Search Path: пути, в которых среда Delphi будет искать нужные ей файлы для компиляции кода компонента.
Для нашего компонента наиболее близким по функциональности является класс TLabel, он и будет родителем нашего компонента. Часто в качестве родителей следует выбирать не ближайший по функциональности компонент, а ближайший так называемый Custom-компонент. Например, непосредственным предком TLabel является TCustomLabel. Класс TCustomLabel реализует всю функциональность TLabel, однако не выносит объявление многих свойств в секцию published, потому что можно только увеличивать область видимости членов класса, но не уменьшать ее. Критерием для выбора между классом и custom-классом служит необходимость оставить скрытыми от пользователя некоторые поля компонента. Например, в TLabel свойство Align переобъявлено в секции published, тогда как в TCustomLabel оно объявляется как protected. Если не нужно давать пользователю компонента доступ к свойству Align, то в качестве предка можно выбрать класс TCustomLabel. Также заметим, что эксперт предлагает в качестве родителя два класса TLabel. Один из модуля StdCtrls, второй из QStdCtrls. Первый относится к иерархии классов VCL, второй к CLX. В примере мы рассмотрим создание VCL-компонента.
Назовем класс нашего компонента TmgCoolLabel. Размещаться он будет на закладке «Our components». Назовем модуль компонента umgCoolLabel.pas, размещаться он будет в отдельной папке, которую мы создали для него ранее.
Нажав кнопку ОК в окне эксперта, мы получим модуль со следующим текстом:
unit mgCoolLabel;
interface
uses SysUtils, Classes, Controls, StdCtrls;
type TmgCoolLabel = class(TLabel) private { Private declarations } protected { Protected declarations } public { Public declarations } published { Published declarations } end;
procedure Register;
implementation
procedure Register; begin RegisterComponents('Our components', [TmgCoolLabel]); end;
end. |
Эксперт создает синтаксически правильную заготовку компонента, т.е минимально необходимый каркас.
Можно, конечно, написать это все вручную, но радости в этом никакой.
Обратите внимание, что помимо декларации класса, модуль содержит функцию Register. Данная функция вызывается при установке компонента и указывает среде, какие компоненты и каким образом должны быть установлены.
Следующим этапом в разработке компонента является создание свойств, методов и событий. Данный этап наиболее длителен и сложен. Какие свойства, методы и события будет содержать компонент – решать вам, однако можно дать несколько общих рекомендаций.
Я в своей работе использую приведенные ниже соглашения об именовании. Это позволяет упростить поиск нужной информации и не забивать голову придумыванием названия для нового компонента. Вот краткое описание этой конвенции:
Название класса компонента желательно начинать с T, так как в этом случае Delphi при использовании компонента будет автоматически называть экземпляры, отсекая букву T. В противном случае имя экземпляра компонента будет совпадать с именем класса, и лишь цифры в конце имени экземпляра будут указывать пользователям компонента, что это экземпляр, а не класс.
Очень желательно предварять имя класса префиксом. Для компонентов в этой статье я выбрал префикс mg (мои инициалы). Класс нашего компонента будет назваться TmgCoolLabel.
Имя модуля я предваряю префиксом u (сокращение от Unit). Остальная часть имени совпадает с именем класса без буквы T. Данное требование не обязательно, однако поможет вам и вашим коллегам быстро отыскать, в каком модуле объявлен компонент, и не вызовет при этом путаницы.
Вы даже представить себе не можете, каким образом могут использоваться ваши компоненты. Поэтому стоит минимизировать предварительные условия использования компонента. Ниже перечислены соответствующие рекомендации.
Не принуждайте пользователя выполнять какие-либо дополнительные действия после вызова конструктора компонента. Если пользователь должен будет вызывать какие-либо методы после создания компонента, чтобы привести его в работоспособное состояние, то велика вероятность, что он просто откажется от использования такого компонента.
Старайтесь не делать предположений о порядке вызова методов объекта или установки значений свойств. Избегайте создания методов, способных перевести компонент в нерабочее состояние.
Объявляете методы в секции public только если они выполняют действия, которые полезны пользователям компонента. Все методы, осуществляющие «внутреннюю» работу, прячьте в секциях protected и private.
Не стесняйтесь объявлять свойства. Свойства – основа быстрой и удобной настройки вашего компонента.
События OnChange, Before и After придают компоненту дополнительную гибкость.
Код компонентаПоскольку наш компонент лишь незначительно отличается от предка, нам не придется писать много кода. Достаточно лишь переопределить конструктор компонента, чтобы изменить начальные его настройки и переобъявить свойства ширины и высоты с новыми значениями директивы default.
unit mgCoolLabel;
interface
uses SysUtils, Classes, Controls, StdCtrls;
type TmgCoolLabel = class(TLabel) private { Private declarations } protected { Protected declarations } public { Public declarations } constructor Create(AOwner:TComponent);override; published { Published declarations } property Height default 30; property Width default 85; end;
procedure Register;
implementation
uses Graphics;
procedure Register; begin RegisterComponents('Our components', [TmgCoolLabel]); end;
{ TmgCoolLabel }
constructor TmgCoolLabel.Create(AOwner: TComponent); begin inherited Create(AOwner); AutoSize:=false; Height:=30; Width:=120; Font.Color:=clBlue; Font.Style:=[fsBold]; Font.Height:=16; Font.Size:=12; end;
end. |
Главная работа по установке новых начальных значений свойств выполняется в конструкторе Create. Переопределение свойств Height и Width необязательно, но очень желательно. Если этого не сделать, значения по умолчанию для данных свойств будут записываться в файл формы, что будет замедлять загрузку формы.
Сохранение состояния компонентовВсе начинается с того, что IDE Delphi вызывает метод WriteComponentResFile. Метод объявлен следующим образом:
procedure WriteComponentResFile(const FileName: string; Instance: TComponent); |
Первый параметр – имя файла, в который нужно сохранить форму, второй - сохраняемый компонент. Код метода очень прост:
procedure WriteComponentResFile(const FileName: string; Instance: TComponent); var Stream: TStream; begin Stream := TFileStream.Create(FileName, fmCreate); try Stream.WriteComponentRes(Instance.ClassName, Instance); finally Stream.Free; end; end; |
Метод создает файловый поток (TFileStream) и вызывает его метод WriteComponentRes. Метод WriteComponentRes всего лишь вызывает WriteDescendentRes(ResName, Instance, nil). WriteDescendentRes формирует заголовок ресурса компонента и вызывает метод WriteDescendent, который и отвечает за запись свойств компонента в поток.
Код метода WriteDescendent так же прозрачен:
procedure TStream.WriteDescendent(Instance, Ancestor: TComponent); var Writer: TWriter; begin Writer := TWriter.Create(Self, 4096); try Writer.WriteDescendent(Instance, Ancestor); finally Writer.Free; end; end; |
Как видим, создается объект TWriter и вызывается его метод WriteDescendent. Таким образом, основная часть работы по сохранению свойств лежит на объекте TWriter.
Класс TWriter извлекает информацию о свойствах записываемого в поток объекта. Данный класс является наследником абстрактного класса TFiler – базового класса, используемого для записи или чтения информации о свойствах компонента в/из потока.
Рассмотрим класс TFiler более подробно. Задачей этого класса является обеспечение не только записи свойств самого компонента, но и всех компонентов, принадлежащих ему. Класс TFiler является абстрактным, то есть содержит лишь объявления методов и свойств, необходимых для выполнения поставленных задач.
Декларация класса выглядит следующим образом:
TFiler = class(TObject) private FStream: TStream; FBuffer: Pointer; FBufSize: Integer; FBufPos: Integer; FBufEnd: Integer; FRoot: TComponent; FLookupRoot: TComponent; FAncestor: TPersistent; FIgnoreChildren: Boolean; protected procedure SetRoot(Value: TComponent); virtual; public constructor Create(Stream: TStream; BufSize: Integer); destructor Destroy; override; procedure DefineProperty(const Name: string; ReadData: TReaderProc; WriteData: TWriterProc; HasData: Boolean); virtual; abstract; procedure DefineBinaryProperty(const Name: string; ReadData, WriteData: TStreamProc; HasData: Boolean); virtual; abstract; procedure FlushBuffer; virtual; abstract; property Root: TComponent read FRoot write SetRoot; property LookupRoot: TComponent read FLookupRoot; property Ancestor: TPersistent read FAncestor write FAncestor; property IgnoreChildren: Boolean read FIgnoreChildren write FIgnoreChildren; end; |
Свойство Root содержит указатель на компонент, со свойствами которого мы работаем.
Свойство Ancestor позволяет определить, значения каких свойств должны быть записаны в поток. Дело в том, что необходимо сохранить лишь те свойства, значения которых отличаются от заданных по умолчанию директивой default. Если значение свойства Ancestor равно nil, записываются все свойства, в противном случае проводится анализ необходимости записи. Свойство Ancestor не равно nil лишь в случае сохранения форм, разработанных в визуальном дизайнере.
Свойство IgnoreChildren указывает, нужно ли, помимо свойств самого компонента, записывать свойства компонентов, владельцем которых он является. Если значение свойства равно True, "дети" данного компонента не записываются.
Свойство LookupRoot указывает на локальный корневой (записываемый/считываемый) компонент. Свойство доступно только для чтения и используется для разрешения имен вложенных фреймов. При сохранении или чтении вложенных во фрейм компонентов указывает на этот фрейм.
Метод FlushBuffer - абстрактный метод синхронизации с потоком, содержащим данные компонента.
DefineProperty – метод для чтения/записи значения свойства. Устанавливает указатели на методы чтения и записи свойства с именем, указанным в первом параметре.
DefineBinaryProperty – метод чтения/записи бинарных данных как значений свойства. Устанавливает указатели на методы чтения и записи свойства с именем, указанным в первом параметре.
Класс TFiler имеет двух наследников TWriter и TReader. TWriter отвечает за запись значений свойств, а TReader за чтение.
Наследники добавляют методы чтения и записи различных типов данных.
Загрузка значений свойств происходит аналогично процессу записи. При этом средой Delphi вызывается метод ReadComponentResFile, и создается объект TReader.
Данный механизм применяется при сохранении свойств в файлы формата ресурсов Windows. Последние версии Delphi (6, 7) по умолчанию сохраняют свойства в файлах текстового формата. Преобразования из одного формата в другой можно выполнить глобальными методами ObjectBinaryToText и ObjectTextToBinary.
По умолчанию свойства компонентов, агрегируемые компонентом, не сохраняются. Для изменения такого поведения необходимо вызвать SetSubComponent с параметром True.
Механизм одинаково работает и для VCL, и для CLX.
Теперь, описав общий механизм записи/чтения свойств можно перейти к примерам его использования.
Загрузка формы в run-timeОдним из интересных методов использования механизма загрузки/чтения свойств является загрузка формы из файла dfm в ходе выполнения программы. Так как в последних версиях Dephi по умолчанию используется текстовый формат хранения свойств формы (второй способ - это хранение в формате ресурсов Windows), то появляется возможность изменять вид формы без перекомпиляции программы.
Создадим новый проект с помощью пункта меню File/New Applcation. На главной форме приложения разместим две кнопки и диалог открытия файла. Установим свойство Caption кнопки Button1 равным LoadForm, а Button2 - SaveForm. Внешний вид формы приведен на рисунке 3.
Рисунок 3.
Ниже приведен текст модуля главной формы.
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; OpenDialog1: TOpenDialog; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } procedure ReadFormProperties(DfmName:String; Form:TComponent); procedure WriteFormProperties(DfmName: String; Form: TComponent); public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var RunTimeForm:TForm; begin RunTimeForm:=TForm1.CreateNew(Self); with RunTimeForm do try if OpenDialog1.Execute then begin ReadFormProperties(OpenDialog1.FileName, RunTimeForm); ShowModal; end; finally RunTimeForm.Free; end; end; procedure TForm1.ReadFormProperties(DfmName: String; Form: TComponent); var FileStream:TFileStream; BinStream: TMemoryStream; begin FileStream := TFileStream.Create(DfmName, fmOpenRead); try BinStream := TMemoryStream.Create; try ObjectTextToBinary(FileStream, BinStream); BinStream.Seek(0, soFromBeginning); BinStream.ReadComponent(Form); finally BinStream.Free; end; finally FileStream.Free; end; end; procedure TForm1.WriteFormProperties(DfmName: String; Form: TComponent); var BinStream:TMemoryStream; FileStream: TFileStream; begin BinStream := TMemoryStream.Create; try FileStream := TFileStream.Create(DfmName, fmOpenWrite or fmCreate); try BinStream.WriteComponent(Form); BinStream.Seek(0, soFromBeginning); ObjectBinaryToText(BinStream, FileStream); finally FileStream.Free; end; finally BinStream.Free end; end; procedure TForm1.Button2Click(Sender: TObject); begin if OpenDialog1.Execute then begin WriteFormProperties(OpenDialog1.FileName, Self); ShowModal; end; end;
end. |
Основную работу по загрузке формы выполняет метод ReadFormProperties, а по записи WriteFormProperties. Оба метода осуществляют конвертацию между двоичным и текстовым представлением свойств формы, используя для этого два потока и вызовы ObjectBinaryToText и ObjectTextToBinary.
Запустим приложение. При нажатии на кнопку LoadForm создается второй экземпляр главной формы приложения. Отредактировав во время выполнения программы файл формы (Unit1.dfm) в текстовом редакторе, и снова нажав кнопку LoadForm, можно убедиться, что сделанные изменения отражаются на внешнем виде формы. Нажатие кнопки SaveForm записывает форму в указанный файл.
ЗАДАНИЯ К ПРАКТИЧЕСКОЙ РАБОТЕ №16Тема: Реализация прикладных вычислительных алгоритмов
Цель работы: Отработать навыки создания проекта, формы и её объектов. Закрепить знания об вычислительных алгоритмах.
Программное обеспечение: Borland Delphi 7
Порядок выполнения задания, методические указания:
1. Создать программу для вычисления площади круга произвольного радиуса.
Ход работы:
1. Создать поля для вывода текстовой информации Label 1, Label2, поле ввода строки Editl, и кнопку Button 1.
2. В окне инспектора объектов изменить свойства элементов формы в соответствии с таблицей: Объект СвойствоИсходное значение Установленное значение
Button 1 Caption Button 1 Вычислить
Editl Text Editl
Forml Caption Forml Разработано студентом группы Ф.И.О.
Label 1 Caption Label 1 Введите радиус окружности
Label2 Caption Label2 ; ;
После создания формы необходимо написать обработчик события OnClick для кнопки Button 1.
Листинг программы:
procedure TForml.ButtonlClick(Sender: TObject);
var s, r: real;
begin
r:=StrToFloat(Editl.text) ; s:=Pi*sqr(r);
Labe12.caption:='Площадь круга '+FloatToStrF(s,ffgeneral,7,2); end;
2. Создать программу для нахождения значений функций у(х) и z(y) при заданном X.
y=ex+imx+l; z=(y-l)5; х=0,53;
Ход работы:
1. Создать поля для вывода текстовой информации Label 1, Label2, поле ввода строки Editl, и кнопку Button 1.
2. В окне инспектора объектов изменить свойства элементов формы в соответствии с таблицей:
Объект Свойство Исходное значение Установленное значение
Button Caption Button 1 Вычислить
Edit Text Editl
Form Caption Forml Разработано студентом группы Ф.И.О.
Label Caption Label 1 Введите X
Label Caption Label2
После создания формы необходимо написать обработчик события OnClick для кнопки Button 1.
Листинг программы:
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Math, StdCtrls;
procedure TForml.ButtonlClick(Sender: TObject);
var x, y, z: real;
begin
x:“StrToFloat(Editl.Text) ; у:=exp(x+sin(x))+1; z:“Power((у—1),5);
Тема: Работа с строками и символами
Цель работы: Научиться использовать компоненты ввода вывода для операций со строками и символами.
Программное обеспечение: Borland Delphi 7.0
Ход работы:
Описание плана разработки программы
1. Открыть новый проект.
2. Разместить на форме экземпляры компонентов: Edit, Label, Button.
3. Программирование кнопки “delete”. Удаление с позиции нужное нам количество символов
procedure TForm1.Button2Click(Sender: TObject);
begin
s:=Edit1.Text;
k:=StrToInt(Edit2.Text);
t:=StrToInt(Edit3.text);
Delete(s,k,t);
Edit10.Text:=s;
end;
4. Программирование кнопки “Insert”. Вставка с указанной позиции вводимую с клавиатуры строку.
procedure TForm1.Button3Click(Sender: TObject);
begin
s:=Edit1.Text; q:=StrToInt(Edit4.Text); w:=Edit5.Text; Insert(w,s,q); edit11.Text:=s;
end;
5. Программирование кнопки “Copy”. Копирование с указанной позиции нужное количество символов.
procedure TForm1.Button4Click(Sender: TObject);
begin
s:=Edit1.Text;
p:=StrToInt(Edit6.Text);
l:=StrToInt(Edit7.Text);
Copy(s,p,l);
sl:=copy(s,p,l);
Edit12.Text:=s1;
end;
6. Программирование кнопки “Pos”. Выдает номер позиции первого символа в веденной части предложения.
procedure TForm1.Button5Click(Sender: TObject);
begin
s:=Edit1.Text; r:=Edit9.Text; a:=Pos(r,s);
edit13.Text:=IntToStr(a);
end;
Программирование кнопки “Lenght”. Показывает общее количество символов в веденной строке.
procedure TForm1.Button6Click(Sender: TObject);
begin
s:=edit1.Text; b:=Length(s); edit14.Text:=IntToStr(b);
end;
8. Запрограммировать кнопки выхода и очистки всех вводимых значений.
ЗАДАНИЯ К ПРАКТИЧЕСКОЙ РАБОТЕ №18
Тема: Работа с табличными данными
Цель работы: Ознакомить с свойствами объекта StringGrid и отработать навыки работы с ним. Закрепить знания полученные на предыдущем занятии
Программное обеспечение: Borland Delphi 7
Порядок выполнения задания, методические указания:
Написать программу вычисления максимального значения массива и квадратного корня с использованием рекурсии и без.
Компоненты, используемые в программе:
1) Label1 – метка “длины масcива” 2) Label2 – вывод в метку значение макс. рекурсии
3) Label3 - вывод в метку значение макс. без рекурсии
4) Label4 - вывод в метку квадратного корня с рекурсией
5) Label5 – вывод в метку квадратного корня без рекурсии
6) Edit1 – ввод длины массива
7) Edit2 – ввод подкоренного значения
8) StringGrid1 – заполнение массива
9) Button1 – кнопка для изменения длины массива
10) Button2 – кнопка для вычисления максимального элемента в массиве
11) Button3 – кнопка для нахождения квадратного корня
12) Button4 – кнопка для закрытия программы
Приблизительная заготовка формы
Запрограммировать кнопку Button2 на вычисление максимального элемента в массиве с рекурсией и без; кнопку Button3 на вычисление квадратного корня заданного числа с рекурсией и без; Кнопку Button1 для изменения длины массива и Button4 для выхода из программы.
Для вычисления максимального элемента и квадратного корня с рекурсией и без предварительно записать в виде функций. Собственные функции и процедуры описываются в разделе Implemetation.
ЗАДАНИЯ К ПРАКТИЧЕСКОЙ РАБОТЕ №19
Тема: Создание прикладного приложения с переключателями с переключателями
Цель работы: научиться пользоваться простейшими компонентами организации переключений (TСheckBox, TRadioGroup). Написать и отладить программу разветвляющегося алгоритма.
Программное обеспечение: Borland Delphi 7
2.1. Обработка событий
Обо всех происходящих в системе событиях, таких как создание формы, нажатие кнопки мыши или клавиатуры и т.д., ядро системы Windows информирует работающие программы путем посылки соответствующих сообщений. Среда DELPHI позволяет принимать и обрабатывать большинство таких сообщений. Каждый компонент содержит относящиеся к нему обработчики сообщений на странице Events инспектора объектов.
Для создания обработчика события необходимо раскрыть список компонентов в верхней части окна инспектора объектов и выбрать необходимый компонент. Затем, на странице Events, нажатием левой клавиши мыши, выбрать обработчик и дважды щелкнуть по его левой (белой) части. В ответ DELPHI активизирует окно текста программы и покажет заготовку процедуры обработки выбранного события.
Каждый компонент имеет свой набор обработчиков событий, однако некоторые из них присуши большинству компонентов. Наиболее часто применяемые события представлены в таблице.
| |
Событие | Описание события |
OnActivate | Форма получает это событие при активации |
OnCreate | Возникает при создании формы (компонент TForm). В |
| обработчике данного события следует задавать действия, |
| которые должны происходить в момент создания формы, |
| обычно установку начальных значений в окнах формы |
OnKeyPress | Возникает при нажатии кнопки на клавиатуре. Параметр Key |
| имеет тип Char и содержит ASCII-код нажатой клавиши |
| (клавиша Enter клавиатуры имеет код #13, клавиша Esc - #27 и |
| т.д.). |
OnKeyUp | Является парным событием для OnKeyDown и возникает при |
| отпускании ранее нажатой клавиши |
OnClick | Возникает при нажатии кнопки мыши в области компонента |
OnDblClick | Возникает при двойном нажатии кнопки мыши в области |
| Компонента |
Кнопки-переключатели в Delphi
При создании программ в DELPHI для организации разветвлений часто используются компоненты в виде кнопок-переключателей . Состояние такой кнопки ( включено - выключено) визуально отражается на форме. На форме (рис.2.1) представлены кнопки-переключатели двух типов (TCheckBox, TRadioGroup ).
Компонент TCheckBox организует кнопку независимого переключателя, с помощью которой пользователь может указать свое решение типа «да/нет». В программе состояние кнопки связано со значением булевской переменной, которая проверяется с помощью оператора if.
Компонент TRadiogroup организует группу кнопок - зависимых переключателей. При нажатии одной из кнопок группы все остальные кнопки отключаются. В программу передается номер включенной кнопки (0,1,2,..), который анализируется с помощью оператора case.
Задание: ввести три числа - x, y, z. Вычислить по усмотрению f=sin(x) или f=x2, или f=ex. Найти максимальное из трех чисел: f, y ,z. Предусмотреть возможность округления результата до целого.
Создать форму, представленную на рисунке, и написать соответствующую программу.
Coздание формы
Создайте форму, такую же, как в задании, скорректировав текст надписей и положение окон TEdit.
Работа с компонентом TСheckBox
Выберите в меню компонентов Standard пиктограмму и поместите ее в нужное место формы. С помощью инспектора объектов измените заголовок (Caption) на «Округлять». В тексте программы появилась переменная CheckBox1 типа TСheckBox. Теперь в зависимости от того, нажата или нет кнопка, булевская переменная CheckBox1.Checked будет принимать значения true или false.
Работа с компонентом TRadioGroup
Выберите в меню компонентов Standard пиктограмму и поместите ее в нужное место формы. На форме появится окаймленный линией чистый прямоугольник с заголовком RadioGroup1. Замените заголовок (Caption) на «Выбор функции». Для того чтобы разместить на компоненте кнопки, необходимо свойство Columns установить равным единице (кнопки размещаются в одном столбце). Дважды щелкните по правой части свойства Items «мышью», появится строчный редактор списка заголовков кнопок. Наберите три строки с именами: в первой строке – «cos(x)»,. во второй –
«sqr(x)», в третьей – «exp(x)», нажмите ОК.
После этого на форме внутри окаймления появится три кнопки-переключателя с введенными надписями.
Обратите внимание на то, что в тексте программы появилась переменная RadioGroup1 типа TRadioGroup. Теперь при нажатии одной из кнопок группы в переменной целого типа RadioGroup1.ItemIndex будет находиться номер нажатой клавиши (отсчитывается от нуля), что используется в тексте приведенной программы.
Запрограммировать кнопку “Выполнить” на вычисление функций по выбору радиокнопок, и кнопку “Выход” на выход из программы.
ЗАДАНИЯ К ПРАКТИЧЕСКОЙ РАБОТЕ №20
Тема: Создание прикладного приложения с ограничением по вводу данных
Цель работы: Ознакомиться с классом Exception. Научится ограничивать ввод данных в зависимости от вводимых значений.
Программное обеспечение: Borland Delphi 7
Теоретическая часть
Ограничения по воду осуществляются исключениями.
Существуют динамические, локальные и синтаксические.
В Delphi для обработки динамических ошибок в выполняемый файл приложения встраиваются специальные фрагменты кода, предназначенные дл реагирования исключений. Механизмы обработки ошибок в Delphi инкапсулированы в класс Exception – базовый класс. Всего имеется сотни классов исключения:
EAbort Аварийное завершение работы без диалогового окна
EAbstractError Абстрактная ошибка метода
AssertionFailed Утверждают неудавшийся запрос
EBitsError Булев массив ошибок
ECommonCalendarError Календарная ошибка
EDateTimeError Ошибка DateTime
EMonthCalError Ошибка месяца
EConversionError Вызывается Convert
EConvertError Ошибка конвертирования объекта
EDatabaseError Ошибка базы данных
EExternal Ошибка аппаратных средств/Windows
EAccessViolation Нарушение прав доступа
EControlC Произошло аварийной завершение работы пользователем
EExternalException Другая Внутренняя ошибка
EIntError Целочисленная ошибка
EDivByZero Деление на ноль
EIntOverflow Переполнение целого числа
ERangeError Вне диапазона значений
EMathError Ошибка с плавающей запятой
EInvalidArgument Плохое значение аргумента
EInvalidOp Несоответствующая операция
EOverflow Значение слишком большое
EUnderflow Значение слишком маленькое
EZeroDivide Деление на ноль
EStackOverflow Серьёзная проблема Delphi
EHeapException Проблемы динамической памяти
EInvalidPointer Плохой указатель памяти
EOutOfMemory Нет возможности распределить память
EInOutError Ошибка ввода/вывода
EInvalidCast Ошибка произведенная объектом
EInvalidOperation Плохая операция компонента
EMenuError Ошибка пункта меню
EOSError Ошибка операционной системы
EParserError Ошибка синтаксического анализа
EPrinter Ошибка принтера
EPropertyError Ошибка свойства класса
EPropReadOnly Недопустимое обращение к свойству
EPropWriteOnly Недопустимое обращение к свойству
EThread Ошибка потока
EVariantError Различная ошибка
Локальные
Конструкция try … finally состоит из двух блоков и следующую форму:
try
// инструкции, выполнение которых может вызвать ошибку
finally
// инструкции, которые должны быть выполнены даже в случае ошибки
end;
Данная конструкция применяется для выполнения всех необходимых действий перед передачей управления на следующий уровень обработки ошибки или глобальному обработчику. Такими действиями могут быть, например, освобождение оперативной памяти или закрытие файла. Эта конструкция не обрабатывает объект-исключение и не удаляет его, а выполняет действия, которые должны быть произведены даже в случае возникновения ошибки.
Конструкция работает следующим образом: если в любой из инструкций блока try возникает исключение, то управление передается первой инструкции блока finally. Если же исключение не возникло, то последовательно выполняются все инструкции обоих блоков.
Конструкции try … except также состоит из двух блоков и имеет следующую форму:
try
// инструкции, выполнение которых может вызвать ошибку
except
// инструкции, которые должны быть выполнены в случае ошибки
end;
В отличие от предыдущей инструкции, данная инструкции предназначена для перехвата исключения и предоставляет возможность его обработки.
Конструкция работает следующим образом: если в инструкциях блока try возникает исключение, то управление передается первой инструкции блока except. Если же исключение не возникло, то инструкции блока except не выполняются.
Пример кода : Версия 1: Деление на ноль с предложением finally |
var |
Числу не было присвоено значение - использование значения по умолчанию
|
Пример кода : Версия 2: Деление на ноль с простым блоком Except |
var |
Неизвестная ошибка |
При необходимости исключение можно сгенерировать программно. Для этого используется инструкция raise, которая создает объект-исключение – экземпляр класса Exception. Инструкция raise имеет следующий синтаксис:
Raise ClassException.Method;
ClassException является классом исключения, на основе которого создается объект-исключение, а конструктор Method выполняет создание объекта-исключения, а для создания объектов-исключений чаще всего используются методы Create и CreateFmt классов исключений.
ПРИМЕР:
if Length(Edit1.Text)5 then
Raise Exception.Create('слишком длинная строка');
Задание: Для данной программы написать ограничение по вводу только
procedure TForm1.Button1Click(Sender: TObject);
begin
if InputBox('Загадка','Сидит дед, в сто шуб одет. Кто его раздевает - тот слёзы проливает. Кто это?','') = 'лук' then
MessageDlg('Правильно!',mtInformation,[mbOk],0)
else
MessageDlg('Вы не угадали.',mtWarning,[mbOk],0)
end;
ЗАДАНИЯ К ПРАКТИЧЕСКОЙ РАБОТЕ №21
Тема: Создание прикладного приложения с информацией о файловой системе
Цель работы: Ознакомиться с классом TMemoryStatus. Научится выводить информацию о файловой системе на экран..
Программное обеспечение: Borland Delphi 7
Класс TMemoryStatus – класс, который включает в себя набор методов в виде констант, предназначенных для использования отображения информации о системе по категориям.
Для того , чтобы задать переменную, ее необходимо внести в глобальные переменные в области переменных var. var MemoryStatus: TMemoryStatus;
Основные Методы:
dwMemoryLoad –использование памяти
dwTotalPhys - Всего физической памяти (в байтах)
dwAvailPhys - Доступно физической памяти (в байтах)
IntToStr(dwTotalPageFile - Всего виртуальной памяти (в байтах)
dwAvailPageFile - Доступно виртуальной памяти (в байтах)
dwTotalVirtual - Доступно байт виртуального адресного пространства текущего процесса
Общая конструкция вывода информации в многострочный редактор Memo:
MemoryStatus .MemoN.Lines.Add(IntToStr(константа-функция));
Для того, чтобы не прописывать переменную MemoryStatus ддля каждого значения в информационном листе можно записать код с помощью конструкции
with MemoryStatus
do
begin
MemoN.Lines.Add(IntToStr(dwMemoryLoad) + ‘обозначение в текстовой форме’) ;
Установка размеров констант осуществляется следующим способом:
MemoryStatus.dwLength := SizeOf(MemoryStatus);
Для загрузки методов используем API функция GlobalMemoryStatus.
Обращение: GlobalMemoryStatus(MemoryStatus) ;
Пример на Delphi быстро и без использования компонентов узнать информацию о системе. Для начала создадим новую форму и разместим на ней: компонент Button (кнопка) и компонент Memo (многострочный редактор) оба с закладки Standart. После чего в обработчик кнопки вставляем следующий код:
Пример 1.
procedure TForm1.Button1Click(Sender: TObject);
var MemoryStatus: TMemoryStatus;
begin
Memo1.Lines.Clear;
MemoryStatus.dwLength := SizeOf(MemoryStatus) ;
GlobalMemoryStatus(MemoryStatus) ;
with MemoryStatus
do
begin
Memo1.Lines.Add(IntToStr(dwMemoryLoad) + '% использованно памяти') ;
Memo1.Lines.Add(IntToStr(dwTotalPhys) +' Всего физической памяти (в байтах)')) ;
Memo1.Lines.Add(IntToStr(dwAvailPhys) +' Доступно физической памяти (в байтах)')) ;
Memo1.Lines.Add(IntToStr(dwTotalPageFile) +' Всего виртуальной памяти (в байтах)')) ;
Memo1.Lines.Add(IntToStr(dwAvailPageFile) +' Доступно виртуальной памяти (в байтах) ')) ;
Memo1.Lines.Add(IntToStr(dwTotalVirtual) +' Адресное виртуальное простанство текущего процесса')) ;
Memo1.Lines.Add(IntToStr(dwAvailVirtual) +' Доступно байт виртуального адресного пространства текущего процесса')) ;
end;
end;
Пример 2.
С помощью TMemoryStatus выводим ифомацию в Label:
|
|
ЗАДАНИЯ К ПРАКТИЧЕСКОЙ РАБОТЕ №22
Тема: Создание приложения с обработкой даты и время
Цель работы: Ознакомиться с классом TDateTime. Научится использовать фунции перевода из целочисленного в дату и время.
Программное обеспечение: Borland Delphi 7
type TDateTime = type Double;
Описание
Тип TDateTime содержит значение даты и времени.
Она сохраняется как переменная Double, с датой как целая часть, а время как дробная. Дата сохраняется как число дней с 30 декабря 1899. Не понятно, почему не 31 декабря. 01 января 1900 имеет значение 2.
Поскольку TDateTime фактически является Double, то вы можете выполнять над ним вычисления, как будто это было число. Это очень полезно для вычислений типа разницы между двумя датами.
Похожие команды
DateTimeToFileDate Преобразует значение TDateTime в формат date/time формат файла. Функция DateTimeToFileDate преобразут величину TDateTime в DateTime формат использующийся для файловых дат.
Файловая дата является более ограниченной в диапазоне чем TDateTime : Год должен быть в промежутке 1980 - 2099. Миллисекунды должны быть округлены до двух знаков после запятой.
DateTimeToStr Конвертирует значение даты и времени TDateTime в строку.
1 function DateTimeToStr ( DateTime : TDateTime ) : string;
2 function DateTimeToStr ( DateTime : TDateTime; const FormatSettings : TFormatSettings ) : string;
Функция DateTimeToStr конвертирует TDateTime значение DateTime в отформатированную строку даты и времени.
Строка включает:
Дата ShortDateFormat
1 пробел
Время LongTimeFormat
Форматы даты и времени также затрагивают значения TimeSeparator и DateSeparator.
Версия 2 этой функции - для использования в пределах потоков. Вы заполняете запись FormatSettings перед вызовом запроса. Она получает локальную копию глобальной переменной, которая делает вашу подпрограмму потоко безопасной.
DateTimeToString Огромные возможности форматирования даты в строку.
1 procedure DateTimeToString ( var Result : string; const Formatting : string; DateTime : TDateTime ) ;
2 procedure DateTimeToString ( var Result : string; const Formatting : string; DateTime : TDateTime; const FormatSettings : TFormatSettings ) ;
Процедура DateTimeToString позволяет форматировать дату и время, и в нужном формате даты и времени DateTime ( тип TDateTime ) переводить в строку. Т.е Delphi процедура DateTimeToString позволяет форматировать и время и дату.
Форматирование строки может включать смешивание обычных символов ( дата будет переведена в строку именно так, как укажет пользователь). Пример форматирования хорошо представлен в примере кода.
Версия 2 этой функции - для использования в пределах потоков. Вы заполняете запись FormatSettings перед вызовом запроса. Она получает локальную копию глобальной форматирующей переменной, которая делает вашу подпрограмму потоко безопасной.
PDateTime Указатель на значение TDateTime.
type PDateTime = ^TDateTime;
Тип PDateTime - указатель на значение TDateTime.
Арифметические операции над указателями, такие как Inc, Dec могут использоваться с ним, например чтобы управлять блоком TDateTime значений, как показано в примере.
StrToDateTime Конвертирует строку с датой и временем в значение типа TDateTime
Функция StrToDateTime предназначена для преобразования строки DateTime в значение типа TDateTime.
Во-первых, часть строки с датой должна соответствовать формату, заданному в переменной ShortDateFormat, и использовать символ DateSeparator (точка - разделитель) для разделения значений дня, месяца и года.
Во-вторых, часть с временем, отделенная пробелом от даты должна соответствовать формату, заданному в переменной LongTimeFormat и использовать символ TimeSeparator (точка - разделитель для разделения значений часа, минуты и секунды.
Форматом по умолчанию для Англии является день/месяц/год час:минута:секунда.мсек, где:
день должен быть в диапазоне 1..31 (зависит от месяца/года)
месяц должен быть в диапазоне 1..12
год должен быть в диапазоне 0..9999 (необязательный параметр)
час должен быть в диапазоне 0..23
минута должна быть в диапазоне 0..59 (необязательный параметр)
секунда должна быть в диапазоне 0..59 (необязательный параметр)
миллисекунда должна быть в диапазоне 0..999 (необязательный параметр)
Задание: Разработать приложение, которое по щелчку мыши в окне редактора выводит ваш возраст по введенной вашей дате рождения.
ЗАДАНИЯ К ПРАКТИЧЕСКОЙ РАБОТЕ №23
Тема: Создание прикладного приложения с логическими выражениями
Цель работы: Научится разрабатывать простые приложения с логическими выражениями на примере игры “Крестики-нолики”
Программное обеспечение: Borland Delphi 7
Задание: Создать игру крестики нолики на клетчатом поле 3 х 3.
Ход выполнения работы:
Создаем интерфейс:
В качестве полей для отображения крестика и нолика будем использовать компонент Panel. (9 штук)
Для удобства написания переименуем компоненты на p1..p9.
Форму назовем Fmain. А заголовок форме дадим «Крестики нолики».
Важные информация для создания условия выполнения:
Крестик либо нолик будут писаться в свойство caption наших панелей. Есть два нюанса: Крестик и нолик должны писаться поочередно, а при повторном нажатии на панель ничего происходить не должно. Для этого воспользуемся свойством Tag. Если у формы Tag=0 то ставится нолик и Tag меняем на 1 и Tag меняем на 0. Вторая проблема решается аналогично, если у Панели Tag=0 то нужно поставить либо 0 либо х, иначе ничего не ставим (в начале все свойства Tag должны быть 0). А победа будет проверяться просто, если в каком ни будь ряду или столбце или по диагонали одинаковые элементы, то победа соответствующего игрока.
Написание процедуры:
Собственные процедуры записываются в разделе implimentation.
Структура процедуры будет иметь вид:
procedure ;
begin
end;
Пример условия победы выглядит так:
if ((fmain.p1.Caption='x') and (fmain.p2.Caption='x') and (fmain.p3.Caption='x'))
Всего 8 условий победы. Но так как выполняется только одно условие из 8, все последующие условия прописываются через оператор or.
Если условие выполняется, тогда выводится на экран сообщение о выигрыше Крестика, а также два выражения. Вывод на панели отличительного знака (p1.Caption:='';) И задаем начальное значение “X” - fmain.p1.Tag:=0; (Прописывается для каждой панели).
После этого завершаются выборка условий по крестикам. B выполняются условия для нулика
end
else
if ((fmain.p1.Caption='o') and (fmain.p2.Caption='o') and (fmain.p3.Caption='o'))
Варианты условия прописываются по аналогичному алгоритму
И последний вариант, когда условие ничьи. Оно заключается в том, что все кнопки не будут равны одному и тому же значению, т.е. не существует равных подряд элементов. Условие кнопки будет выглядеть так (fmain.P1.Caption'').
Создание метода:
Создание метода осуществляется с помощью активации события onClick на компоненте Panel.
В теле метода записываем алгоритм условия выполнения задачи.
Свойству BevelInner компонента Panel задайте значение bvLowered. Т.е. для панели задается внутренняя фаска, которая будет выглядеть утопленной (кнопка кажется нажатой). Описать в коде программы.
Фрагмент программы будет выглядеть так:
if p1.Tag=0 then
begin
if fmain.Tag=1 then
begin
p1.Caption:='x';
fmain.Tag:=0;
end
else
begin
p1.Caption:='o';
fmain.Tag:=1;
end;
p1.Tag:=1;
end;
После описания фрагмента необходимо вызвать процедуру.
По аналогии сделайте остальные 8 кнопок.
После завершения написания кода, проверьте все ли процедуры закрыты.
Результат показать преподавателю.
ЗАДАНИЯ К ПРАКТИЧЕСКОЙ РАБОТЕ №24
Тема: Создание изображений. Анимация и мультимедиа возможности.
Цель работы: Научиться использовать свойства компонента Image, освоить использование компонента для работы с графикой и анимации.
Программное обеспечение: Borland Delphi 7
Задание: Создать несложную анимацию, по дороге будут ездить на встречу друг другу автомобиль и мотоцикл.
Используемые компоненты:
TImage (Графический холст) находится на вкладке Additional.
TTimer (Таймер) находится на вкладке System.
В папке “Picture” расположены изображения fon.bmp, avto.bmp и moto.bmp. Это наши заготовки, которые мы будем использовать в программе.
Рассмотрим 2 способа:
Первый способ
Запускаем Delphi и создаем новое приложение: File-New-VCL Forms Application – Delphi.
Помещаем на форму 3 компонента TImage. Один в один из них загружаем фон, а в два других изображение мотоцикла и автомобиля соответственно и в режиме таймера будем изменять положения компонетов TImage с изображением автомобиля и мотоцикла относительно фона.
В компонент Image1 в свойство Picture загружаем подготовленный нами файл fon.bmp, свойство Align устанавливаем alClient. А форму растянем до размеров фона.
В компонент Image2 в свойство Picture загружаем подготовленный нами файл avto.bmp и перемещаем его на дорогу.
В компонент Image3 в свойство Picture загружаем подготовленный нами файл moto.bmp и перемещаем его на дорогу.
Сравнить вашу форму с примером:
В коде программы перед разделом type добавим раздел const и объявим две константы
const
scr_width = 640; // ширина формы
scr_height = 480; // высота формы
В разделе var объявим переменные x,y,x1,y1 типа integer.
var
Form1: TForm1;
x,y,x1,y1:integer;
Создайте метод procedure TForm1.Timer1Timer и запишите его выполнение
procedure TForm1.Timer1Timer(Sender: TObject);
begin
x:=x+2;//текущая координата + шаг для автомобиля
x1:=x1-2;//текущая координата + шаг для мотоцикла
if xscr_width+image2.Width then x:=-image2.Width;// ограничение справа
if x1ограничение слева
//рисуем
image2.Left:=x;
image3.Left:=x1;
end;В свойствах таймера свойство интервал устанавливаем в пределах от 1 до 100, в зависимости от того какую скорость анимации вы хотите получить.
Второй способ
Второй способ заключается в том, что мы создаем для нашего случая 4 объекта типа TBitMap, в первый загружаем фон, во второй - автомобиль, в третий - мотоцикл, а четвертый будет буфером обмена в котором мы вначале будем формировать картинку, а потом выводить ее на экран. Это необходимо делать для того чтобы избежать мерцания картинки на экране во время движения в результате ее перерисовки. Если эффект мерцания для вас не существенен, то можно выводить изображение сразу на экран.
Помещаем на форму компонент TImage и компонент TTimer.
Для компонента Image1 свойство Align устанавливаем alClient.
А для формы свойство AutoSize устанавливаем True.Объявите константы
const
scr_width = 640; // ширина экрана
scr_height = 480; // высота экранаВ описании переменных var объявляем четыре переменных для хранения графических картинок, тип tbitmap
var
fon:tbitmap;//Графический образ Фона
avto:tbitmap;//Графический образ автомобиля
moto:tbitmap;//Графический образ мотоцикла
scr_buffer:tbitmap;//Графический образ автомобиля
x,y,x1,y1:integer;//координаты автомобиля и мотоциклаДля того чтобы вывести на экран изображения нужно :
а) Активировать созданные переменные
//создаем объекты
fon:=TBitmap.Create; // фон
moto:=TBitmap.Create;// мотоцикл
avto:=TBitmap.Create; // машина
scr_buffer:=TBitmap.Create; // буфер обмена
scr_buffer.Width:=scr_width; // ширина буфера
scr_buffer.Height:=scr_height; // высота буфера
б) Загрузить изображения в эти переменные
// загружаем объекты
moto.LoadFromFile('moto.bmp'); // мотоцикл
avto.LoadFromFile('avto.bmp'); // машина
fon.LoadFromFile('fon.bmp');// фон
x:=0; //начальные координаты машины
y:=430;
x1:=500;// начальные координаты мотоцикла
y1:=380;
в) Установить прозрачный фон вокруг машины и мотоцикла
avto.transparent:=true;//задаем прозрачность
moto.transparent:=true;
г) Вывод изображения на графический холст Image
//Определение ление координат
x:=x+2;//текущая координата + шаг для автомобиля
x1:=x1-2;//текущая координата + шаг для мотоцикла
if xscr_width+avto.Width then x:=-avto.Width;// ограничение справа
if x1//рисуем
scr_buffer.Canvas.Draw(0,0,fon);//возобновление фона
scr_buffer.Canvas.Draw(x1,y1,moto);//движение мотоцикла
scr_buffer.Canvas.Draw(x,y,avto);//движение машины
form1.Canvas.Draw(0,0,scr_buffer); //копируем содержимое буфера на экран
При этом первая цифра в скобках, это координата x, а вторая цифра соответственно координата y
д) Для того , чтобы изображения стали двигаться, необходимо динамически менять координаты изображений на холсте, желательно стирая старое изображение.
Эту задачу выполняет компонент Timer.Создать метод закрытия формы и закрыть все изображения, включая буфер изображений.
Тема: Разработка приложения “Графический редактор”
Цель работы: Научится проектировать простое приложение “Графический редактор” в среде Borland Delphi 7
Программное обеспечение: Borland Delphi 7
Проектируем форму
Основным элементом на форме будет, конечно же, картинка. Есть несколько вариантов компонентов для нее. Это Image, PaintBox и другие со свойством Canvas.
Остановим свой выбор на PaintBox"е.
Так же нужно не забывать, что картинка может быть больше, чем размеры формы. Для решения этой проблемы, используем ScrollBox.
Для панели инструментов выберем нижнюю часть окна - установим Panel.
Кнопки на панели - SpeedButton.
1. Устанавливаем Panel, свойства Align=alBottom, Height=65.
2. На панель ставим 5 штук SpeedButton. У всех свойство GroupIndex=1 или другому числу. Главное, чтоб было одинаково. Одной из кнопок назначим Down=True
3. 2 штуки ColorBox на панель инструментов, в свойстве Style - cbPrettyNames=True. Второму присвоим Selected=clWhite.
4. Подпишем их "Цвет" и "Фон" соответственно с помощью Label.
5. Устанавливаем на форму ScrollBox, ставим у него свойство Align=alClient.
6. Внутрь ScrollBox ставим PaintBox. Ставим свойства Top=0 и Left=0, Align=alNone.
7. Также сделаем меню. Поставим MainMenu, сделаем в нем 1 меню - "Файл" с пунктами: Открыть, Сохранить, Выход.
Тема: Разработка приложения “Графический редактор”
Цель работы: Научится разрабатывать простое приложение “Графический редактор” в среде Borland Delphi 7
Программное обеспечение: Borland Delphi 7
Программирование
Форму мы спроектировали. Теперь можно начать писать непосредственно программу.
Рисовать мы будем не на холсте PaintBox"a, как можно подумать сначала, а в памяти. На холст будем выводить лишь результат работы.
Для этого объявим глобальные переменные:
img, buffer: TBitmap;
x0,y0: integer;
Также объявим переменную dwn: boolean, которая будет говорить нажата левая кнопка или нет (рисовать или нет).
Объявим тип TShape = (sPen, sRect, sEllipse, sPoly, sFill).
И глобальную переменную nowdrawing: TShape. В ней будет хранится тип фигуры, которую мы рисуем.
В событии формы OnCreate напишем:
Img:=TBitmap.Create;
buffer:=TBitmap.Create;
img.Width:=PaintBox1.ClientWidth;
buffer.Width:=PaintBox1.ClientWidth;
img.Height:=PaintBox1.ClientHeight;
buffer.Height:=PaintBox1.ClientHeight;
nowdrawing:=sPen;
dwn:=false;
В событии OnMouseDown PaintBox"a проверяем, нажата ли левая кнопка. Если да, то устанавливаем значениеnowdrawing"a в нужное, а также сохраняем текущую картинку и начальные координаты мыши. Если это заливка, то нам не нужно учитывать движение мыши, нам достаточно одного нажатия. Поэтому, если заливка, то снимаем флагdwn, чтоб не реагировать на движения.
Если мы рисуем ломаную линию, то реагировать нужно и на правую кнопку: для создания нового узла. Т.е. для рисования ломанной нужно держать левую кнопку нажатой, а для создания узлов кликать правую кнопку.
Если нажата не левая кнопка, то начальные координаты просто переписываем (x0,y0).
if button=mbLeft then begin
img.assign(buffer);
x0:=x; y0:=y;
if SpeedButton1.Down then
begin
nowdrawing:=sPen;
img.canvas.MoveTo(x,y);
end else
if SpeedButton2.Down then
nowdrawing:=sEllipse else
if SpeedButton3.Down then
nowdrawing:=sRect else
if SpeedButton4.Down then
nowdrawing:=sPoly else
if SpeedButton5.Down then
nowdrawing:=sFill;
dwn:=true;
img.Canvas.Pen.Color:=ColorBox1.Selected;
img.Canvas.Brush.Color:=ColorBox2.Selected;
if nowdrawing=sFill then
begin
img.Canvas.FloodFill(x0,y0,img.Canvas.Pixels[x,y],fsSurface);
buffer.Assign(img);
dwn:=false;
end
end else
begin
if (dwn)and(nowdrawing=sPoly) then begin
x0:=x;
y0:=y;
buffer.Assign(img);
end;
end;
paintbox1.Canvas.CopyRect(bounds(0,0,img.Width,img.Height),
img.Canvas,bounds(0,0,img.Width,img.Height));
В событии OnMouseMove самое интересное: если флаг dwn не включен, то выходим сразу же из процедуры.
Восстанавливаем старый холст и по выбору рисуемой фигуры в nowdrawing соответственно рисуем линию, прямоугольник, эллипс или отрезок - часть ломаной на картинке img. В конце рисования, переносим его на холст PaintBox"a.
if not dwn then exit;
img.assign(buffer);
case nowdrawing of
sPen:begin
img.Canvas.LineTo(x,y);
buffer.Assign(img);
end;
sRect:begin
img.Canvas.Rectangle(x0,y0,x,y);
end;
sEllipse:begin
img.Canvas.Ellipse(x0,y0,x,y);
end;
sPoly:begin
img.Canvas.MoveTo(x0,y0);
img.Canvas.LineTo(x,y);
end;
sFill:begin
//nothing.
end;
end;
paintbox1.Canvas.CopyRect(bounds(0,0,img.Width,img.Height),
img.Canvas,bounds(0,0,img.Width,img.Height));
В событии OnMouseUp:
if button=mbLeft then dwn:=false;
buffer.Assign(img);
В событии OnPaint PaintBox"a напишем прорисовку картинки из буфера:
paintbox1.Canvas.CopyRect(bounds(0,0,img.Width,img.Height),
buffer.Canvas,bounds(0,0,img.Width,img.Height));
Тема: Управление приложениями
Цель работы: Рассмотреть управление приложениями на примере управления раскладкой клавиатуры в активном окне и в самой программе.
Программное обеспечение: Borland Delphi 7
Нашей задачей создать процедуры и функции для управления раскладкой клавиатуры. Сначала обозначим их и установим для них параметры:
function NameKeyboardLayout(layout : LongWord) : string; - Получает название раскладки из списка. Имеет строковый тип. Создает массив и записывает в него список названий раскладки.
function GetActiveKbdLayout : LongWord; - Получает раскладку в своей программе
function GetActiveKbdLayoutWnd : LongWord; - Получает раскладку в активном окне
procedure SetKbdLayout(kbLayout : LongWord); - Устанавливает раскладку в своей программе
procedure SetLayoutActiveWnd(kbLayout : LongWord); - Устанавливает раскладку в активном окне.
Тип LongWord является целочисленным, то есть это некое число (порядок) раскладки, которое вызывается в зависимости от назначения функции или процедуры.
Ход работы:
Откройте Delphi 7.0 (Пуск - Программы - Borland - Delphi 7.0)
На форме расположите следующие компоненты:
Button1 – кнопка для выполнения активации активной раскладки в активном окне
Button2 – кнопка для установки раскладки в активном окне
Button3 – кнопка для выполнения активации активной раскладки в своей программе
Button2 – кнопка для установки раскладки в свой программе
Label1 – поле для отображения активной раскладки в активном окне
Label2 – поле для отображения активной раскладки в своей программе
Нажмите F12 для перехода к коду программы.
Опишем типы:
const
CNT_LAYOUT = 2; // количество известных раскладок
ENGLISH = $409;
RUSSIAN = $419;
TKbdValue : array [1..CNT_LAYOUT] of LongWord =
( ENGLISH,
RUSSIAN
);
TKbdDisplayNames : array [1..CNT_LAYOUT] of string =
('English',
'Русский'
);
Далее в разделе implementation описываем наши функции и процедуры.
Сначала запишем процедуру получения раскладки
function NameKeyboardLayout(layout : LongWord) : string;
var
i: integer;
begin
Result:='';
try
for i:=1 to CNT_LAYOUT do
if TKbdValue[i]=layout then Result:= TKbdDisplayNames[i];
except
Result:='';
end;
end;
Функция установки активной раскладки в своей программе.
function GetActiveKbdLayout : LongWord;
begin
result:= GetKeyboardLayout(0) shr $10;
end;
Функция установки активной раскладки в активном окне.
function GetActiveKbdLayoutWnd : LongWord;
var
hWindow,idProcess : THandle;
begin
// получить handle активного окна чужой программы
hWindow := GetForegroundWindow;
// Получить идентификатор чужого процесса
idProcess := GetWindowThreadProcessId(hWindow,nil);
// Получить текущую раскладку в чужой программе
Result:=(GetKeyboardLayout(idProcess) shr $10);
end;
Процедура установки раскладки в свою программу
procedure SetKbdLayout(kbLayout : LongWord);
var
Layout: HKL;
begin
// Получить ссылку на раскладку
Layout:=LoadKeyboardLayout(PChar(IntToStr(kbLayout)), 0);
// Переключить раскладку на русскую
ActivateKeyboardLayout(Layout,KLF_ACTIVATE);
end;
Процедура установки раскладки в активное окно
procedure SetLayoutActiveWnd(kbLayout : LongWord);
var
Layout: HKL;
hWindow{, idProcess} : THandle; // ION T: не используется
begin
// получить handle активного окна чужой программы
hWindow := GetForegroundWindow;
// Получить ссылку на раскладку
Layout:=LoadKeyboardLayout(PChar(IntToStr(kbLayout)), 0);
// посылаем сообщение о смене раскладки
sendMessage(hWindow,WM_INPUTLANGCHANGEREQUEST,1,Layout);
end;
Далее запрограммируйте кнопки на действие по щелчку, вызвав в каждой кнопке соответсвующую ей функцию или процедуру.
{активная раскладка в активном окне}
Label1.Caption:= NameKeyboardLayout(GetActiveKbdLayoutWnd);
{активная раскладка в своей программе}
Label2.Caption:= NameKeyboardLayout(GetActiveKbdLayout);
{установить раскладку в своей программе}
SetKbdLayout(ENGLISH);
{установить раскладку в активном окне}
SetLayoutActiveWnd(ENGLISH);
Покажите результат преподавателю
Тема: Вызов других приложений
Цель работы: Рассмотреть и изучить принципы запуска другого приложения из своей программы с ожиданием его завершения.
Программное обеспечение: Borland Delphi 7
Ход работы:
Откройте Delphi 7.0 (Пуск - Программы - Borland - Delphi 7.0)
На форме расположите следующие компоненты:
Button1 – кнопка для вызова приложения калькулятор
В разделе implementation опишите следующую функцию:
Опишите функцию вызова приложения и задайте параметры названия файла, установка пробелов и вид окна. Результат функции будет иметь логический тип.
function ExecAndWait(const FileName, Params: ShortString;const WinState: Word): boolean;
export;
В разделе описания переменных задайте параметры информации о запуске, информация о процессе и установка строки имени приложения
var
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
CmdLine: ShortString;
После открытия тела функции помещаем имя файла между кавычками, с соблюдением всех пробелов в именах Win9x и устанавливаем активность окон, получаем информации о запуске и запускаем сам процесс
begin
CmdLine := '"' + Filename + '" ' + Params;
FillChar(StartInfo, SizeOf(StartInfo), #0);
with StartInfo do
begin
cb := SizeOf(SUInfo);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := WinState;
end;
Result := CreateProcess(nil, PChar( String( CmdLine ) ), nil, nil, false,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
PChar(ExtractFilePath(Filename)),StartInfo,ProcInfo);
Далее, ожидаем завершения приложения
if Result then
begin
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
{ Free the Handles }
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;
end;
Запрограммируйте кнопку Button1 на запуск приложения Калькулятор. В параметре FileName необходимо прописывать полный путь к файлу. Вызов процедуры выглядит так:
ExecAndWait( 'C:\windows\calc.exe', '', SH_SHOWNORMAL) ;
Параметр FileName = Имя внешней программы.
Параметр Params = Параметры, необходимые для запуска внешней программы
Параметр WinState = Указывает - как будет показано окно:
Попробуйте изменить параметр WinState. Для данного параметра можно использовать так же следующие значения:
SW_HIDE, SW_MAXIMIZE, SW_MINIMIZE, SW_SHOWNORMAL.
Ознакомьтесь с результатом. Покажите результат преподавателю.
Тема: Многодокументные приложения
Цель работы: научится создавать многопользовательский интерфейс на этапе проектирования и разработки на примере программы, предназначенная для просмотра текстовых и графических файлов.
Программное обеспечение: Borland Delphi 7
Ход работы:
Открыть Delphi
На первой форме (главной) расположите следующие компоненты:
MainMenu1
OpenDialog1
OpenPictureDialog1
MainMenu1 имеет следующую структуру:
Вкладка Файл (Открыть текст, Открыть графику, Закрыть окно, Закрыть все, Выход)
Вкладка Окно (Каскад, Мазаика)
Создайте две дочерные формы предназначенные для просмотра текста и графических файлов.
На дочерной текстовой форме расположите компонент Memo1
На дочерной графической форме расположите компонент Image1
Для главной формы установите значение свойства FormStyle = fsMDIForm.
Для дочерных форм установите значение свойства FormStyle = fsMDIChild.
Для того, чтобы дочерные формы не запускались перед запуском программы, отмените авто создание этих форм.
Уберите динамически Memo1. Выполнение операции происходит при создании формы графической.
Procedure TfmChildGraphic.FormCreate(Sender:TObject);
Begin
Inherited;
Memo1.Free;
End;
Настройте OpenDialog1 и OpenPictureDialog1 c помощью фильтров (выполнение операций из предыдущих работ). В окне выбора должны отображатся только текстовые форматы для текстового просмотрщика и изображения для графического просмотрщика.
В заголовках дочерных окон отобразите полное только имя и расширение файлов с помощью функции ExtractFileName.
После оформления всех форм, покажите результат преподавателю.
Сохраните проект и юниты с помощью Safe Project AS
Создайте для главной формы обработчик события OnCreate. Присвойте свойству Caption значение ‘Просмотр файла’, свойству FormStyle – fsMDIForm (если не установлено в инспекторе объектов), WindowsMenu – mnuWindows.
Зайдите в редактор меню и выберите во вкладке Файл -открытие текста. Дважды щелкните по нему. Создастся метод с событием OnClick. В данной процедуре создается экземпляр текстовой формы при условии, если будет произведен выбор в окне диалога открытия файла. Открытие файла и загрузка в компонент Memo1 текст происходит вызовом из компонента OpenDialog1 методом Execute.
Аналогично загружается графический файл в компонент OpenPictureDialog1
Кнопка закрытия одного файла осуществляется также созданием метода с событием onClick. fmMain – главная форма. В процедуре записывается следующее:
If fmMain.ActiveMDIChildnill then fmMain.ActiveMDIChild.Close;
Процедура для закрытия всех окон:
Var n:integer; где n -количество открытых окон
Begin n:=FmMDIChildCount – 1 downto 0 do
If fmMain.ActiveMDIChildnill then fmMainChildren[n].Close;
End;
Для кнопки каскада в процедуре каскада прописывается fmMain. Cascade;
Мозаика вызывается методом Tile: fmMain.Tile;
Также необходимо прописать процедуры создания и удаления дочерных форм. Создание выполняется с помощью события OnCreate, а удаление onClose.
При удалении в процедуре значением свойства Action = caFree. Создание и удаление дочерных форм производится на той форме, которую нужно создать или удалить.
После выполнения работы показать результат преподавателю.
Тема: Консольные приложения
Цель работы: Научиться разрабатывать простые консольные приложения.
Программное обеспечение: Borland Delphi 7
Ход работы:
Создайте консольное приложение “Hello Word”.
1. Выберите команду File/New Application.
2. Выберите команду File/Remove From Project, и появится диалоговое окно, Remove From Project, показанное на рис. 1.15.
3. В проекте содержится один модуль формы. Выберете его и щелкните на кнопке ОК. Появится диалоговое окно Save changes to Unit1.pas?
4. Щелкните на кнопке No, и форма будет удалена из проекта.
5. Сохраните проект как EgConsoleHello.
6. Выберите команду View/Project Source, и в редакторе появится следующий текст.
program EgConsoleHello;
uses
Forms;
{$R *.RES}
begin
Application.Initialize;
Application.Run;
end;
7. Модуль Forms, однако он не используется, поэтому данную строку можно удалить. Строки с Application используются для инициализации OLE-сервера и вывода главной формы. Поскольку мы не используем ни того, ни другого, удалите и эти строки. Последнее действие - объяснить компилятору, что мы хотим создать обычное, простое, незамысловатое консольное приложение. Этого можно достичь с помощью команды $APPTYPE. Код в результате будет выглядеть так.
program EgConsoleHello;
{$APPTYPE CONSOLE}
{$R *.RES}
begin
end;
Для ввода сообщения добавьте между begin и end строку
WriteLn ('Hello, world!');
Сохраните, скомпилируйте и запустите проект из командной строки. Консольные приложения используют стандартные потоки ввода-вывода, а значит, вы можете использовать функции Read, ReadLn, Write и WriteLn.
Измените заголовка консольного окна. В кода программы наберите следующий текст.
program EgConsoleTitle;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils;
{$R *.RES}
var
sNewTitle, sErrMsg: string;
begin
sNewTitle := 'Welcome to Con5ole World';
if not SetConsoleTitle(PChar(sNewTitle)) then
begin
sErrMsg := 'Unable to set caption - ' + SysErrorMessage(GetLastError);
MessageBox(0, PChar(sErrMsg), 'Error', MB_ICONEXCLAMATION + MB_OK);
end;
ReadLn;
end.
Функция API SetConsoleTitle возвращает False, если назначить новый заголовок невозможно. GetLastError возвращает числовое значение последней ошибки API, которое SysErrorMessage конвертирует в строку для вывода на экран.
8. Показать результаты преподавателю.
Тема: Создание прикладного приложения с элементами интерфейса
Цель работы: Ознакомиться с разработкой интерфейса на примере ранее изученного интерфейса MDI.
Программное обеспечение: Borland Delphi 7
Теоретическая часть
Автоматическое создание форм
По умолчанию при запуске приложения Delphi автоматически создает по одному экземпляру каждого класса форм в проекте и освобождает их при завершении программы. Автоматическое создание обрабатывается генерируемым Delphi кодом в трех местах.
Первое — раздел интерфейса в файле модуля формы.
type
TForm1 = class (TForm)
private
{Закрытые объявления.}
public
{Открытые объявления.}
end;
В данном фрагменте кода объявляется класс TForm1.
Вторым является место, в котором описывается переменная класса.
var Form1: TForm1;
Здесь описана переменная Form1, указывающая на экземпляр класса TForm1 и доступная из любого модуля. Обычно она используется во время работы программы для управления формой.
Третье место находится в исходном тексте проекта, доступ к которому можно получить с помощью меню View/ Project Source. Этот код выглядит как:
Application.CreateForm(TForm1, Form1);
Процесс удаления форм обрабатывается с помощью концепции владельцев объектов: когда объект уничтожается, автоматически уничтожаются все объекты, которыми он владеет. Созданная описанным образом форма принадлежит объекту Application и уничтожается при закрытии приложения.
Динамическое создание форм
Хотя автоматическое создание форм полезно при разработке SDI-приложений, при создании MDI-приложении оно, как правило, неприемлемо.
Для создания нового экземпляра формы используйте конструктор Create класса формы. Приведенный ниже код создает новый экземпляр TForm1 во время работы программы и устанавливает его свойство Caption равным 'New Form'.
Form1:= TForm1.Create(Application);
Form1.Caption:= 'New Form';
Конструктор Create получает от вас в качестве параметра потомка TComponent, который и будет владельцем вашей формы. Обычно в качестве владельца выступает Application, чтобы все формы были автоматически закрыты по окончании работы приложения. Вы можете также передать параметр Nil, создав форму без владельца (или владеющую собой — как вам больше нравится), но тогда закрывать и уничтожать ее придется вам. В случае возникновения необрабатываемой ошибки такая форма останется в памяти, что не говорит о высоком профессионализме программиста...
В приведенном ниже коде Form1 указывает только на последнюю созданную форму. Если вам это не нравится, воспользуйтесь приведенным ниже кодом — возможно, он более точно отвечает вашим запросам:
with TFormI.Create(Application) do
Caption:= 'New Form';
Даже при динамическом создании форм Delphi попытается навязать вам свои услуги по созданию экземпляра каждой формы. Чтобы отказаться от них, воспользуйтесь диалоговым окном Project Options, и удалите классы форм из списка Auto-create forms.
Диалоговое окно Project Options позволяет установить опции для текущего проекта
Если вы захотите получить доступ к отдельному дочернему экземпляру класса, используйте свойство MDIChildren, описываемое в следующем разделе.
MDI-свойства TForm
Объект TForm имеет несколько свойств, специфичных для MDI-приложений.
ActiveMDIChild
Это свойство возвращает дочерний объект TForm, имеющий в текущее время фокус ввода. Оно полезно, когда родительская форма содержит панель инструментов или меню, команды которых распространяются на открытую дочернюю форму.
Например, представим, что проект использует дочернюю форму, содержащую элемент TMemo, названный memDailyNotes. Имя класса этой дочерней формы— TfrmMDIChild. Родительская форма содержит кнопку Clear в панели инструментов, которая удаляет содержимое memDailyNotes в активной дочерней форме. Вот как это реализуется.
procedure TfrmMDIParent.spbtnClearClick(Sender: TObject);
begin
if not (ActiveMDIChild = Nil) then
if ActiveMDIChild is TfrmMDIChild then
TfrmMDIChild(ActiveMDIChild).memDailyNotes.Clear;
end;
В первой строке проверяется, равен ли ActiveMDIChild значению Nil, так как в этом случае обращение к объекту вызовет исключительную ситуацию.
Свойство MDIChildren является массивом объектов TForm, предоставляющих доступ к созданным дочерним формам. MDIChildCount возвращает количество элементов в массиве MDIChildren.
Обычно это свойство используется при выполнении какого-либо действия над всеми открытыми дочерними формами. Вот код сворачивания всех дочерних форм командой Minimize All.
procedure TFormI.mnuMinimizeAllClick(Sender: TObject);
var
iCount: Integers;
begin
for iCount:= MDIChildCount-1 downto 0 do
MDIChildren[iCount].WindowState:= wsMinimized;
end;
Если вы будете сворачивать окна в порядке возрастания элементов массива, цикл будет работать некорректно, так как после сворачивания каждого окна массив MDIChildren обновляется и пересортировывается, и вы можете пропустить некоторые элементы.
TileMode
Это — свойство перечислимого типа, определяющее, как родительская форма размещает дочерние при вызове метода Tile. Используются значения tbHorizontal (по умолчанию) и tbVertical для размещения форм по горизонтали и вертикали.
WindowMenu
Профессиональные MDI-приложения позволяют активизировать необходимое дочернее окно, выбрав его из списка в меню. Свойство WindowMenu определяет объект TMenuItem, который Delphi будет использовать для вывода списка доступных дочерних форм.
Для вывода списка TMenuItem должно быть меню верхнего уровня. Это меню имеет свойство Caption, равное swindow.
MDI-события TForm
В MDI-приложении событие OnActivate запускается только при переключении между дочерними формами. Если фокус ввода передается из не MDI-формы в MDI-форму, генерируется событие OnActivate родительской формы, хотя ее свойство Active никогда и не устанавливается равным True. Эта странность на самом деле строго логична: ведь, если бы OnActivate генерировался только для дочерних форм, не было бы никакой возможности узнать о переходе фокуса ввода от другого приложения.
MDI-методы TForm
Специфичные для MDI-форм методы перечислены ниже.
Arrangelcons выстраивает пиктограммы минимизированных дочерних форм в нижней части родительской формы.
Cascade располагает дочерние формы каскадом, так что видны все их заголовки.
Next и Previous переходит от одной дочерней формы к другой, как будто вы нажали или .
Tile выстраивает дочерние формы так, что они не перекрываются.
Ход работы:
Пример MDI-приложения
Создание интерфейса
Выполните следующие действия для создания родительской формы.
1. Выберите команду File/New Application, и появится пустое приложение.
2. Установите следующие свойства.
Свойство Значение
Caption Image Viewer
FormStyle fsMDIForm
Name frmMDIParent ShowHint True
3. Поместите компонент TPanel в форму. Установите следующие его свойства.
Свойство Значение
Align alTop
Caption -
4. Поместите три компонента TSpeedButton в TPanel и назовите их spbtnLoad, spbtnStretch и spbtnCenter. Установите следующие их свойства.
Свойство Значение
spbtnLoad.Hint Load
spbtnLoad.Left 8
spbtnLoad.Top 8
spbtnStretch.AllowAlIUp True
spbtnStretch.Grouplndex 1
spbtnStretch.Hint Stretch
spbtnStretch.Left 48
spbtnStretch.Top 8
spbtnCenter.AllowAlIUp True
spbtnCenter.Grouplndex 2
spbtnCenter.Hint Center
spbtnCenter.Left 80
spbtnCenter.Top 8
Свойства Glyph установите те же, что и для SDI-приложения.
5. Добавьте в форму компонент TOpenDialog и установите следующие его свойства.
Свойство Значение
Filter Bitmaps (*.bmp)]*.bmp
Name opndlgLoad
Options [ofPathMustExist,ofFileMustExist]
Теперь создадим дочернюю форму.
1. Выберите из меню File/New Form, и появится пустая форма.
2. Установите следующие ее свойства.
Свойство Значение
FormStyle fsMDIChild
Name frmMDIChild
Position poDefaultPosOnly
3. Поместите компонент TImage во вновь созданную форму и установите его следующие свойства.
Свойство Значение
Align alClient
Name imgMain
Удалите дочернюю форму из списка автоматически создаваемых форм следующим образом.
1. Выберите команду Project/ Options, и появится диалоговое окно Project Options, показанное на рис. 1.14.
2. Выберите frmMDIChild в списке Auto-create forms.
3. Щелкните на кнопке. Форма frmMDIChild при этом будет перенесена в список Available forms.
4. Щелкните на кнопке ОК.
Теперь самое время сохранить проект, выбрав команду File/Save Project As. Сохраните Unit1 как MDIParent, а проект — как EgMDIApp.
Написание кода
Создав интерфейс, перейдем к написанию исходного текста приложения. Сначала загрузим изображение. Введите следующий код в обработчик события OnClick компонента spbtnLoad.
procedure TfrmMDIParent.spbtnLoadClick(Sender: TObject);
begin
if opndlgLoad.Execute then
with TfrmMDIChild.Create(Application) do
begin
Caption:= opndlgLoad.FileName;
imgMain.Picture.LoadFromFile(opndlgLoad.FileName);
ClientWidth:= imgMain.Picture.Width;
ClientHeight:= imgMain.Picture.Height;
end;
end;
После запуска диалогового окна создается новый экземпляр дочерней формы и загружается файл изображения. После загрузки размеры дочерней формы изменяются так, чтобы можно было видеть все изображение.
Еще пара штрихов— и приложение заработает, как и предусматривалось. Поскольку модуль ссылается на тип TfrmMDIChild, находящийся в модуле MDIChild, после строки implementation следует добавить еще одну строку:
uses MDIChild;
Теперь можно приступить к компиляции и запуску приложения. Однако заметьте, что, когда вы щелкаете на кнопке Close, дочерняя форма не закрывается, а сворачивается в пиктограмму. Чтобы заставить ее закрыться, следует добавить в код обработчика OnClose класса TfrmMDIChild маленькую деталь— изменить свойство Action:
Action:= caFree;
Компоненты TSpeedButton Stretch и Center выполняют те же функции, что и в SDI-приложении, однако их обработчики события OnClick следует изменить следующим образом
if not (ActiveMDIChild = Nil) then
if ActiveMDIChild 15 TfrmMDIChild then
TfrmMDIChild(ActiveMDIChild).imgMain.Stretch:= spbthStretch.Down;
и
if not (ActiveMDIChild = Nil) then
if ActiveMDIChild is TfrmMDIChild then
TfrmMDIChild(ActiveMDIChild).imgMain.Center:= spbthCenter.Down;
Остается последняя проблема — состояния кнопок Stretch и Center одинаковы для всех дочерних форм Для решения этой задачи добавьте в обработчик события OnActivate класса TfrmMDIChild строки.
frmMDIParent.spbtnStretch.Down:= imgMain.Stretch;
frmMDIParent.spbtnCenter.Down:= imgMain.Center;
И, наконец, самый последний из последних штрихов— в модуле MDIChild добавьте после строки implementation строку.
uses MDIParent;
Компилируйте, запускайте приложение.
Результат показать преподпвателю.
Тема: Создание прикладного приложения с отсчетом времени и линейками прокрутки
Цель работы: Разработать приложения с отчетом времени и линейкой прокрутки, используя визуальные и не визуальные компоненты.
Программное обеспечение: Borland Delphi 7
Откройте Delphi
На форме создайте компонент Label1 (Standart). В свойстве Caption введите “Секундомер”. Это будет названием наши программы.
Создайте еще один Label. Здесь мы будем выводить результат на экран.
Создайте Button1 и Button2 (кнопка запуска секундомера и кнопка сброса соответственно).
Создайте компонент Timer (System).
Для форму задайте метод, активируя событие onCreat. Описание медота:
procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Caption:='00:00'; //текст метки
Button1.Caption:='Пуск'; //название кнопки Button1
Button2.Caption:='Сброс'; //название кнопки Button2
Timer1.Enabled:=false //таймер не запущен
end;
Для кнопки “Пуск/Стоп” прописать метод, запускаемый событием onClick.
procedure TForm1.Button1Click(Sender: TObject);
begin
if Timer1.Enabled
then //если секундомер работает
begin
Timer1.Enabled:=False; //останавливаем таймер
Button1.Caption:='Пуск'; //меняем название кнопки
Button2.Enabled:=True; //кнопка "Сброс" доступна
end
else //если секундомер не работает
begin
Timer1.Enabled:=True; //запускаем таймер
Button1.Caption:='Стоп'; //меняем название кнопки
Button2.Enabled:=False; //кнопка "Сброс" недоступна
end
end;
Для кнопки “Сброс” прописать метод, запускаемый событием onClick.
procedure TForm1.Button2Click(Sender: TObject);
begin
sec:=0;
min:=0;
Label1.Caption:='00:00';
Button2.Enabled:=False; //кнопка "Сброс" недоступна
Timer1.Enabled:=False; //останавливаем таймер
end;
Для компонента Timer используем событие onTimer для задания метода
procedure TForm1.Timer1Timer(Sender: TObject);
var
str: string;
begin
if sec=59
then
begin
inc(min);
sec:=0;
end
else inc(sec);
if minthen str:='0'+IntToStr(min)
else str:=IntToStr(min);
if secthen str:=str+':0'+IntToStr(sec)
else str:=str+':'+IntToStr(sec);
Label1.Caption:=str;
end;
Используя листинг программы создать приложение и объяснить, что выполняет данное приложение.
AlphaBlend – свойство Form, включает или выключает условие прозрачности.
AlphaBlendValue - свойство Form, задает степень прозрачности от О до 255.
Interval – свойство Timer, устанавливает интервал времени между операциями.
Enabled - свойство Timer имеет булевский тип. Включает или выключает Timer.
procedure TForm1.FormCreate(Sender: TObject);
begin
AlphaBlend:=true;
AlphaBlendValue:=5;
Timer1.Interval:=55;
Timer1.Enabled:=true;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if AlphaBlendValue=255
then
Timer1.Enabled:=false
else
AlphaBlendValue:=AlphaBlendValue+5
end;
Компонент ScrollBar.
Формы или окна могут определять линейки прокрутки как часть оформления своих рамок, которые внутренне связаны с отображающим их окном, а не являются самостоятельными компонентами. Их положение ограничено правым или нижним краями окна, к которому они принадлежат. Автономный компонент, ScrollBar, может появляться в каком угодно месте внутри окна формы.
Имеется два вида линеек прокрутки:
вертикальная (sbVertical);
горизонтальная (sbHorizontal).
Свойство Kind компонента ScrollBar служит переключателем между двумя состояниями.
Установите компонент ScrollBar и установите необходимые свойства. Поместите в нижней части компонент Image и вставьте рисунок. При запуске рисунка не будет видно, но при перемещении ползунка вниз, должна появится картинка.
Тема: Создание прикладного приложения с панелями инструментов и строки состояния
Цель работы: Разработать приложения с информацией в строке состояния.
Программное обеспечение: Borland Delphi 7
Теоретическая часть
Строка состояния - это управляющий элемент, с помощью которого пользователю выдается разного рода вспомогательная информация о ходе выполнения приложения.
Для этой цели используется специальный компонент StatusBar , представляющий собой ряд панелей, обычно располагающихся внизу главной формы приложения, которые содержат текущую справочную информацию. Каждая такая панель представлена в списке свойства Panels данного компонента.
Свойства данного компонента.
Свойство SimplePanel (тип Boolean) определяет, будет статусная строка содержать одну панель или несколько. Для того чтобы отображалась одна панель, данное свойство нужно установить в True, чтобы несколько - в False.
Свойство SimpleText (тип String) содержит текст, который выводится в статусной строке в случае, если свойство SimplePanel имеет значение True.
Свойство Count (тип Integer) показывает количество панелей в строке состояния. Данное свойство доступно только для чтения.
Свойство SizeGrip (тип Boolean) определяет возможность изменения размеров статусной строки. Если свойство имеет значение True, то в правом нижнем углу статусной строки будет отображаться специальная треугольная область захвата, с помощью которой можно изменять размеры статусной строки путем растягивания. В случае, когда строка состояния выровнена по нижнему краю формы, использование области захвата будет приводить к изменению размеров самой формы. Однако при этом для свойства BorderStyle формы должно быть установлено значение bsSizeable или bsSizeToolWin, в противном случае область захвата появляться не будет.
Свойство AutoHint (тип Boolean), имеющее значение True, устанавливает, что в статусной строке автоматически будет отображаться значение текущей всплывающей подсказки (hint). При этом сама всплывающая подсказка не показывается.
Свойство Panels (тип TStatusPanels) содержит список панелей статусной строки. При выполнении приложения можно обращаться к соответствующей панели по ее индексу (нумерация начинается с нуля).
В качестве основных свойств панели как объекта класса TStatusPanels можно выделить следующие.
1) Свойство Alignment (тип TAligrunent) задает способ выравнивания текста относительно панели.
2) Свойство Bevel (тип TStatusPanelBevel) определяет вид панели: углубленная, приподнятая или плоская.
3) Свойство Style (тип TStatusPanelStyle) устанавливает способ отображения информации на панели и может принимать одно из двух значений:
• psText - в качестве содержимого панели используется значение свойства Text (по умолчанию);
• psOwnerDraw - вывод текстовой и графической информации выполняется программно с использованием поверхности рисования (Canvas) строки состояния.
4) Свойство Text (тип String) содержит текст, выводимый на панели.
5) Свойство Width (тип Integer) задает ширину панели. По умолчанию устанавливается ширина в 50 пикселей, а последняя панель занимает все оставшееся свободное пространств строки состояния.
Ход работы:
Необходимо создать приложение, отражающее различные возможности работы со строкой состояния.
На форму помещаются такие компоненты: строка состояния StatusBar, многострочный редактор Memo,переключатель Checkbox, группа зависимых переключателей RadioGroup и две кнопки Button с заголовкамиОчистить и Выход.
Для компонента StatusBar свойству AutoHint присваивается значение True. Затем для этого компонента с помощью Инспектора объектов через свойство Panels вызывается редактор Editing Status Bar.Panels, в котором добавляются шесть панелей. Начальные установки для каждой панели задаются путем изменения свойства Text.
Свойству Width для каждой панели задается соответствующее значение, на выбор программиста.
В панелях будет отображаться следующая информация:
• Панель 0: значение текущей всплывающей подсказки (hint), то есть подсказки для того элемента, над которым в данный момент находится указатель мыши.
• Панель 1: цвет текста в поле редактора Memo.
• Панель 2: стиль шрифта в поле редактора Memo (обычный или курсив).
• Панель 3: состояние кнопки Caps Lock (если кнопка включена, то выводится строка 'Большие буквы', если выключена, то отображается строка 'Маленькие буквы').
• Панель 4: количество строк, содержащихся в.редакторе Memo.
• Панель 5: текущее время.
В поле многострочного редактора Memo пользователь получает возможность вводить любой текст.
Свойству Caption переключателя Checkbox устанавливается значение 'Курсив'. Данный переключатель будет определять, обычным или наклонным шрифтом отобразится текст в редакторе Memo.
Свойство Caption группы переключателей RadioGroup получает значение 'Цвет текста'. Затем через свойствоItems задаются три переключателя с названиями 'Черный', 'Красный' и 'Синий'. Свойству Itemlndex данного компонента присваивается значение 0. Эти переключатели будут обеспечивать изменение цвета текста, содержащегося в поле многострочного редактора.
По нажатию кнопки "Очистить" содержимое редактора Memo удаляется.
Обработчики событий:
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin // во второй панели отображается каким цветом выводится текст в редакторе Memo
case RadioGroup1.ItemIndex of
0:begin
Memo1.Font.Color:=clBlack;
StatusBar1.Panels[1].Text:='Черный цвет';
end;
1:begin
Memo1.Font.Color:=clRed;
StatusBar1.Panels[1].Text:='Красный цвет';
end;
2:begin
Memo1.Font.Color:=clBlue;
StatusBar1.Panels[1].Text:='Синий цвет';
end;
end;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin // в третьей панели отображается выводится текст курсивом или обычным //шрифтом
if CheckBox1.Checked then
begin
StatusBar1.Panels[2].Text:='Курсив';
Memo1.Font.Style:=[fsitalic];
end
else begin
StatusBar1.Panels[2].Text:='Обычный шрифт';
Memo1.Font.Style:=[];
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin // отображение в панели статусной строки состояния клавиши Caps Lock
if getkeystate(vk_capital)=1 then
StatusBar1.Panels[3].Text:='большие буквы'
else
StatusBar1.Panels[3].Text:='маленькие буквы';
StatusBar1.Panels[5].Text:=TimeToStr(Time); // отображение текущего времени в
//панели статусной строки
end;
procedure TForm1.Memo1Change(Sender: TObject);
begin // отображение в панели количества строк в редакторе Memo
StatusBar1.Panels[4].Text:='Строк:'+IntToStr(Memo1.Lines.Count);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin // Выход
close;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin // Очистка поля ввода редактора Memo
memo1.clear;
end;
end.
Тема: Создание приложения “Текстовый редактор”
Цель работы: Спроектировать прикладное приложение “Текстовый редактор”
Программное обеспечение: Borland Delphi 7
На примере разработки приложения «Редактор текстов» рассмотрим использование на форме невизуальных и неоконных компонентов, а также порядок проектирования главного меню, всплывающего меню и панели инструментов.
Разрабатываемое приложение должно обеспечить:
• отображение существующего текстового файла в окне редактирования или создание нового файла;
• выполнение простейших операций по редактированию: вставка-удаление символов, копирование и перемещение фрагментов текста с использованием Системного буфера обмена (ClipBoard);
• сохранение результатов редактирования в том же или ином файле.
Рассмотрим последовательно этапы разработки приложения.
Первый этап – проектирование интерфейса. Главное окно приложения будет содержать следующие визуальные компоненты:
• главное меню, расположенное в верхней части окна;
• панель инструментов, расположенную сразу под строкой Главного меню;
• область для отображения и редактирования текстов, которая должна занимать всю оставшуюся часть главного интерфейсного окна;
• «всплывающее» меню, которое должно появляться при нажатии правой кнопки мыши в области редактирования.
Создание Главное меню. Для организации выполнения перечисленных действий построим Главное меню приложения.
Разобьем функции приложения на две группы – «Файл» и «Редактировать». Эти две группы и представляют собой опции Главного меню.
В группу «Файл» войдут функции «Создать», «Открыть», «Сохранить», «Сохранить как…» и «Выход». Опция меню «Файл» должна объединять соответствующие пункты меню, представляющие собой команды, вызывающие выполнение перечисленных функций.
В группу «Редактировать» - функции «Врезать», «Копировать» и «Вставить».
Дизайнер меню. Компонент Главного меню располагается на странице «Стандартные» Палитры компонентов. Установим компонент на форме и вызовем Дизайнер меню. Это можно сделать либо через свойство Items компоненты Главного меню, либо с помощью контекстного меню, вызвав его на форме.
Каждый пункт меню вводится с помощью Дизайнера, а затем отображается в строке меню на форме. При вводе нового пункта на самом деле создается новый компонент и добавляется в список компонентов Инспектора объектов (хотя визуально на форму ничего не добавляется). В свойствах компонента обязательно заполняются поля Caption – название пункта, Name – имя компонента и, если необходимо, поля ShortCut – «горячая клавиша» для вызова функции с помощью клавиатуры и Bitmap – для добавления пиктограммы к заголовку пункта.
Для удобства восприятия команды меню визуально разбиваются на группы с помощью добавления в меню специальных пунктов-разделителей. Чтобы ввести такой пункт, достаточно в свойстве Caption установить знак «-» (дефис).
Панель инструментов. Следующий этап проектирования формы – размещения Панели инструментов. Панель инструментов предназначена для дублирования наиболее часто использующихся команд меню графическими кнопками, что обеспечивает более быстрый способ вызова функций.
В Delphi есть специальный компонент ToolBar (страница «Win32» Палитры компонентов), предоставляющий готовую панель инструментов со своими собственными кнопками. Компонент ToolBar инкапсулирует соответствующий стандартный элемент управления Windows.
Разместим компонент на форме и зададим значения некоторым свойствам (помимо свойства Name). Значение alTop свойства Algin определяет положение панели инструментов на форме - в верхней части, сразу под строкой Главного меню. Установка свойства Flat в true задает особый стиль изображения кнопок панели – без прорисовки контура (контур появляется только у кнопки, на которую указывает курсор).
Сначала размещенная на форме панель инструментов пуста. Добавление кнопок осуществляется с помощью всплывающего контекстного меню компонента: для добавления кнопки используется команда New Button, а для добавления разделителя – команда New Separator.
Компонент ToolBar содержит объекты класса TToolButton. Это внутренние объекты (аналогично объектам класса TMenuItem, которые являются внутренними для объекта MainMenu).
Далее для каждой кнопки задается рисунок – пиктограмма, соответствующая функциональному назначению кнопки. Определение рисунков для кнопок панели инструментов осуществляется с помощью невизуального компонента ImageList. Этот компонент не имеет своего места на форме и предназначен для создания коллекции рисунков, выбор которых происходит по индексу – номеру рисунка в коллекции.
Имя компонента заносится в свойство Image Панели инструментов и, таким образом, обеспечивается связь каждой отдельной кнопки панели с соответствующей картинкой.
Коллекция рисунков ImageList. Для создания коллекции рисунков на форму добавляется компонент ImageList ( страница «Win32» Палитры компонентов). Контекстное меню компонента позволяет вызвать Редактор ImageList, с помощью которого проводятся действия по добавлению и удалению рисунков коллекции.
Каждый добавленный рисунок получает в коллекции свой индекс и может быть в дальнейшем связан с некоторой кнопкой панели инструментов путем занесения значения индекса в свойство ImageIndex кнопки.
На примере кнопки Панели инструментов продемонстрируем использование пары свойств ShowHint и Hint для формирования «всплывающих» подсказок. Установка свойства ShowHint в True обеспечивает включение аппарата «всплывающей» подсказки для компонента, т.е. появление в специфическом «всплывающем» окне текста, заданного в свойстве Hint, при задержке курсора в области компонента.
Область для отображения и редактирования текстов. Для отображения и редактирования текстовых файлов разместим на форме компонент Memo класса TMemo. Установим значение Client в свойстве Algin компонента, обеспечив тем самым заполнение компонентом всей незанятой части главного интерфейсного окна.
Компонент Memo предназначен для ввода разделенных и не разделенных на строки текстов. При установке свойства WordWrap в True происходит дополнительное разбиение текстов на строки по ширине компонента.
Свойство ScrollBar позволяет установить на области компонента стандартные полосы «прокрутки» текстов: ssVertical – только вертикальная полоса, ccHorizontal – только горизонтальная полоса, ssBoth – обе полосы.
Компонент автоматически поддерживает стандартные функции редактирования – ввод, замену и удаление отдельных символов, а также выделение фрагментов текста.
Приведем фрагмент текстового описания формы для компонента Memo( имя компонента – EditMemo):
Object EditMemo:Mеmo
Left =0;
Top=25;
Width=493;
Height=295;
Algin=alClient;
ScroollBar=ssVertical;
TabOrder=1;
End;
Разработка Контекстного меню. Кроме Главного меню обычно ещё используется похожий на него компонент PopupMenu (страница «Стандартные»). Такое меню отображается при нажатии на правую кнопку мыши в области компонента, свойство PopupMenu которого указывает на данное меню. Это стандартный способ использования контекстного меню.
Разместим на форме неоконный компонент PopupMenu и добавим в меню опции из группы команд «Редактирование» Главного меню. Порядок проектирования контекстного меню полностью совпадает с порядком проектирования Главного меню и тоже предполагает использование Дизайнера меню.
Для привязки пунктов контекстного меню к компоненту Memo занесем свойство PopupMenu компонента имя контекстного меню.
Использование стандартных диалогов. Для организации работы с файлами (открытия файлов для редактирования и сохранения результатов) используются компоненты стандартных диалогов Windows, реализованные в среде. Разместим на форме приложения неоконные компоненты OpenDialog и SaveDialog (страница «Dialogs») и рассмотрим возможности их использования на примере компонента OpenDialog (SaveDialog работает похожим образом).
Использование диалоговых компонентов не обеспечивает автоматического открытия или сохранения файлов, но позволяет получить для дальнейшей обработки в программе имя выбранного пользователем файла.
Рассмотрим некоторые свойства компонентов, позволяющие управлять видом и характером действия диалогового окна.
Свойство FileName назначает имя файла по умолчанию (имя, которое будет отображаться в окне «Имя файла» при открытии диалогового окна) содержит имя выбранного пользователем файла.
Свойство DefaultExt позволяет указать расширение имени файла, которое будет добавляться по умолчанию в том случае, если в окне «Имя файла» имя будет указано без расширения.
Свойство Filter задает список файловых масок (файловых фильтров), из которого пользователь может выбирать для отображения в диалоговом окне только нужные типы файлов. Файловый фильтр представляет собой строку, состоящую из одной или более пар значений. Пара значений – это описание фильтра и сам фильтр. Каждая пара значений задает один фильтр. Пары значений и значения внутри одной пары разделяются символом «І». Например, следующая строка задает два фильтра для диалога:
MyOpenDialog.Filter:=’Текстовые файлы (*.txt) І *.txt І Все файлы (*.*)І *.* ’
Тема: Создание приложения “Текстовый редактор”
Цель работы: Разработать прикладное приложение “Текстовый редактор”
Программное обеспечение: Borland Delphi 7
Второй этап разработки приложения – разработка процедур обработки событий. Рассмотрим последовательно процедуры-обработчики для пунктов Главного меню (обработчики события OnClick для каждого компонента класса TMenuItem).
Пункт Главного меню Файл/Открыть предназначен для организации диалога выбора файла на редактирование. Метод OpenDialog.Execute открывает диалоговое окно, а после нажатия на кнопку «Открыть» в диалоговом окне возвращает значение True и заполняет свойство OpenDialog.FileName, помещая в него имя выбранного в окне диалога файла.
Метод LoadFromFile объекта TString, представляющего свойство Lines компонента EditMemo, позволяет одновременно организовать открытие и чтение файла в область редактирования. Если процесс загрузки файла закончился удачно, изменяется заголовок окна приложения (в него помещается имя открытого файла) и заполняется глобальная переменная CurrentFileName, служащая для хранения имени текущего файла. В случае возникновения ошибки при загрузке файла управление передается в блок обработки исключений и выдается диалоговое окно сообщения.
Приведем текст процедуры:
Procedure TForm1.MFile_OpenClick(Sender:TObject);
Begin
If OpenDialog.Execute then
Try
EditMemo.Lines.LoadFromFile(OpenDialog.FileName);
Form1.Caption:=Form1.Caption + ‘ – ‘ + OpenDialog.FileName;
CurrentFileName:=OpenDialog.FileName;
Except
On EFOpenError do
MessageDlg (‘Ошибка при открытии файла’ , mtError,[mbOk],0);
End;
End;
Пункт Главного меню Файл/Сохранить как… предназначен для сохранения результатов редактирования в файле, имя которому назначает пользователь. При организации процесса сохранения результатов необходимо учесть возможность существования файла с именем, указанным в окне диалога сохранения. В предлагаемой процедуре-обработчике используется стандартная функция FileExists для проверки существования файла и организуется запрос-диалог для принятия решения. Стандартная функция MessageDlg открывает диалоговое окно с тремя управляющими кнопками - [Yes], [No] и [Cancel] и возвращает константу – признак выполненного действия (нажатой кнопки).
В зависимости от принятого пользователем решения выполняется одна из трех последовательности действий: сохранение результатов редактирования с помощью применения метода SaveToFile, симметричного методу LoadFromFile; повторяется диалог назначения имени файла или происходит выход из процедуры-обработчика:
Procedure TForm1.MFile_SaveAsClick(Seder:TObject);
Label 1;
Var btn: word;
Fsave:Boolean;
Begin
If EditMemo.Text’ ‘then
Begin
1: if SaveDialog.Execute then
if FileExists (SaveDialog.FileName) then
begin
btn:= MessageDlg(‘Файл существует. Перезаписать?’,
mtWarning, [mbYes, mbNo, mbCancel], 0);
if btn= mrNo then goto 1;
if btn=mrCancel then fsave:=false;
if btn=mrYes then fsave:=true;
end
else fsave:=true;
if fsave then
try
EditMemo.Lines.SaveToFile(SaveDialog.FileName);
CurrentFileName:=SaveDialog.FileName;
Form1.Caption:=Progcaption + ‘-‘ + SaveDialod.FileName;
Except
On EInOutError do
MessageDlg(‘Ошибка записи в файл’, mtError, [mbOk], 0);
End;
End;
Посредством пункта Главного меню Файл/Сохранить результаты редактирования сохраняются в текущем файле, если имя текущего файла не пусто, или происходит вызов процедуры-обработчика для пункта меню Файл/Сохранить как…:
Procedure TForm1.MFile_SaveClick(Sender:TObject);
Label 1;
Var btn:word;
Fsave: Boolean;
Begin
If EditMame.Text’ ‘ then
If CurrentFileName = ‘ ‘ then MFile_SaveAs.Click
Else
Try
EditMemo.Lines.SaveToFile(CurrentFileName);
Except
On EInOutError do
MessageDlg(‘Ошибка записи в файл’, mtError, [mbOk], 0);
End;
End;
Обработчики событий пунктов Главного меню из группы «Редактировать» построены на использовании методов работы с Системным буфером обмена. Рассмотрим эти методы, общие для компонентов, поддерживающих процессы редактирования.
Метод CopyToClipboard предназначен для копирования выделенного фрагмента текста в Системный буфер обмена.
Метод CutToClipboard предназначен для удаления из текста выделенного фрагмента и переноса его в Системный буфер обмена.
Метод PasteToClipboard предназначен для вставки текста, содержащегося в Системном буфере обмена, по месту текстового курсора.
Использование этих методов позволяет организовать процедуры редактирования, связанные не только с перемещением фрагментов текста внутри области редактирования, но и обеспечить взаимодействие разрабатываемого приложения с другими, поддерживающими обработку текстовой информации.
Процедуры-обработчики, реализованные для пунктов Главного меню, являются общими и подключаются к соответствующим кнопкам панели инструментов и соответствующим пунктам контекстного меню.