От Delphi 4 к Delphi 5 часть 41

От Delphi 4 к Delphi 5 Быстрая разработка приложений MDI.
Вы познакомились с вопросом построения MDI-приложений в Delphi. Воспользовавшись выбранным подходом, смогли узнать подробности о MDI в Windows и о поддержке Delphi этого подхода. Однако не самый лучший способ следовать подходу "с самого начала", если вам нужно построить реальное приложение MDI. В Delphi реализован шаблон MDI Application, позволяющий быстро построить начальный код приложения MDI. Рассмотрим основные функции этого инструментального средства.
Чтобы использовать шаблон MDI Application, примените команду File/New меню Delphi, из раскрывшегося диалогового окна выберите страницу Projects, а затем MDI Application. Определите каталог для проекта, и Delphi произведет копирование файлов, которые вам необходимы для простого приложения MDI с инструментальной линейкой, строкой состояния и меню. При формировании этих составных частей шаблона будут производиться запросы.
На полученной форме размещены следующие компоненты: OpenDialog, ImageList, ActionList.
Форма, порожденная шаблоном, содержит стандартные элементы: главное меню, панель, используемую как инструментальная линейка, компонент StatusBar1 и некоторые системные диалоговые панели.
Программный код главной формы имеет следующее содержание:
uses ChildWin, About;

procedure TMainForm.CreateMDI Child(const Name: string);
var
Child: TMDIChild;
begin
{ create a new MDI child window }
Child:= TMDIChild.Create(Application);
Child.Caption:= Name;
if FileExists(Name) then Child. Memo1.Lines.LoadFromFile(Name);
end;

procedure TMainForm.FileNew1Execute(Sender: TObject);
begin
CreateMDIChild('NONAME' + IntToStr(MDIChildCount + 1));
end;

procedure TMainForm.FileOpen1Execute(Sender: TObject);
begin
if OpenDialog.Execute then
CreateMDIChild(OpenDialog. FileName);
end;

procedure TMainForm.HelpAbout1 Execute(Sender: TObject);
begin
AboutBox.ShowModal;
end;

procedure TMainForm.FileExit1Execute(Sender: TObject);
begin
Close;
end;

end.
Программный код для дочерней формы:
implementation

{$R *.DFM}

procedure TMDIChild.FormClose (Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
end;

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

Приложения SDI
Название интерфейса одного документа (SDI) подразумевает, что эти приложения состоят из единственного окна. Многооконные приложения SDI могут выглядеть очень похожими на приложения MDI, но требуют больших усилий при программировании в зависимости от степени сложности, реализуемой в управлении окнами.
Примером сложного SDI-приложения является среда Delphi. Оно допускает существование многих окон, которые привязаны к области клиента родительского окна. Приложение SDI обычно имеет окно, считающееся главным и состоящее часто из линейки меню.
Когда вы закрываете главное окно, сворачиваете или разворачиваете на весь экран, то вначале выполняются необходимые действия с родственными окнами. Например, прежде чем свернуть свое главное SDI-окно, среда Delphi сворачивает все свое семейство окон.
Многооконные приложения SDI требуют некоторых усилий, если от них ожидаются действия подобные поведению MDI-приложений. Примером может служить поддержка меню главного окна во всем приложении, даже когда фокус ввода находится в другой форме. Например, главное окно может содержать меню File, которое вы хотите сделать доступным своему семейству окон SDI. В приложении MDI родительское меню доступно всегда, это не требует никаких программных затрат, поскольку является свойством родительского меню по определению. В приложении SDI по умолчанию меню — это просто меню текущего окна SDI. Если в текущем окне SDI нет меню (как, например, в инспекторе объекта), то по умолчанию, нажатие Alt+F для вызова меню File не производит никакого действия. В данном случае должен быть написан дополнительный программный код, чтобы процесс главного окна обрабатывал запрошенный выбор меню.

Управление семейством окон SDI
Управление окном SDI отличается от управления окном MDI. В SDI нет специфических свойств, таких как ActiveMDIChild, помогающих управлять окнами. Здесь необходимо разрабатывать собственные средства управления.
Для того чтобы достичь функциональных возможностей SDI, как в Delphi, необходимо идентифицировать каждое окно в качестве главного либо члена семейства. Причем члены семейства ведут себя так же, как обычные окна, позволяющие их открывать, свертывать, разворачивать на весь экран и закрывать по своему усмотрению. Но когда вы выполняете любую из этих операций на главном окне, то необходимо пересылать управляющие запросы членам семейства, например, закрывать окна членов семейства перед закрытием основного окна. В результате этого получается интерфейс, похожий на приложения MDI, но обладающий большей гибкостью. Конечно, расплатой за это будет дополнительный программный код.
Ключом к управлению окнами SDI является поддержка переменных — дескрипторов форм (form — handle) для тех окон SDI, которые являются управляемыми.
Манипуляция объектами главного окна SDI со стороны членов семейства достигается выполнением следующих действий: главное окно SDI обычно создает окна членов семейства во время выполнения программы; для этого необходимо включать ссылку на модуль окна — члена семейства в секцию uses главного окна, эта ссылка должна присутствовать как в MDI, так и в SDI для управления соответственно дочерними окнами и членами семейства.
Окно члена семейства SDI, которое требует доступа к объектам главной формы, таким как меню, должно включать ссылку на файл главного модуля.
Правильное обслуживание окон членов семейства главным окном — это задача программирования на уровне главной формы.
В Репозитории имеется основная скелетная структура SDI. Этот шаблон уже снабжен набором компонентов визуальных и не визуальных, сконфигурированных так, чтобы у вас имелся исходный пункт для разработки приложения. По умолчанию на шаблоне приложения устанавливается меню, компонент OpenDialog, SaveDialog, ImageList, ActionList. В шаблоне организована строка состояния и окно About.
Программный код шаблона показан ниже:
procedure TSDIAppForm.FileNew1 Execute(Sender: TObject);
begin
{ Do nothing }
end;

procedure TSDIAppForm.FileOpen1 Execute(Sender: TObject);
begin
OpenDialog.Execute;
end;

procedure TSDIAppForm.FileSave1 Execute(Sender: TObject);
begin
SaveDialog.Execute;
end;

procedure TSDIAppForm.FileExit1 Execute(Sender: TObject);
begin
Close;
end;

procedure TSDIAppForm.HelpAbout1 Execute(Sender: TObject);
begin
AboutBox.ShowModal;
end;

end.

Циклы в Delphi
Важным аспектом программирования является использование циклов. Они позволяют заменять повторяющиеся действия. Циклические структуры позволяют многократно выполнять заданный блок операторов, но в то же время циклы относятся к наиболее сложным аспектам программирования, так как от правильной организации цикла зависит правильный результат ваших действий.
Object Pascal имеет в своем распоряжении различные структуры управляющих конструкций, среди которых циклы while, repeat, for.
Цикл — это программная структура, используемая для описания и выполнения повторяющейся группы операторов.
Все циклические структуры имеют общие характерные особенности, к которым относятся:
— условие цикла;
— его инициализация;
— итерация цикла;
— завершение цикла;
— тело цикла.
Условие цикла — это элемент, управляющий повторением действий. Оно определяет, продолжать итерации в цикле или прекратить их выполнение. В каждой итерации проверяется условие цикла.
Различие типов циклов заключается в том, когда происходит проверка условия. В самом начале условие проверяется в циклах while и for, в конце — для цикла repeat.
Специальные циклы могут предусматривать проверку условия в середине цикла. Если условие продолжения цикла выполняется, то продолжается еще одна итерация. В случае невыполнения условия происходит завершение цикла.
Перед выполнением цикл должен быть инициирован. Необходимо обеспечить правильное функционирование цикла, а для этого нужно инициировать все счетчики итераций, определить условие выхода для обеспечения предсказуемости цикла.
После каждой итерации должно происходить увеличение числовых значений данных, их уменьшение или другие действия, связанные с изменениями, возможно проведение каких-либо событий. Необходимо следить за тем, чтобы не происходило зацикливание операций, т.е. бесконечного их повторения.
Бесконечный цикл — это цикл, который никогда не прекращается, повторяя итерации до бесконечности. Как правило, бесконечный цикл является результатом программной ошибки. Проявление бесконечности цикла происходит в отсутствии реакции на ваши действия и зависании компьютера.
Обычно организуется счетчик выполнения цикла — это переменная целого типа, значение которой увеличивается или уменьшается при каждой итерации. Возможны и другие варианты.
Факт прекращения итераций предполагает не обязательное знание их числа, так как условие выхода может быть организовано по достижению значения какой-либо величины или действия. Но в этом случае вы должны предусмотреть условия выхода, в случае не достижения заданной величины в процессе работы. Прекращение работы цикла должно быть в любой ситуации.
Операторы, которые выполняются внутри цикла, называют телом цикла.
Тело цикла может представлять собой простой или структурный оператор. Оно выполняется столько раз, сколько предписывает условие повтора.

Цикл for
Он представляет собой цикл со счетчиком. Переменная, образующая счетчик, хранит количество итераций, которые будут выполняться в цикле. Повторение итераций происходит до тех пор, пока значение счетчика не изменится от начальной величины до величины заданной, называемой конечной.
Циклы for делятся на два вида: с увеличением счетчика и уменьшением счетчика.
Рассмотрим пример цикла for с увеличением счетчика.
Синтаксис такого счетчика имеет следующий вид:
for СчетчикЦикла: = НачальноеЗначение to КонечноеЗначение do
begin
Оператор1;
Оператор2;

ОператорМ;
end;
Для организации такого счетчика необходимо, чтобы начальное значение было меньше или равно конечному значению, иначе ни одна итерация цикла не выполнится. Величина счетчика цикла увеличивается на единицу после каждого прохода цикла.
1. Запустите Delphi.
2. Поместите на форму три компонента Edit. Edit1 используйте для ввода начального значения счетчика цикла, Edit2 используйте для ввода конечного значения счетчика цикла. Результат проведенных вычислений поместите в компонент Edit3.
3. Поместите на форму компонент Button1. Используя свойство Caption, введите заголовок "Решение". Поместите компонент Button2, используя свойство Caption, введите заголовок "Очистить". Щелчок по кнопке Button2 будет обнулять содержимое компонента Edit3. Запишите программный код:
procedure TForm1.Button1Click (Sender: TObject);
var
I:Integer;
X,Y:Integer;
begin
X:= StrToInt(Edit1.Text);
Y:= StrToInt(Edit2.Text);
for I:= X to Y do
X:= X + 1;
Edit3.Text:= IntToStr(X);
end;

procedure TForm1.Button2Click (Sender: TObject);
begin
Edit3.Text:= '';
end;

end.
Оператор for обеспечивает выполнение тела цикла до тех пор, пока не будут перебраны все значения параметра цикла от начального значения до конечного значения. После каждого повтора значение параметра цикла увеличивается на единицу.
Синтаксис цикла for с уменьшением значения счетчика:
for СчетчикЦикла: = НачальноеЗначение downto КонечноеЗначение do
begin
Операто1;
Оператор2;

ОператорМ;
end;
Величина начального значения должна быть больше или равна величине конечного значения, иначе не выполнится ни одна итерация цикла. Значение счетчика цикла уменьшается на единицу при каждом проходе цикла.
Поместите на форму компонент Edit1 и Button1. Запишите программный код для расчета некоторого значения:
procedure TForm1.Button1Click(Sender: TObject);
var
I,Min: Integer;
begin
Min:= 25;
for I:= 10 downto 1 do
Min:= Min — I;
Edit1.Text:= IntToStr(Min);
end;
end.
Цикл for начинается зарезервированным словом for. За ним следует оператор присваивания, инициирующий величину счетчика цикла. Переменная в левой части оператора присваивания — счетчик цикла. Это может быть произвольная переменная порядкового типа, обычно Integer. Справа от операции присваивания — выражение, задающее начальное значение счетчика цикла.
Переменная счетчика цикла — это обычная переменная, которая может иметь любое имя. Единственное ограничение состоит в том, что счетчик цикла должен быть обязательно объявлен, как и другие переменные, и объявлен локально — в той же области действия, что и цикл for.
Начальное значение, которое вы присваиваете счетчику, может быть любым, если оно совместимо с типом переменной величины в виде константы.
Вместо явного задания величины счетчика, можно применять произвольные выражения.
За инициализацией счетчика следует ключевое слово to или downto, которое определяет тип цикла: с возрастающим значением счетчика или с убывающим.
Далее следует конечное значение счетчика цикла, которое может быть задано явно или как переменная, или произвольное выражение, совместимое по типу с переменной счетчика цикла.
После конечного значения счетчика цикла следует зарезервированное слово do, а затем тело цикла. Если в цикле используется больше одного оператора, то все тело цикла заключается в блок begin — end.

Компонент ImageList
Этот компонент представляет собой контейнер с набором изображений одинаковых размеров. Ссылка на изображения производится по их индексам, которые начинаются с 0.
Многие компоненты (меню, списки, панели и т.д.) имеют в своих свойствах опцию Images, позволяющую внедрять изображения. Главное, что позволяет компонент — это экономное управление пиктограммами и битовыми матрицами.
Свойство property AllocBy: Integer; устанавливает дополнительное число изображений (образов), которыми список будет заполняться, когда необходимо создать место для новых изображений. По умолчанию установлено значение 4.
Свойство property BkColor: TColor; определяет цвет фона, на котором отображается пиктограмма.
Свойство property BlendColor: TColor; определяет цвет переднего плана изображения. BlendColor обеспечивает изменение цвета переднего плана изображения, когда будет установлено свойство DrawingStyle = dsFocus или dsSelected. Большее количество цветов свойства BlendColor объединено с изображениями, когда DrawingStyle = dsSelected. ClNone не определяет никакой цвет, в то время как clDefault определяет основной цвет системы.
Свойство property Height: Integer; определяет высоту изображений в списке изображений. Размер высоты изображения необходимо определять перед внедрением их в компонент ImageList. Если вы введете новый размер, в то время как изображения внедрены, то компонент ImageList окажется пустым. В этом случае вам придется вновь добавлять новые пиктограммы.
Свойство property ImageType: TImageType; определяет, использует ли список изображений маску изображений или не использует.
type TImageType = (itImage, itMask); если установлено itImage — рисует изображение, если установлено itMask — рисует маску.
Свойство property Masked: Boolean; определяет, включает ли список изображений маски, которые могут быть объединены с изображениями (образами). Замаскированная часть bitmap будет прозрачной или заменена цветом, указанным в свойстве BkColor.
Свойство property Width: Integer; определяет ширину изображений в списке изображений.
Свойство property Count: Integer; определяет число изображений в списке изображений.
Изображения в компонент могут быть загружены в процессе проектирования с помощью редактора списков изображений. Окно редактора вызывается двойным щелчком по компоненту ImageList.
Необходимо учесть, что при добавлении изображения в список открывается окно, в котором вы выбираете интересующий вас файл. Как правило, это пиктограммы, помещаемые на кнопки, элементы меню и т.д. Эти изображения имеют не одно, а два и более изображений. В этом случае при попытке добавить изображение появляется окно с запросом "Размерность изображения bookshut. bmp больше размерности списка. Разделить на две битовых матрицы?". Если вы ответите отрицательно, то все изображения уменьшатся в горизонтальном размере и лягут на одно изображение. Изображение нельзя будет использовать дальше. Поэтому всегда отвечайте на заданный вопрос положительно. Произойдет разделение битовой матрицы на отдельные изображения, в дальнейшем ненужные вы можете удалить с помощью кнопки Delete.
В редакторе списков изображений вы можете после выделения того или иного изображения установить свойства Transparent Color и Fill Color.
Свойство Transparent Color определяет цвет, используемый в маске для прозрачного рисования изображения. Для пиктограмм данное свойство устанавливается в clNone.
Свойство Fill Color определяет цвет для заполнения пустого пространства при перемещении и центрировании изображения. Для пиктограмм данное свойство устанавливается в clNone.
Радиокнопки Options определяют способ размещения изображения битовой матрицы с размерами, не соответствующими размерам, принятым в списке.
Опция Group позволяет отображать часть изображения, помещающегося в размер списка, начиная с левого верхнего угла.
Опция Stretch определяет размеры изображения, равные размерам списка, но при этом возможны искажения.
Опция Center позволяет изображению располагаться в центре списка. Если его размер больше размера списка, то не помещающиеся области отсекаются.

Владимир Скуратов



Компьютерная газета. Статья была опубликована в номере 12 за 2002 год в рубрике программирование :: delphi

©1997-2024 Компьютерная газета