Главная » C++, C++ Builder » Добавление функциональных возможностей в Мастер

0

У нас создана основа, так сказать скелет Мастера, что, конечно, приятно, но отнюдь не выполняет возложенных на Мастер функций. Нам надо добавить в Мастер все те возможности, которые мы реализовали в только что написанном приложении. Как это сделать?

На    самом     деле     добавление     новых     возможностей     не     составит     большого     труда. В конце концов, у нас уже есть форма для получения всех необходимых данных и есть код, позволяющий сгенерировать новый класс компонента, базирующийся на этих данных. То есть вся работа уже сделана, и все, что нам надо, — это добавить форму и все остальные модули из предыдущего приложения в DLL, отобразить эту форму при вызове Мастера,  и  все  остальное будет сделано без нашего участия. Собственно, для этого-то мы и создавали форму сначала в простом приложении. Так гораздо проще тестировать функции, исправлять ошибки, короче говоря, доводить форму и остальные функции до удовлетворяющего нас состояния, а потом уже объединять их в полноценный Мастер CBuilder. В разработке любых приложений руководствуйтесь принципом — на каждом  этапе решать только одну задачу — и ваша жизнь станет веселее.

Скопируйте файлы формы и модулей из проекта приложения (кроме файла проекта, MAK-файла и промежуточных файлов компилятора) в новую директорию. После этого проделайте приведенные ниже преобразования кода Мастера. Естественно, больше всего изменений  придется  внести  в метод RunExpert, поскольку он отвечает за всю работу Мастера. Вот как выглядит код для этого метода:

__stdcall RunExpert( TIMenuItemIntf* )

{

TPagesDlg *frm; try

{

frm = new TPagesDlg(Application); Form1 = new TForm1(frm);

Form2 = new TForm2(frm); if( frm->ShowModal() )

{

TCreateModuleFlags mf;

mf << cmAddToProject << cmNewUnit << cmMarkModified; ToolServices->CreateCppModule(  frm->

SourceFile->Text,"","","", 0L, 0L, 0L, mf );

}

frm->Free();

}

catch(…)

{

HandleException();

}

}

В этом коде есть несколько вещей, на которые стоит обратить внимание. Во-первых, это использование блока try … catch по отношению ко всему коду метода для того, чтобы обезопасить пользовательскую систему — не дать возможной ошибке в Мастере просочиться на уровень IDE. Следующий небезынтересный момент — создание экземпляров всех форм системы непосредственно в функции RunExpert. Поскольку у DLL в отличие от приложений нет объекта application, нет, соответственно , и автоматического создания форм; поскольку  нет автоматического создания, вам надо создать формы самостоятельно до того, как вы будете их использовать. Если формы создать не удастся, VCL сгенерирует исключительную  ситуацию  и работа Мастера будет прекращена. Если формы были успешно созданы, мы идем дальше и модально отображаем первую из них, то есть на экране появляется обычный страничный диалог, позволяющий пользователю вводить данные для нового компонента — точно так же, как он это

делал в простом приложении.

После отображения формы следует блок кода, который является вызовом метода CreateCppModule объекта ToolServices. Этот вызов весьма важен — он добавляет  в  данный проект новый модуль, точно так же, как и CBuilder в своем «родном» Мастере компонентов. Для обеспечения совместимости нам также придется это сделать. Далее форма удаляется  вызовом метода Free базовой формы.

Небольшое отступление: объект ToolServices

Одним из наиболее важных объектов, использующихся при создании Мастеров, является объект ToolServices, который содержит методы для работы с самой IDE. В табл. 17.4  перечислены методы класса TIToolServices, экземпляром которого и является этот объект2.

Таблица 17.4. Методы класса TIToolServices

CloseProject Закрывает текущий проект

OpenProject Открывает новый проект, определенный в вызове

SaveProject Сохраняет текущий проект

CloseFile Закрывает редактируемый файл

OpenFile Открывает указанный файл в окне редактора

SaveFile Сохраняет редактируемый файл

ReloadFile Заново считывает редактируемый файл с диска

CreateModule Создает новый модуль (модули) в текущем проекте

CreateModuleEx То же самое, что и CreateModule, но с большим количеством опций GetParentHandle Возвращает ссылку (handle) родителя объекта, вызывающего метод GetProjectName Возвращает имя текущего проекта

GetUnitCount Возвращает количество модулей (unit) в текущем проекте

GetUnitName Возвращает имя указанного (по индексу) модуля (unit) в текущем проекте EnumProjectUnits Перебирает все модули (unit) в проекте, вызывая для каждого обработчик, определенный  пользователем

GetFormCount Возвращает количество форм в текущем проекте

GetFormName Возвращает имя указанной (по индексу) формы в текущем проекте

IsFileOpen Определяет, загружен ли указанный файл в редактор

GetNewModuleName Возвращает имя следующего модуля, используя стандартные для проекта обозначения (напр. Unit1,Unit2)

GetModuleCount Возвращает количество модулей (module) в текущем проекте GetComponentCount Возвращает количество компонентов, определенных в данной системе GetMainMenu Возвращает ссылку (handle) на главное меню системы IDE  CreateCppModule Создает в проекте новый файл CPP и (в зависимости от параметров) добавляет его в проект

RaiseException Позволяет программисту возбуждать исключительные ситуации приложения в системе

2  В данной главе слово «модуль» используется для обозначения двух различных терминов, module и unit. Термином module обозначают все модули системы, то есть исходный файлы, формы, DLL и т. п. Термин же unit означает пару из исходного файла (например, Unit1.cpp) и заголовочного (Unit1.h). Будьте бдительны! — Примеч. перев.

Как вы, наверное, поняли из таблицы, методы объекта ToolServices предостав ляют вам полный контроль над IDE. Имея в своем распоряжении подобные методы, вы можете посредством своих Мастеров добавить в систему любые новые возможности. Я думаю, что если вы привыкли самостоятельно создавать всяческие расширения для различных систем, то CBuilder вам весьма и весьма понравится. Действительно, эта система предоставляет вам для создания Мастеров все свои возможности и обрабатывает внутренние ошибки в Мастерах с той же тщательностью, что и свои собственные проблемы. Поэтому практически невозможно обрушить  систему  CBuilder посредством Мастера (хотя я уверен, что найдутся и такие умельцы — ломать не строить!).

А теперь давайте вернемся к нашему примеру.

Проблемы, проблемы, проблемы

Первое, что вы обнаружите, сынсталлировав и запустив Мастера непосредственно из среды разработки, так это то, что он не работает. Удивительно? Не очень. Ведь мы велели формам использовать базы данных, находящиеся в локальной директории  приложения.  Для  DLL локальной является текущая директория CBuilder, а не текущая директория DLL. Измените названия директорий в таблицах базы данных так, чтобы они соответствовали директории, в которую вы сынсталлировали DLL и базу данных.

А теперь важное замечание. Если вы инсталлируете DLL в ту же директорию, где и создаете ее, то вскоре выясните, что не можете встроить ее в среду. Причина этого весьма проста. CBuilder загружает DLL в память операционной системы, и операционная система не позволит вам переписывать этот файл, пока он загружен в нее, так что в случае если вы все-таки попробуете так сделать, то получите сообщение операционной системы о невозможности совместного доступа к файлу (sharing violation). Так что всегда инсталлируйте свои DLL из любой директории системы (например, CBuilder\bin), кроме той, в которой вы ее тестировали. Естественно, для того чтобы протестировать изменения, внесенные в DLL, вам придется закрыть IDE и запустить ее заново. Здесь мы столкнулись с проблемами скорее операционной системы,  нежели CBuilder. Раз загруженная, DLL остается в памяти операционной системы до тех пор, пока не будет закрыта IDE. Поэтому вы не можете и скопировать ее поверх старой версии (вы  получите то же самое сообщение о невозможности совместного доступа).

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

По теме:

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