Программирование на C++ Builder

 


SDI MDI


Окна в C++ Builder

Мы уже умеем создавать программу с одним окном. Теперь посмотрим как создавать много оконные программы. Для начала надо определить кого типа будет ваше приложение. На сегодняшний день существуют два типа приложений SDI (single-document interface ) и MDI (multiple-document interface). SDI-приложения имеют одно главное окно могут отображать другие окна, не привязанные к главному. MDI-приложения имеют главное окно (MDI-предок) и связанные с ним подчиненные окна (MDI-потомки). Типичный пример MDI-приложения - WORD. Давай рассмотрим процесс создания MDI и SDI приложений.

Свойства формы

Для начало познакомимся поближе с формой. Класс TForm имеет много свойств. Наиболее часто используемые отображены в инспекторе объектов. Давайте рассмотрим некоторые из них.

ActiveControl: это свойство используется для выбора элемента на который будет активен при открытии окна. Выбрать элементы можно в выпадающем списке в инспекторе объектов.

AutoScrol, HorizScrollBar, VertScrollBar: эти свойства предназначены для управления линейками прокрутки.

BorderStyle: определяет тип рамки вокруг формы. Поумолчанию bsSizeable т.е. окно с изменемыми размерами. bsDilog, bsNone используются для фиксации размеров окна.

ClientWidth, ClientHeight: эти свойства указывают высоту и ширину рабочей области окна.

Font: определяет тип шрифта. Если в инспекторе объектов два раза щелкнуть в правом столбце , откроется диалоговое окно, для изменения шрифта.

FormStyle: стиль формы. Обчно значение Normal. Формы MDI должны быть типа fsMDIForm,а подчиненные формы типа fsMDIChild.

Icon: определяет значок, который будет в заголовке формы при выполнении программы.

В инспекторе объектов отображаются далеко не все свойства компонентов. Не которые свойства доступны только во время исполения программы.

Handle: возвращает дескриптор окна (HWND). Используется при обращении к API функциям.

MDIChildCount: возвращает количество открытых MDI окон.

ModalResult: используется для закрытия модального (подчиненного) окна. Обычно возвращает значение кнопки которая была нажата.

Name - имя формы (экземпляра класса)

Owner: это свойство- указатель на владельца формы( объект отвечающий за ее уничтожение).

Parent: указатель на порождающий объект. Порождающий объект - это объект, который содержит данный компонент.

Методы формы

BringToFront() - расположение данной формы поверх остальных окон.

Close() - закрывает форму предварительно вызывая CloseQuery(), который проверяет возможность нормального закрытия. CloseQuery() в свою очередь вызывает обработчик события OnCloseQuery и если переменная переданная обработчику имеет значение false, то форма не закроется.

SetFocus() - активизтирует форму и помещает ее поверх других.

Show() - отображает форму как немодальную.

ShowModal() - отображает форму модально.

События формы все отображены в инспекторе объектов ( вкладка Events )и имеют понятные имена.

Пример MDI и SDI прораммы

Теперь напишем маленькую программку, где реализуем обе технологии создания окна. По технологии SDI мы создадим окно About, а по технологии MDI окна для вывода картинок.

SDI

Итак окно About.

Теперь напишем обработчик события для кнопки:

Осталось только написать код. Вредакторе кода появилась новая функция:
(void __fastcall TForm1::Button1Click(TObject *Sender))
и курсор мигает как раз в теле функции. Введите следующее:
About->Show();
и запустите. В данном примере при появлении окна About можно активизировать окно главной формы, но если вместо метода Show() воспользоваться методом ShowModal(), вы не сможете активизировать главное окно до тех пора, пока не закроете окно About (как обычно и делается с подобными информационными окнами).

Ну что, технологию однодокументного интерфейса мы освоили. Для создания многодокумментного интерфейса (MDI) будим использовать нашу программу в качестве каркаса.

MDI

Для начала необходимо поменять свойства основной формы, а точнее нужно помять значение свойства FormStyle с fsNormal на fsMDIForm . Я думаю, пока понятно что происходит.
Теперь добавим меню. Вы еще незабыли, что наша прорамма будет показывать растровые изображения? В C++ Builder меню тоже выполнено в виде компонента. Находится компонент меню во вкладке Standard и называется MainMenu

Подготовительные действия проведены, теперь давайте напишем код соответвующий каждому пункту меню.

<p>void __fastcall TForm1::Open1Click(TObject *Sender) { if (OpenDialog-&gt;Execute()) { TMdiWin *MdiWin = new TMdiWin(Application); MdiWin-&gt;Image-&gt;Picture-&gt;LoadFromFile(OpenDialog-&gt;FileName); MdiWin-&gt;ClientWidth= MdiWin-&gt;Image-&gt;Picture-&gt;Width; MdiWin-&gt;ClientHeight =MdiWin-&gt;Image-&gt;Picture-&gt;Height; MdiWin-&gt;Caption = OpenDialog-&gt;FileName; MdiWin-&gt;Show(); } } Для пункта Exit меню File создайте следующий обработчик : void __fastcall TForm1::Exit1Click(TObject *Sender) { Close(); } А для Help / About следующий: void __fastcall TForm1::About1Click(TObject *Sender) { About-&gt;ShowModal(); }

Теперь создадим само подчиненное окно. Для этого создайте новую форму (File/New Form ), измените поле Name на MdiWin, измените свойство FormStyle на fsMDIChild. Теперь необходимо поместить в эту форму компонент Image:

Теперь запишите новую форму ( File / Save As ) под названием MdiForm
В редакторе кода перейдите к файлу основной формы ( у меня это Unit1.cpp) и включите в него заголовочный файл подчиненной формы ( File / Include Unit Hdr и выберите MdiForm ) .

Почти все, но есть одна проблема. Дело в том что C++ Builder автоматически создает все окна, т.е. при запуске приложения у нас всегда изначально будет одно пусто подчиненное окно. Исправить это легко:

Теперь можно запустить наше приложение. Если все прошло нормально то ваше приложение сможет показывать растровые изображения в формате .bmp, .wmf, .ico. Но немного поработав вы обнаружите две вещи:

Кнопку About можно просто удалить, но при этом ваше приложении будет содержать весь ненужный код, относящийся к ней. Если это вас не устраивает, то вам придется удалить обработчик события этой кнопки и все объявления связанные с ней в заголовочном файле формы, это строка типа: void __fastcall Button1Click(TObject *Sender); в объявлении класса формы. В общем если вы что-то забыли удалить, то компоновщик вам напомнит об этом сообщением об ошибке.

Пришло время разобратся: как все же создаются MDI окна?

Начнем с начала. Мы создали форму MdiWin, там самым создав класс TMdiWin, который и определяет все наши подчиненные окна, и придали ему свойство fsMDIChild.

Далее в обработчике пункта меню Open мы собственно и создаем подчиненные окна строками: TMdiWin *MdiWin = new TMdiWin(Application); и MdiWin- >Show(); .

И последнее: если ни как не описать закрытие подчиненных окон, то по умолчанию они будут просто сворачиваться при попытке их закрыть. Для того чтобы они закрывались, создадим обработчик:

Весь исходный код программы находится в файле sdimdi.zip

В начало страницы

Содержание