Интерфейс множества документов MDI

Автор: Михаил Христосенко // Development и Дельфи (http://delphid.dax.ru)

Немного расскажу о том, что же это за интерфейс такой - MDI (Multi Document Interface). Одним из наиболее типичных программ такого типа является всем знакомый Microsoft Word. В приложениях MDI всегда имеется одна главная (родительская) форма и несколько дочерних форм. Следует заметить, что новые окна могут создаваться  самим пользователем в процессе работы программы и их число неограниченно. Все дочерние формы располагаются в области главной формы. Как правило на главной форме располагаются только главное меню, панель инструментов, и строка состояния, оставляя тем самым все остальное место для дочерних форм. Также часто главная форма при запуске развертывается на весь экран.

Для создания приложения MDI необходимо создать и спроектировать главную и дочернюю формы. В главной форме свойство FormStyle необходимо установить в fsMDIForm, а  в дочерней это же свойство надо сделать равным fsMDIChild. Также дочерние окна надо исключить из списка создаваемых автоматически (Project->Options; далее с помощью стрелок перенести формы из Auto-Create forms, в Available forms).

Теперь рассмотрим процесс создания дочерних форм во время работы программы. Для этого создайте новый проект (New->Application). Главную форму назовите Fmain, теперь создайте еще одну форму (New->Form), назовите ее FDoc. Не забудьте установить свойство FormStyle у обеих форм и  убрать форму FDoc из списка создаваемых автоматически!!! Сохраните только что созданный проект, модуль, содержащий первую форму назовите Umain.pas, а модуль со второй формой назовите Udoc.pas. Теперь вам необходимо добавить в Uses главной формы имя модуля UDoc. Теперь поставьте на форму кнопку, при нажатии на которую будут создаваться новые дочерние окна. Обработчик нажатия на нее может иметь такой вид:

procedure TFMain.Button1Click(Sender: TObject);
var NewF:TFdoc;
begin
NewF:=TFDoc.Create(Application);
NewF.Caption:='Новая дочерняя форма';
NewF.show;
end;

Для управления дочерними форма у родительской формы есть ряд свойств и методов. Все свойства доступны только для чтения и во время работы программы.

Свойство MDIChildCount позволяет определить сколько дочерних форм открыто. Свойство MDIChildren[i:integer]; позволяет получить доступ к дочернему окну с индексом i. В качестве примера попробуем сделать так, чтобы при создании новых дочерних окон в нашей программе, они получали свои порядковые номера. Тогда строчку, где форме присваивается заголовок (Caption), надо заменить на:

NewF.Caption:='Новая дочерняя форма № '+inttostr(MDIChildCount);

Чтобы закрыть (свернуть) все открытые окна, начинаю с последнего, поставьте на форму еще одну кнопку и в обработчике события OnClick напишите следующее:

procedure TFMain.Button2Click(Sender: TObject);
var i:integer;
begin
for i:= MDIChildCount-1 downto 0 do
MDIChildren[i].close;
end;

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

Если хотите можно поставить на форму несколько кнопок с заголовками приведенными выше, а можно создать меню, создать такие пункты в разделе окно. Сути это не играет, но когда вы используете меню, ваше приложение выглядит лучше. 

Обработчик события OnClick, для кнопки "Каскадом":

Cascade;

Обработчик события OnClick, для кнопки "Упорядочить по горизонтали":

TileMode:=tbHorizontal;

Tile;

Обработчик события OnClick, для кнопки "Упорядочить по вертикали":

TileMode:=tbVertical;

Tile;

Обработчик события OnClick, для кнопки "Упорядочить значки":

ArrangeIcons;

Осталось разобрать еще один вопрос. Необходимо, чтобы меню дочерних форм не появлялось в окнах документов, а встраивалось бы в меню главной формы. То есть на родительской формы находится только меню "Окно", а на дочерней форме - меню, например, "Файл", "Правка", "Найти", "Справка" и т.д. Свойство AutoMerge на это не влияет, но к счастью меню дочерней формы само встраивается в меню главной формы. Но за место, куда будет размещено меню дочерней формы отвечает свойство GroupIndex каждого из разделов меню. Например, чтобы на первом месте главного меню появилось меню дочерней формы "Файл" его свойство GroupIndex должно быть равно 0. Тогда свойство GroupIndex для раздела меню "Окно" главной формы должно быть равно 1.

Если кто-нибудь не понял чего-то из статьи привожу полный код того, что получилось у меня (главное меню я не использовал):

unit Umain;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TFMain = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Button6: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
FMain: TFMain;

implementation
uses UDoc;
{$R *.DFM}

procedure TFMain.Button1Click(Sender: TObject);
var NewF:TFdoc;
begin
NewF:=TFDoc.Create(Application);
NewF.Caption:='Новая дочерняя форма № '+inttostr(MDIChildCount);
NewF.show;
end;

procedure TFMain.Button2Click(Sender: TObject);
var i:integer;
begin
for i:= MDIChildCount-1 downto 0 do
MDIChildren[i].close;
end;

procedure TFMain.Button3Click(Sender: TObject);
begin
cascade;
end;

procedure TFMain.Button4Click(Sender: TObject);
begin
TileMode:=tbHorizontal;
Tile;
end;

procedure TFMain.Button5Click(Sender: TObject);
begin
TileMode:=tbHorizontal;
Tile;
end;

procedure TFMain.Button6Click(Sender: TObject);
begin
ArrangeIcons;
end;
end.



Опубликовал admin
17 Дек, Среда 2003г.



Программирование для чайников.