Автоматизация RegisterClass в C ++ Builder VCL
-
20-08-2019 - |
Вопрос
Мы используем C ++ Builder для приложения, формы которого хранятся вне EXE-файла в базе данных.Код приложения написан на C ++
Это позволяет нам изменять формы и form / actions без повторной компиляции.Вот фрагмент кода, который выполняет работу по загрузке формы.
RegisterClass(__classid(TButton));
RegisterClass(__classid(TEdit));
RegisterClass(__classid(TRadioGroup));
RegisterClass(__classid(TGroupBox));
RegisterClass(__classid(TCheckBox));
RegisterClass(__classid(TRadioButton));
RegisterClass(__classid(TTimer));
RegisterClass(__classid(TListBox));
RegisterClass(__classid(TComboBox));
RegisterClass(__classid(TBitBtn));
RegisterClass(__classid(TSpeedButton));
RegisterClass(__classid(TMaskEdit));
RegisterClass(__classid(TProgressBar));
ms = new TMemoryStream;
ms2 = new TMemoryStream;
// Loading Module into Memory Stream
ms->Position = 0;
ms->LoadFromFile(Filename->Text);
ms->Position = 0;
pModule = new TForm(this);
// Reading Module Definition
if( !Inputisbin->Checked )
{
ms2->Position = 0;
ObjectTextToBinary(ms, ms2);
ms2->Position = 0;
ms2->ReadComponent(pModule);
}
else
ms->ReadComponent(pModule);
Log->Lines->Add("Displaying Module");
pModule->Show();
Мне любопытно узнать, есть ли какие-либо встроенные функции, которые я могу вызвать, чтобы зарегистрировать все классы, на которые ссылаются.Я полагаю, что можно самостоятельно просканировать поток памяти или файл для всех объектов и вызвать RegisterClass для каждого, но надеялся, что кто-то знает о функции, которая уже сделала это.
Как таковые, не все формы также используют все эти классы, поэтому было бы неплохо зарегистрировать только те, которые фактически унаследованы.
Решение
Подход, который у вас здесь есть, на мой взгляд, совершенно правильный.Я использовал тот же подход много лет назад, используя Delphi2, хотя мне пришлось реализовать свою собственную фабрику классов и функции ObjectToText / TextToObject, поскольку ReadComponent() никогда не фигурировал в VCL.
По вашему второму пункту о регистрации только обязательных классов, наверняка им нужно зарегистрироваться только один раз?И накладные расходы на определение того, нужно ли регистрировать класс, перевесят затраты на регистрацию всего.Опять же, я бы оставил все как есть.
Другие советы
Я не знаю ни о каких существующих функциях - мне кажется, это довольно редкая вещь, которую приходится делать.Подход к хранению DFMS форм в базе данных (они хранятся отдельно в файлах CPP и H для устройства?) также странен.Я знаю, вы говорите "Это позволяет нам изменять формы и form / actions без повторной компиляции", но лично я бы сохранил их в DLL и перекомпилировал - по крайней мере, тогда, в зависимости от вашей системы сборки, она будет версионной, и ваш модуль будет сохранен как "unit".Я признаю, что не знаю ваших системных требований, и у вас, вероятно, есть веская причина сделать это по-своему.
Однако, учитывая ваш подход, я думаю, что сканирование потока, поиск предложений object и регистрация этих компонентов перед вызовом ReadComponent, вероятно, является лучшим подходом.
При хранении DFM отдельно (чтобы просто изменить события и обработчики действий) все равно остаются файлы CPP и H, скомпилированные в вашем основном приложении.Исходя из этого, разве у вас уже не были бы зарегистрированы и встроены компоненты, так что в этом нет никакой необходимости?