Главная » C++, C++ Builder » Великое изменение — переход к многодокументным формам C++ Builder

0

Я хочу рассказать вам грустную, но абсолютно правдивую историю из своего программистского прошлого. Как-то несколько лет назад работал я в небольшой компании, разрабатывающей программные продукты. Мы получили задание конвертировать уже  написанную программу под MS-DOS в приложение под Windows 3.1, используя для этого Visual C++ и MFC. После переговоров с менеджером по продажам и клиентами нам было велено разрабатывать программу, используя однодокументный (Single Document Interface, SDI) каркас. И я, и другие программисты нашей группы несколько раз спрашивали у них, уверены ли они в том, чего хотят, но они твердо стояли на своем. Складывалось ощущение, что человек, который проектировал программу, никогда не работал в среде Windows и в принципе не знаком с концепцией многодокументного интерфейса. В результате мы провели шесть месяцев, разрабатывая действительно неплохой программный продукт на основе однодокументной модели.

Но вот шесть месяцев закончились, и продукт наконец был готов к системному тестированию. Было приглашено несколько человек из главного управления, в котором слышали хорошие отзывы о нашей программе. Наверное, вы можете угадать конец истории. Один из старших менеджеров, который работал-таки в Windows (то есть просто использовал Word и Excel), взглянул на интерфейс нашей программы и сказал: «Неплохо. Сделайте-ка его многодокументным приложением».

Примерно неделю  мы пытались переделать уже готовое приложение в многодокументное. Проблема состояла в том, что нам надо было изменить все имена классов. Все описания единичного документа тоже должны были быть изменены. В конце концов при помощи мастера приложений Visual C++ было создано совершенно новое многодокументное приложение, в которое по кусочкам были скопированы подходящие строки кода.

Вы спросите — в чем же мораль? Что вы должны лучше клиента знать, что ему надо? Возможно. Но тут есть одна небольшая проблема, связанная с тем, что обычно именно клиенты (или ваши шефы) платят за работу, и поэтому они подразумева ют, что все делается так, как им хочется. Если они передумали, ваша проблема переделать все заново, а не их.

К чему я клоню? Ну, давайте предположим, что ваш босс после демонстрации чудесного программного продукта Scribble вызывает вас к себе и заявляет:  «Отличная  работа.  Сделайте теперь вашу программу многодокументной, чтобы можно было рисовать сразу  в  нескольких окнах. И чтобы изменение в одном отражалось и в остальных». Если бы вы использовали старый продукт типа Borland C++ или Visual C++, вам бы пришлось прийти к тому же решению, что и моей группе разработчиков когда-то: переписать все заново, а потом вставить соответствующие

куски кода из старой версии. К счастью, вы занимаетесь разработкой не в Visual C++ и MFC, и не в Borland C++ и OWL. Вы имеете счастье использовать CBuilder.

В следующем примере мы собираемся переделать Scribble из одного-единствен ного окна, как сейчас, в многодокументное приложение. Вы будете приятно удивлены  тем,  как  просто произойдет это изменение, особенно если у вас есть печальный опыт работы с другими системами.

В чем различие?

Первым важным аспектом, на который следует обратить внимание, переходя к многодокументным приложениям на CBuilder, является отсутствие принципиаль ной разницы между окном многодокументного приложения и обычным окном. Окна многодокументных приложений бывают двух типов — родительского (parent) и дочернего (children). В каждом многодокументном приложении, как правило, существует одно родительское окно, которое является «рамкой», ограничивающей размер приложения на экране, в поле которой располагаются дочерние окна.

В каждом таком приложении может быть (и обычно есть) много дочерних форм, которые могут быть как одного, так и различных типов. Вполне может существовать, например, многодокументное приложение, в котором будет пять дочерних окон, и все разных типов форм. Я, честно говоря, не очень понимаю, зачем вам может такое понадобиться, но если все-таки вы решитесь на что-либо подобное, CBuilder позволит вам осуществить задуманное.

Рис. 2.6. Многодокументное приложение Scribble

На  рис. 2.6  показано  приложение,  которое  мы  будем  разрабатывать.  В  данном  случае  окном-

«рамкой» будет являться главное окно приложения, содержащее главное меню. Дочерними окнами будут окна Scribble. С точки зрения разработки дизайна, нет почти что никакой разницы между дочерним окном Scribble и отдельно взятым главным окном приложения Scribble, которое мы использовали до сих пор.

На самом деле, если бы мы не хотели, чтобы все окна использовали один и тот же список точек, мы могли бы просто использовать формы из предыдущего примера.

Проводим  преобразования

Первое, что надо сделать для преобразования приложения из одно- в многодокумент  ное,  это понять, в чем же отличие родительской или дочерней формы многодокумен тного приложения от

нормальной формы. Отличие находится в одном-единственном свойстве формы, а именно в свойстве Form Style (стиль формы). Для большинства форм в ваших приложениях свойство Form Style имеет значение fsNormal, которое обозначает, что форма является простым окном, которое мы можем рассматривать как некое нами же определенное диалоговое окно. Для форм многодокументного приложения свойство Form Style устанавливается в fsMDIForm для родительской формы или в fsMDIChild для дочерних форм.

Если форма имеет тип fsMDIForm, то автоматически она создается  с одним дочерним  окном, которое будет первым образцом дочерней формы в проекте. Форма стиля fsMDIChild  будет создана внутри границ родительской формы приложения.

Первым шагом на пути преобразования нашего приложения Scribble в многодокументное станет добавление в приложение новой формы, которая будет единым родителем для всего приложения. Итак, добавьте новую форму и установите ее свойство Form Style  в  fsMDIForm.  Добавьте  в новую форму меню, а в него добавьте два новых пункта с названиями Файл и Вид. В пункт меню Файл добавьте два подпункта — Новый и Выход. В пункт меню Вид добавьте один-единственный подпункт — Обновить все.

Команда Файл – Новый будет использоваться для создания в приложении новых дочерних форм. Команда Файл – Выход предусмотрена для «чистого» выхода из приложения. И наконец, команда Вид – Обновить все будет перерисовывать все дочерние формы так, что у всех у них поля рисования будут отображать одну и ту же картинку.

Выберите форму для рисования из программы Scribble и измените ее стиль на fsMDIChild. Это будет основная форма просмотра в нашем приложении. Несмотря на то что нам придется сделать несколько изменений для корректного сосуществования нашей формы с остальными формами, основная часть кода для окна Scribble останется неизменной. Итак, все, что требуется для преобразования формы из независимой в дочернюю, — это изменить свойство Form Style.

Замечание

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

Следующим шагом надо убедиться, что главная форма  создается  первой  в  порядке автоматического создания форм, осуществляемом CBuilder. Для изменения  порядка  создания форм откройте окно Project Manager (View – Project Manager) и выберите в нем кнопку Options (опции). В списке автоматически создающихся форм щелкните на названии Form2 и, не отпуская кнопку мыши, перетащите ее на самый верх списка, перед названием Form1. Вот и все. Когда вы запустите программу, форма Form2 (главная форма многодокументного приложения) будет создана первой, а дочерние формы (Form1, форма рисования из примера Scribble) будут создаваться после нее, уже как дочерние формы единой родительской.

Каждая форма в системе должна знать об остальных формах, соответственно, нам надо сообщить им друг о друге. Для этого выберите главную форму (Form2) и команду File – Include Unit Hdr. Вы увидите список, в котором находится название формы Form1. Выберите его  и  щелкните кнопку OK. Теперь повторите все для формы Form1 и включите заголовок формы Form2.

Замечание

Когда вы включаете заголовок другой формы, вы автоматически получаете возможность использовать объекты, в нем определенные, в своей форме. Если вы взглянете в конец заголовочного файла для формы Form2 (Unit2.h), вы увидите строку следующего содержания:

extern TForm2 *Form2;

Эта строка позволяет вам использовать объект Form2 в других формах или объектах, просто включив заголовочный файл. Этот изящный штрих,  добавленный  разработчиками  системы CBuilder, лишний раз показывает стремление их максимально облегчить жизнь программиста.

Итак, у нас есть родительская и дочерняя формы многодокументного приложения. Теперь можно скомпилировать и запустить приложение, и вы увидите главную форму. Дочернее  окно, находящееся внутри границ главного, — это форма рисования Scribble, в которой можно, нажав левую кнопку мыши и перемещая мышь по полю формы, рисовать веселые картинки. Не верите — попробуйте сами.

Источник: Теллес М. – Borland C++ Builder. Библиотека программиста – 1998

По теме:

  • Комментарии