MDI - Многодокументный интерфейс
MDI - Многодокументный интерфейс
Существуют два основных стиля интерфейсов пользователя: интерфейс с одним документом (single-document interface, SDI) и интерфейс со многими документами (multiple-document interface, MDI). Текстовый редактор с интерфейсом SDI позволяет открыть только один документ - чтобы открыть другой, следует закрыть предыдущий. В приложении MDI Вы можете открыть сразу несколько документов.
Контейнер для форм
В приложение Visual Basic можно добавить MDI форму, которая будет служить контейнером для подчиненных форм. Подчиненная форма - это обычная форма, у которой значение свойства MDIChild равно True. В режиме выполнения подчиненные окна помещаются внутри родительского окна MDI формы. Меню команд MDI формы может быть общим для всех подчиненных окон, или, если подчиненная форма имеет собственное меню команд, оно замещает меню формы контейнера. При закрытии формы-контейнера закрываются все подчиненные формы.
В приложении MDI можно открыть много окон построенных по одному образцу. При этом в режиме проектирования создается один экземпляр формы. Для того чтобы в режиме выполнения открыть много окон в коде программы создаются новые экземпляры подчиненной формы.
Dim NewDoc As New Form1 ' Создать новый экземпляр формы NewDoc.Show ' Показать на экране
Поскольку много подчиненных форм имеют одинаковое имя и одинаковый код, то не следует в коде программы (если код используется несколькими экземплярами формы) использовать имя формы. В модуле формы для ссылок на текущую форму используйте ключевое слово Me.
Unload Me ' Выгрузить текущую форму
На форму MDI можно поместить управляющий элемент, если он имеет свойство Align (Выстроить) или является невидимым в режиме выполнения.
Создадим Текстовый редактор
Простой текстовый редактор имеет интерфейс MDI.
Создайте форму-контейнер командой Add => MDI Form, меню Project.
На форме Form1 создайте текстовое поле Text1 и установите для него свойство Multiline в True, Top и Left в 0.
Свойство MDIChild установите в True.
Создайте процедуру Form_Resize, чтобы размеры текстового окна изменялись при изменении размеров формы:
Text1.Height = Me.ScaleHeight Text1.Width = Me.ScaleWidth
Создайте меню Файл для формы MDIForm1. В процедуру создания нового документа добавьте код:
Option Explicit Private Sub mnuNew_Click() Dim NewDoc As New Form1 ' Создать новый экземпляр формы. Static n As Integer ' Статическая переменная сохраняет значение после завершения работы процедуры NewDoc.Show ' Показать на экране окно нового документа n = n + 1 ' Увеличиваем значение переменной на 1, при создании еще 1 экземпляра MDIForm1.ActiveForm.Caption = Left(MDIForm1.ActiveForm.Caption, 4) + CStr(n) End Sub
Код дочерней формы Form1:
Option Explicit Private Sub Form_Resize() Text1.Height = Me.ScaleHeight Text1.Width = Me.ScaleWidth ' Необходимо использовать ключевое слово Me ' Так как последующий экземпляры класса будут работать не корректно End Sub
Создайте новый пункт в меню Файл => Окна. Установите свойство WindowList - для отображения списка доступных окон, это свойство доступно лишь для MDI и подчиненных форм.
Меню в приложениях MDI
Обычно используется несколько наборов меню. Когда закрыты все документы, отображается меню MDI формы. Когда пользователь открывает документ, меню команд подчиненной формы замещает меню MDI формы. Панель инструментов располагается всегда в MDI форме.
Таким образом, некоторые команды могут быть в меню формы контейнера, в меню подчиненной формы и на панели инструментов. Чтобы не дублировать код, нужно создать открытую процедуру в подчиненной форме и вызывать ее из процедуры обработки событий.
Форма-контейнер может содержать несколько типов документов.
В меню Файл, MDI формы добавим пункт Новый Документ.
Меню команд подчиненной формы также содержит эту команд. Нужно написать процедуру создания нового документа и процедуры обработки для команд меню.
Код MDI формы:
Option Explicit ' Объявляем глобальную переменную для нумерации документов Public n As Integer
Код подчиненной формы:
Option Explicit Private Sub Form_Resize() Text1.Height = Me.ScaleHeight Text1.Width = Me.ScaleWidth End Sub Public Sub NewFile(m As Integer) Dim NewDoc As New Form1 NewDoc.Show m = m + 1 MDIForm1.ActiveForm.Caption = Left(MDIForm1.ActiveForm.Caption, 4) + CStr(m) End Sub Private Sub mnuNew_Click() NewFile MDIForm1.n End Sub
Загрузка и выгрузка форм MDI и подчиненных форм
При загрузке подчиненной формы автоматически загружается и форма MDI. Однако при загрузке формы MDI, подчиненные формы автоматически не загружаются. Это можно увидеть, установив в качестве стартового объекта MDI форму. Можно загрузить подчиненные формы как скрытые, установив значение свойства AutoShowChildren в True и отобразить их в нужный момент методом Show.
Выгрузка формы выполняется по команде Unload в коде программы или при закрытии окна.
При этом выполняются обработки событий QueryUnload и Unload для формы, в которых можно отследить сохранение введенных данных. При выгрузке MDI формы выгружаются и все подчиненные формы. Команда End вызывает немедленное завершение программы, при этом не выполняется процедуры обработки событий.
Проверка были ли сохранены данные
В приложении MDI отслеживается сохранение данных. Если есть не сохранные данные при завершении работы программы или при закрытии одного документа, то данные могут быть сохранены по умолчанию.
Для получения информации о состоянии документа в модуле подчиненной формы введем логическую переменную:
Public fs As Boolean
Переменная fs получает значение True при любых изменениях в текстовом поле.
Private Sub Text1_Change() fs=True End Sub
Пусть сохранение документа выполняется в процедуре SaveFile. Переменная fs получает значение False после сохранения документа.
Private Sub SaveFile() : fs=False End Sub
Если при закрытии документа fs равно True, то функцию MsgBox выводит вопрос и возвращает ответ пользователя. Если ответ был Yes, то выполняется процедура SaveFile.
Private Sub Form_QueryUnload(Cancel As integer, UnloadMode As Integer) If fs Then If MsgBox("Сохранить файл?", vbYesNo)=vbYes Then SaveFile End If End Sub