Главная » C++, C++ Builder » Создание Мастера в CBuilder

0

Мастер, или Эксперт, — это расширение системы CBuilder, которое служит пользователю для облегчения выполнения некоторых задач (в основном, по созданию чего-либо). Для создания компонентов в CBuilder существует Мастер компонентов, который можно вызвать посредством команды меню Component д New. Кроме этого, в системе есть Мастер форм (Dialog Form Wizard),

Мастер диалогов (Dialog Wizard, доступен только в версиях CBuilder Professional и выше) и основной Мастер форм, находящиеся в Object Repository. Хорошо подготовив API для использова ния Мастеров, фирма Borland предоставляет вам возможность вносить собственные добавления в систему CBuilder.

На рынке условнобесплатных программ (shareware) существует несколько Мастеров для CBuilder. Причем самый интересный среди них вообще бесплатный (freeware). Написанный Даниэлем Карей (Daniel Carey), программирующим на CBuilder, он предоставляет возможность создавать простейшую основу для Мастеров в CBuilder. По своей сути это Мастер создания Мастеров, который облегчает вам создание своих собственных Мастеров. Я несколько раз прибегал к его помощи для создания основ своих Мастеров, и, естественно, вы также можете воспользоваться им. Вы найдете этот Мастер в виде и исходного, и двоичного (DLL) файла на прилагаемом компакт- диске в директории Extras.

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

Когда вы создаете новую DLL в системе CBuilder, вы выполняете практически всю ту же самую работу, что и при создании Мастера. Используя Мастер создания Мастеров мы создадим основу нашего Мастера компонентов++ и рассмотрим ее. Если вы не хотите самостоятельно инсталлировать Мастера или вообще заниматься им, просто посмотрите на код, написанный мной:

#include <vcl\sharemem.hpp>

#include <vcl\vcl.h>

#include <vcl\exptintf.hpp>

#include "ClassTabForm.h"

#include "DefPropForm.h"

#include "DefMethodForm.h"

#pragma hdrstop USERES("CompWiz.res"); USELIB("Bcbmm.lib");

USEFORM("ClassTabForm.cpp",  PagesDlg); USEUNIT("Utility.cpp"); USEFORM("DefPropForm.cpp",  Form1); USEFORM("DefMethodForm.cpp",  Form2);

//——————————————————————-

TExpertState tx;

//——————————————————————-

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason,void*)

{

return 1;

}

Это всего лишь точка входа для всех DLL. В DLL должна быть эта функция, и она должна экспортироваться, с тем чтобы Windows знала, как загружать DLL в память. Любая глобальная инициализация или выделение/высвобождение памяти будут осуществляться здесь. Эта функция будет вызываться неоднократно при работе с DLL, особо при загрузке и выгрузке DLL.

class __declspec(delphiclass) CompWiz; class CompWiz : public TIExpert

{

public:

System::AnsiString __stdcall GetName(void);

// Короткое описательное имя

System::AnsiString __stdcall GetAuthor(void){};

// Не используется в данном Мастере

System::AnsiString __stdcall GetComment(void){};

// Не используется в данном Мастере

System::AnsiString __stdcall GetPage(void){};

// Не используется в данном Мастере

HICON __stdcall GetGlyph(void){};

// Не используется в данном Мастере

TExpertStyle      stdcall GetStyle(void);

// Стиль Мастера, форма, проект и т.п. TExpertState      stdcall GetState(void){};

// Не используется в данном Мастере

System::AnsiString __stdcall GetIDString(void);

// Уникальный внутренний идентификатор

System::AnsiString __stdcall GetMenuText(void){};

// Не используется в данном Мастере

void __stdcall Execute(void){};

// Не используется в данном Мастере

void __fastcall OnClick( TIMenuItemIntf* Sender);

// Вызывается, когда пользователь выбирает команду меню

void __fastcall AddMenuItem(void);

__fastcall CompWiz(void){};

__fastcall virtual ~CompWiz(void){};

};

Это описание класса и есть, собственно говоря, наш Мастер. Обратите внимание, что класс наследует от класса VCL, называемого TIExpert. Этот класс,  не  отраженный  в  системе контекстной помощи по системе VCL CBuilder, формирует основу для всех Мастеров в системе CBuilder. Обратите внимание на комментарии под методами класса. Они были сгенерированы Мастером для того, чтобы вам было проще ориентировать ся в том, какие из них используются, а какие нет в данном типе Мастеров. Создаваемый нами Мастер принадлежит к расширениям системы (тип add-in) CBuilder, то есть он будет присутствовать в меню Tools (инструменты) и сможет выполнять довольно большой объем работ. К другим типам Мастеров относятся Мастера форм (создающие различные виды форм), Мастера проектов (создающие проекты целиком) и стандартные Мастера (выполняющие обычные повторяющиеся задания).

void HandleException(void)

{

}

Этот  метод используется для  обработки локальных исключительных ситуаций внутри  DLL, так что они не отражаются на уровне основного приложения (в данном случае CBuilder).

void __stdcall RunExpert( TIMenuItemIntf* )

{

}

Метод RunExpert — основная точка входа в Мастер. Он отвечает практически за все, что делает Мастер. Код, который должен быть добавлен в Мастера, в основном будет  нами  добавляться именно в этот метод.

System::AnsiString __stdcall CompWiz::GetName(void)

{

try

{

return "CompWiz";

}

catch(…)

{

HandleException();

}

return "";

}

Метод GetName возвращает короткое, простое имя Мастера. Мы хотим, чтобы наш Мастер создавал компоненты, так что его короткое имя будет CompWiz, то самое имя, которое возвращается в IDE CBuilder для использования в различного рода сообщениях.

TExpertStyle      stdcall CompWiz::GetStyle(void)

{

try

{

return esAddIn;

}

catch(…)

{

HandleException();

}

return esAddIn;

}

Метод GetStyle вызывается системой CBuilder для того, чтобы определить тип Мастера, с которым она имеет дело. В нашем случае это Мастер-расширение системы (add-in), так что мы возвращаем константу esAddIn. Кроме этого, возможны следующие константы типов: esStandart, esForm, esProject. Эти константы определены в заголовочном файле EXPTINTF.HPP, который находится в директории include\vcl дерева каталогов CBuilder.

System::AnsiString __stdcall  CompWiz::GetIDString(void)

{

try

{

return "CWZ100";

}

catch(…)

{

HandleException();

}

return "";

}

Метод         GetIDString         возвращает         строку-уникальный         идентификатор         Мастера. В нашем случае я выбрал значение CWZ100 (Component Wizard 1.00). Вы можете выбрать какую угодно строку, но с тем условием, чтобы она была уникальна для данного Мастера.

__fastcall CompWiz::OnClick( TIMenuItemIntf* Sender)

{

try

{

RunExpert( 0L );

}

catch(…)

{

}

}

Обработчик события OnClick вызывается системой, когда пользователь выбирает команду меню, ассоциированную с данным Мастером (командой меню мы займемся в ближайшем будущем). Мы внесем наш собственный обработчик в пункт меню системы в регистрирующей функции данного Мастера. Когда пользователь выбирает команду меню, вызывается метод RunExpert, в котором, как я уже упоминал, происходит все важное для системы.

void __fastcall DoneExpert(void)

{

}

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

void __fastcall CompWiz::AddMenuItem(void)

{

int index; TIMainMenuIntf *mmi;

TIMenuItemIntf *miparent; TIMenuItemIntf *michild; TIMenuFlags mf;

try

{

mf << mfVisible << mfEnabled;

mmi = ToolServices->GetMainMenu();

michild = mmi->FindMenuItem( "ToolsGalleryItem"); index = michild->GetIndex();

index++;

miparent = michild->GetParent();

miparent->InsertItem( index,  "ComponentWizard++", "CompWiz", "", 0, 0, 0, mf, OnClick );

michild->Release(); miparent->Release(); mmi->Release();

}

catch(…)

{

}

}

Метод AddMenuItem вызывается для добавления нового пункта в главное меню IDE CBuilder. В данном случае мы добавляем в меню, содержащее пункт ToolsGalleryItem (то есть в меню Tools), пункт с заголовком «Component Wizard++». Идентификатор этого пункта меню был получен простым увеличением последнего в меню идентификатора, то есть новый пункт добавляется в конец меню Tools. Этому пункту соответствует метод OnClick, обрабатывающий обращение к пункту. Вот как организовано взаимодействие кода Мастера и IDE:

extern "C" __declspec(dllexport) bool

__stdcall INITEXPERT0016( Toolintf::TIToolServices* ToolServices, TExpertRegisterProc  RegisterProc,

TExpertTerminateProc  &Terminate)

{

// Убеждаемся, что нашли первый и единственный

// нужный пункт

int Result = Exptintf::ToolServices == NULL; if (!Result) return false;  Exptintf::ToolServices = ToolServices;

if (ToolServices != NULL)

Application->Handle =  ToolServices->GetParentHandle(); else

return false;

Terminate = DoneExpert;

// Регистрация Мастера CompWiz *ew = new CompWiz; (*RegisterProc)(ew);

ew->AddMenuItem();

return true;

}

Это наша регистрирующая функция, которая вызывается IDE CBuilder при первой загрузке DLL. DLL загружается при регистрации в CBuilder (мы поговорим о том, как это происходит, чуть позже), и система начинает работу. После этого каждый Мастер в системе опрашивается и загружается регистрирующей функцией. Сначала эта функция проверяет, зарегистрированы ли мы уже. Если нет, то создается новый экземпляр класса CompWiz и в меню Tools добавляется новый пункт.

Замечание

В этой главе используется как термин Мастер (wizard), так и термин Эксперт (expert), так же как и в документации фирмы Borland. Использование того или иного из них — это дело привычки.

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

По теме:

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