Termi_uc |
Отправлено: 14.02.2007, 20:01 |
|

Дежурный стрелочник
Группа: Участник
Сообщений: 61

|
В каждом пакете BPL, есть функция которая регистрирует классы входящие в пакет. Это или Initialization, или Residter?
Смотрю исходники:
CODE |
procedure Register;
begin
RegisterPropertyEditor(TypeInfo(string), TSsComponent, 'Version',
TSsVersionProperty);
...
RegisterComponents('ShellShock',
[
TStShellAbout,
...
TStDialogPanel
]);
end;
|
Но в других источниках читаю, что эта функция называется Initialization.
Вобщем как вызвать ф-цию пакета BPL, которая регистрирует все входящие в BPL классы???
Функция InitializePackage не подходит.
Если у кого есть наработки в области загрузки пакетов в run-tim'e и считывание / использование классов которые там хранятся — пажалуйста пришлите пример. Со своей стороны поделюсь своими наработками в этой области.
Зарание спасибо.
|
 |
AVC |
Отправлено: 15.02.2007, 10:13 |
|
Ветеран
Группа: Модератор
Сообщений: 1583

|
RegisterComponent отношения к runtime не имеет.
По поводу RegisterClass и прочих регистраций есть в component registration routines.
InitializePackage, судя по названию, содержит коды, выполняющиеся при загрузке пакета в память.
CODE |
// Пример регистрации компонента в палитре компонентов на вкладке Data Controls
namespace Dbgridm
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TDBGridM)};
RegisterComponents("Data Controls", classes, 0);
}
}
// пример регистрации нескольких визуальных компонентов
namespace Panlab
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[] = {__classid(TPanelBmp), __classid(TTileBmp), __classid(TLabelS) };
RegisterComponents("Standard", classes, 2);
}
}
// пример регистрации не визуального компонента
namespace Axrecord
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TAxRecord)};
RegisterNoIcon(classes, 0);
}
}
| |
 |
Termi_uc |
Отправлено: 15.02.2007, 16:21 |
|

Дежурный стрелочник
Группа: Участник
Сообщений: 61

|
QUOTE (AVC @ 15.02.2007, 10:13) | RegisterComponent отношения к runtime не имеет. |
судя по:
CODE |
procedure RegisterComponents(const Page: string;
const ComponentClasses: array of TComponentClass);
begin
if Assigned(RegisterComponentsProc) then
RegisterComponentsProc(Page, ComponentClasses)
else
raise EComponentError.CreateRes(@SRegisterError);
end;
|
можно установить свой RegisterComponentsProc (в приложении он обычно равен nil), а затем вызвать Register для всех юнитов (он экспортируется) пакета bpl.
Как вызвать Register?
Может я туплю, но найти (GetProcAddress) в BPL процедуры с названием "_Register" не удалось. Возможно я плохо искал.
Но я точно знаю, что в runtime можно подгрузить пакет и вызвать процедуру регистрирующюю все класы входящие в BPL. Видел готовые продукты, сам свой собственный пакет (написаный на CBuilder) подгружал и видел в палитре компонентов СВОИ.
|
 |
AVC |
Отправлено: 15.02.2007, 17:00 |
|
Ветеран
Группа: Модератор
Сообщений: 1583

|
QUOTE |
Может я туплю, но найти (GetProcAddress) в BPL процедуры с названием "_Register" не удалось. Возможно я плохо искал.
|
Нет. Искали вы хорошо, но вы ошибочно предположили, что Borland формирует имя глобального символа так же как и стандартный C. Искать надо было так
@Ваш_Namespace@Register$qqrv
QUOTE |
Но я точно знаю, что в runtime можно подгрузить пакет и вызвать процедуру регистрирующюю все класы входящие в BPL.
|
В runtime чего? И где вы хотите их регистрировать?
Может я чего то не понимаю, но я веду речь о регистрации компонентов (своих или чужих) в среде Builder'а.
А может вы имеете ввиду COM регистрацию?
QUOTE |
сам свой собственный пакет (написаный на CBuilder) подгружал и видел в палитре компонентов СВОИ.
|
В примере я и привел как СВОИ компоненты поставить в палитру BCB
Среда Builder'а (и Delphi) при старте сама просматривает список пакетов, ищет Regiser и делает свои "темные дела". |
 |
Termi_uc |
Отправлено: 15.02.2007, 20:40 |
|

Дежурный стрелочник
Группа: Участник
Сообщений: 61

|
QUOTE |
В runtime чего? И где вы хотите их регистрировать?
|
Регистрировать компоненты в программе ф-цией RegisterClass
QUOTE |
В примере я и привел как СВОИ компоненты поставить в палитру BCB
Среда Builder'а (и Delphi) при старте сама просматривает список пакетов, ищет Regiser и делает свои "темные дела".
|
Вот мне и надо при старте СВОЕЙ програмы просматривать список пакетов, искать Regiser и делать "темные дела".
ХМ...
Ладно по-порядку:
1. Есть програма (моя), в неё надо встроить дизайнер, который читал / писал / редактировал бы dfm и создавал на основи их формы.
2. Для чтения dfm нужно зарегестрировать все компоненты, которые на ней могут быть.
3. Если в форме которая записана в dfm есть компонент, который не зарегестрирован в програме, то форма не загрузится.
4. Для того, чтобы грузить любые формы с програмой поставляется расширеный набор пакетов — стандартные Builder (VCLXX.bpl, RTLXX.bpl ...) и пакеты сторонних разработчиков.
Так вот, если все пакеты компелировать с програмой, то всё чики-пуки. Но тогда для добавления нового компонента надо заново компилировать прогу.
Я хочу подругому, в некую папку "BPLs" кидаю пакеты, и подгружаю их в момент запуска програмы.
Но как вызвать функцию регистрирующюю компоненты?
Спасибо AVC, подсказал направление:
QUOTE |
Нет. Искали вы хорошо, но вы ошибочно предположили, что Borland формирует имя глобального символа так же как и стандартный C. Искать надо было так
@Ваш_Namespace@Register$qqrv
|
Тогда как узнать все Namespace в пакете?
Я знаю как узнать все ContainsUnit в пакете, может это одно и тоже?
Отредактировано Termi_uc — 15.02.2007, 20:47
|
 |
Termi_uc |
Отправлено: 15.02.2007, 20:49 |
|

Дежурный стрелочник
Группа: Участник
Сообщений: 61

|
Кстати AVC вы оставили без коментариев:
QUOTE |
судя по:
CODE |
procedure RegisterComponents(const Page: string;
const ComponentClasses: array of TComponentClass);
begin
if Assigned(RegisterComponentsProc) then
RegisterComponentsProc(Page, ComponentClasses)
else
raise EComponentError.CreateRes(@SRegisterError);
end;
|
можно установить свой RegisterComponentsProc (в приложении он обычно равен nil), а затем вызвать Register для всех юнитов (он экспортируется) пакета bpl.
|
|
 |
AVC |
Отправлено: 16.02.2007, 10:18 |
|
Ветеран
Группа: Модератор
Сообщений: 1583

|
QUOTE (Termi_uc @ 15.02.2007, 19:40) |
[b]Тогда как узнать все Namespace в пакете?
Я знаю как узнать все ContainsUnit в пакете, может это одно и тоже?
|
для просмотра чего и как экспортируется/импортируется я пользуюсь следующими батниками
CODE |
// alltolst.bat
@Echo Off
Call DelDef.bat
Call tolst . VclBde50 bpl
Call tolst . AxLib bpl
Call tolst .. hcenger exe
Call tolst .. doa34c5 bpl
Call tolst .. fr5 bpl
Call tolst .. frdoa bpl
Call tolst .. hcacount bpl
// tolst.bat
IF Not Exist %1\%2.%3 GoTo Exit
Echo %1\%2.%3
Tdump %1\%2.%3 %2.lst > nul
rem Tdump -em %1\%2.%3 %2.imp > nul
Impdef -h %2.def %1\%2.%3 > nul
:Exit
|
Но это для глаз что бы знать как зовут то, чего ишешь.
Есть GetPackageInfo, но я с ней не работал.
QUOTE (Termi_uc @ 15.02.2007, 19:40) |
Вот мне и надо при старте СВОЕЙ програмы просматривать список пакетов, искать Regiser и делать "темные дела".
|
Я такой задчи не решал.
Когда то понадобилось иметь в приложении элементы итспектора объектов (самые зачатки). Не по теме, но а вдруг пригодится, так как это может решать ту же задачу с другой стороны.
CODE |
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
AnsiString __fastcall TF_ObjList::ObjPropsInfo (TObject *obj)
{
if (!obj) return "NULL";
int cou = GetTypeData(PTypeInfo(obj->ClassInfo()))->PropCount;
if (cou <= 0) return "";
TStringList *slist = FTmpSList;
slist->Clear();
bool isok = true;
char *buf = new char[cou*sizeof(PPropInfo)];
try {
AnsiString name;
AnsiString tname;
AnsiString erstr = "Error: ";
PPropList proplist = (PPropList)(buf);
PPropInfo propinfo;
PTypeInfo typeinfo;
Typinfo::TTypeKind kind;
Variant val;
GetPropInfos(PTypeInfo(obj->ClassInfo()), proplist);
for (int i=0; i < cou; i++)
{ propinfo = *(proplist+i);
if (!propinfo) continue;
name = AnsiString(propinfo->Name);
typeinfo = *(propinfo->PropType);
if (!typeinfo)
{ slist->Add(ClpPad(name,20) + erstr + "Bad TypeInfo");
continue;
}
kind = typeinfo->Kind;
if (kind == tkMethod ) continue;
tname = AnsiString(typeinfo->Name).Trim().UpperCase();
try { val = GetPropValue(obj, name, true); }
catch (Exception &xcp) { val = erstr + xcp.Message; isok = false; }
if (kind == tkClass )
{ try { val = SObj ( (TObject*) (int(val)) ); }
catch (Exception &xcp) { val = erstr + xcp.Message; isok = false; }
}
slist->Add(ClpPad(name,30) + VarToString(val));
}
} // try buf
catch (Exception &xcp)
{ isok = false;
slist->Add(AnsiString("Error: ") + xcp.Message);
}
delete[] buf;
if (isok) slist->Sort();
return slist->Text;
}
//---------------------------------------------------------------------------
AnsiString __fastcall TF_ObjList::SObj (TObject *obj)
{
if (!obj) return "NULL";
return AnsiString(obj->ClassName()) + "*";
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
| |
 |
Termi_uc |
Отправлено: 16.02.2007, 17:08 |
|

Дежурный стрелочник
Группа: Участник
Сообщений: 61

|
Спасибо AVC, за подсказку:
QUOTE | Искать надо было так
@Ваш_Namespace@Register$qqrv |
ВСЁ РАЗОБРАЛСЯ с Register.
Но осталась одна БОЛШАЯ проблема: Как получить список всех функций регистрации в пакете. Но это уже по другой теме.
Тему можно считать закрытой
Да вот окончательный вариант и проект, если кому надо.
Например для пакета CBuilder6\Bin\dclstd60.bpl, одна из функций регистрации — @Stdreg@Register$qqrv.
Если будут наработки пишите...
CODE |
//Функция регистрации компонентов в свою палитру
void __fastcall MyRegisterComponentsProc1(const AnsiString Page,
TMetaClass* const * ComponentClasses,
const int ComponentClasses_Size)
{
TTabSheet * tsh(NULL);
if(Form1)//Форма на которой находится палитра
{
for(int j(0); j < Form3->pcPallete->PageCount; j++)
if(Form3->pcPallete->Pages[j]->Caption == Page)
{
tsh = Form3->pcPallete->Pages[j];
break;
}
if(!tsh)
{
tsh = new TTabSheet(Form3);
tsh->PageControl = Form3->pcPallete;
tsh->Caption = Page;
//MEMOS объявлен в *.h файле формы с палитрой как:
//TMemo * MEMOS[40];
MEMOS[tsh->TabIndex] = new TMemo(Form1);
MEMOS[tsh->TabIndex]->Parent = tsh;
MEMOS[tsh->TabIndex]->Align = alClient;
}
}
for(int i(-1); i < ComponentClasses_Size; i++)
{
// ShowMessage(ComponentClasses[i + 1]->ClassName());
if(Form1)MEMOS[tsh->TabIndex]->Lines->Add(ComponentClasses[i + 1]->ClassName());
RegisterClass(ComponentClasses[i + 1]);
}
}
//...
HINSTANCE lModule(NULL);
//Загрузка пакета
void __fastcall TForm1::LoadPackClick(TObject *Sender)
{
if(!OpenDialog1->Execute())return;
if(lModule)UnloadPackage((unsigned)lModule);
lModule = (void *)LoadPackage(OpenDialog1->FileName);
}
//---------------------------------------------------------------------------
//Найти указаную в Edit3->Text функцию ренистрации и вызвать
void __fastcall TForm1::Button8Click(TObject *Sender)
{
//Поставить свою функцию, как функцию регистрации пакетов
// для всего приложения
RegisterComponentsProc = MyRegisterComponentsProc1;
if(!lModule)return;
void (__stdcall * Register1)();
Register1 =
(void (__stdcall *)())
GetProcAddress(lModule, Edit3->Text.c_str());
if(Register1){Register1(); ShowMessage("BRRRRR");}
}
//---------------------------------------------------------------------------
//Не забудте выгрузить пакет
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if(lModule)UnloadPackage((unsigned)lModule);
} |
|
 |
Termi_uc |
Отправлено: 16.02.2007, 17:12 |
|

Дежурный стрелочник
Группа: Участник
Сообщений: 61

|
QUOTE (AVC @ 16.02.2007, 10:18) | QUOTE (Termi_uc @ 15.02.2007, 19:40) |
Вот мне и надо при старте СВОЕЙ програмы просматривать список пакетов, искать Regiser и делать "темные дела".
|
Я такой задчи не решал.
Когда то понадобилось иметь в приложении элементы итспектора объектов (самые зачатки). Не по теме, но а вдруг пригодится, так как это может решать ту же задачу с другой стороны. |
Спасибо, но инспектор объектов я почти сделал. Только осталось как-то вызывать зарегестрированые редакторы свойств (PropertyEditors).
|
 |
Termi_uc |
Отправлено: 16.02.2007, 17:18 |
|

Дежурный стрелочник
Группа: Участник
Сообщений: 61

|
Да, и обещяный проект — Тестовый полигон загрузки пакетов.
Не забывайте:
Для пакета CBuilder6\Bin\dclstd60.bpl, одна из функций регистрации — @Stdreg@Register$qqrv. — Для примера.
|
 |
|