Windows используются два вида приложений - это однодокументные и многодокументные. По названию можно догадаться, что в однодоментном приложении можно работать только с одним документом. Примером может быть хорошо известный windows блокнот. Да и почти все примеры на данном сайте тоже являются однодокументными приложениями.
Многодокументное приложение может использовать в своей работе несколько документов. Примером может быть Microsoft Word и Excel.
В многодокументном окне главная форма может содержать несколько дочерних окон. Свойство FormStyle определяет какой будет форма (главной или дочерней). Главная форма может быть только одна и свойство FormStyle должно быть fsMDIForm, а для дочерних форм - fsMDIChild.
В главной форме лучше не использовать такие средства управления как кнопки, таблицы строк и надписи, т.к. они будут мешать при просмотре дочерних форм. В интерфейс для главной формы лучше включать: меню, строку состояния, панель инструментов. Остальная незанятая область будет использована для дочерних форм.
Если при запуске приложения нам не требуется создание экземпляра дочернего окна, то его создание лучше организовать динамически, во время создания приложения.
Для лучшего понимания темы создадим приложение состоящее из 2-х форм. Первой присвоим, используя Инспектор Объектов, заголовок "Главная форма", имя - MainForm, FormStyle - fsMDIForm. Для второй "Дочерняя форма", ChaildForm, fsMDIChild - соответственно. На первую форму помещаем объект меню и задаем такие пункты как на рисунке внизу.
На вторую форму помещаем компонент SaveDialog, кнопку, memo, образцу:
Для того чтобы второе окно создавалось динамически, в процессе работы приложения, нужно через меню Delphi Project -> Options открыть вкладку Forms. В левой части окна, под надписью Auto-create forms перечислены формы, создаваемые автоматически, в правой части формы, под надписью Available forms, будут располагаться формы, которые необходимо создавать вручную (т.е. программисту необходимо написать код).
Ниже следующий код мы поместим в обработчик меню "Файл" главной формы:
procedure TMainForm.N2Click(Sender: TObject); begin ChaildForm:=TChaildForm.Create(Application); end;
Запустив приложение и нажав на "Файл" мы создадим вторую форму, при повторном нажатии и далее будут создаваться дочерние формы. Но если мы захотим закрыть ненужную нам дочернюю форму, нажав на крестик, как обычно для windows приложений, то у нас получиться только свернуть форму.
Для закрытия дочерней формы нам понадобиться прописать в обработчике onClose формы свойство Action := caFree;
Свойство Action может принимать значение caNone - ничего не делать, caMinimize - свернуть окно (это значение используется по умолчанию), caFree закрыть окно.
У нас на дочерней форме расположен компонент, в который мы будем печатать текст и чтобы случайно не потерять набранное мы будем делать проверку. Обработчик закрытия формы будет следующим:
procedure TChaildForm.FormClose(Sender: TObject; var Action: TCloseAction); begin if Memo1.Modified then begin if MessageDlg('Текст не сохранен! Закрыть окно?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then Action := caFree ; end else Action := caFree; end;
Для сохранения содержимого нашего редактора напишем такой обработчик кнопки:
procedure TChaildForm.BitBtn1Click(Sender: TObject); begin if SaveDialog1.Execute then Memo1.Lines.SaveToFile(SaveDialog1.FileName); end;
Дочерние окна, при таком создании, могут отличаться по размеру от первоначально установленных. Если это критично, то можно задать высоту и ширину такой какая необходима в обработчике создания формы:
procedure TChaildForm.FormCreate(Sender: TObject); begin Height:= 231; Width := 410; end;
Дочерние формы по умолчанию размещаются каскадом. Для пункта меню главной формы "Каскад" напишем обработчик:
procedure TMainForm.N4Click(Sender: TObject); begin Cascade; end;
Дочерние формы могут располагаться мозаикой. Для этого свойство формы будет Tile. При мозаичном расположении мы можем дочерние окна разметить по всей ширине или по всей высоте клиентской области. Это определяет свойство TitleMode (tbHorizontal - вся ширина, tbVertical - вся высота).
Для того чтобы дочерние формы располагались мозаикой и располагались во всю длину клиентской области пункт меню главной формы "Мозаика" будет таким:
procedure TMainForm.N5Click(Sender: TObject); begin Tile; TileMode := tbVertical; end;
Итог: мы познакомились с многодокументными приложениями и их возможностями.