Форум: "Основная";
Текущий архив: 2003.09.25;
Скачать: [xml.tar.bz2];
ВнизСоздать компонент по имени его класса?? Найти похожие ветки
← →
ilka (2003-09-08 18:10) [0]Уважаемые мастера подскажите как создать какой либо компонент(класс) если мне известноо его имя.
Сейчас я это делаю так
//когда необходимо создать вызываю эту функцию
function TFORM1.CreateControl(name:String;i:integer):TComponent;
var
com:TComponent;
const
prefix="my_component";
begin
if name="TForm" then
TForm.Create(self).Name:=prefix+IntToStr(i)
else if name=.....
можно ли сделать как-то попроще?
← →
Palladin (2003-09-08 18:17) [1]TObject.ClassName
← →
jack128 (2003-09-08 18:17) [2]читай FindClass и далее по ссылкам
← →
Palladin (2003-09-08 18:18) [3]хм, о чем это я :)
← →
ilka (2003-09-08 18:34) [4]FindClass вообще никак не работает
FindClass("TForm");
FindClass("Form1");
//в обоих случаях вылетает...
TObject.ClassName ????? и как ЭТО использовать?
← →
Кто-то (2003-09-08 18:39) [5]> ilka © (08.09.03 18:34) [4]
> FindClass вообще никак не работает
F1 - RegisterClasses
← →
jack128 (2003-09-08 18:41) [6]
> ilka © (08.09.03 18:34) [4]
Интересно, когда народ хелп научится читать...
← →
HolACost! (2003-09-08 18:45) [7]А когда форумов не будет!
← →
ilka (2003-09-08 18:47) [8]переформулируем
на входе: имя класса
на выходе: экземпляр класса
//////////////////////////
>Кто-то
чтобы что-то зарегистрировать надо сначала что-то создать
← →
Кто-то (2003-09-08 18:55) [9]> ilka © (08.09.03 18:47) [8]
Вам ТОЧНО говорят, что нужно делать и где об этом написано. Говорят люди, делавшие это не один десяток раз. Вы не верите, читать справку не хотите и изрекаете философскую мысль:
"чтобы что-то зарегистрировать надо сначала что-то создать"
Ну, что ж, создавайте, флаг Вам в руки.
← →
ilka (2003-09-08 19:20) [10]Вам ТОЧНО говорят, что нужно делать и где об этом написано
ага очень точно...
было дано 3 совета по теме
1 TObject.ClassName-функция которая возращает имя класса
а мне нужно создать экземпляр TButton или TLable или TMemo и куда здесь впихнуть TObject.ClassName
2 FindClass
//function FindClass(const ClassName: string): TPersistentClass;
может это и можно испольховать(Скорее всего и нужно) НО
на вызовах
FindClass("TForm");
FindClass("Form1");
в обоих случаях вылетело => я не могу ее использовать
3 RegisterClass(TPersistenClass);
у меня нет TPersistenClass его надо создать
итак Я имею 3 совета которые я не могу применить
у когонибудь есть какие-нибудь идеи как решить проблему?
← →
Кто-то (2003-09-08 19:40) [11]> ilka © (08.09.03 19:20) [10]
> у когонибудь есть какие-нибудь идеи как решить проблему?
Идей нет. Они и не нужны. Потому что есть готовое, тривиальное, много раз использовавшееся и прекрасно работающее решение. О котором Вам тут и рассказали. Регистрируете класс, потом вызываете FindClass и по полученной классовой ссылке спокойно создаете экземпляр этого класса. Все как в самой Delphi, без всяких "идей" и прочих велосипедов.
А вот так больше НИКОГДА не говорите:
"у меня нет TPersistenClass его надо создать".
Потому что такие заявления, да еще сделанные таким уверенным тоном, вызывают приступ смеха. Вы бы уж хотя бы сначала разобрались, а что же такое TPersisten t Class.
← →
Serginio666 (2003-09-08 20:08) [12]TdocClass= class of TCustomDoc;
TId10DocClass = record
ClassName:String;
Class1:TDocClass;
end;
DocClasses:array[0..2] of TId10DocClass=((ClassName:"TDocSchet";Class1:TDocSchet),
(ClassName:"TDocPeremetshenie";Class1:TDocPeremetshenie),(ClassName:"TDocSpisanie";ClassName:TDocSpisanie));
Сортируй, находи половинным делением. и Вызывай
DocClasses[1].Class1.Create;
Либо используй TstringList и его свойство TDocClass(Objects[Index: Integer]).Create. или Хэш таблицу, что более предпочтительней для строк
Вместо регистрации используй инициализацию массива,TstringList или Хэш таблицы. Для частых вызовов рекомендуется.
← →
panov (2003-09-08 20:13) [13]>Кто-то
Выступления, сделанные от анонимного ника в таком уверенном тоне, вызывают более гомерический приступ смеха.
← →
Кто-то (2003-09-08 20:40) [14]> Serginio666 (08.09.03 20:08) [12]
Не подскажете, зачем введено поле ClassName, если уже у TObject есть такая же КЛАССОВАЯ функция?
Очевидно, что оно лишнее. И тогда в записи остается только одно поле. А тогда не нужна и сама запись. И вместо массива записей получаем массив ссылок. А можно было бы хранить их и в TList.
Именно так и поступает Delphi. Именно с таким списком и работают функция RegisterClass (добавляет класс в список) и обратная ей функция GetClass (проходит по списку и находит класс по его имени, вызывая ClassName).
И зачем же изобретать велосипеды?
> panov © (08.09.03 20:13) [13]
Вы имеете что-нибудь возразить по сути? Что-то сказано неправильно? Предложено заведомо неверное решение?
Нет. Значит, для уверенного тона есть все основания. Нравится он Вам, или не нравится - извините, но это дело лично Ваше.
А по поводу анонимного ника - разрешите отослать Вас на страницу форума, где сказано о НЕОБЯЗАТЕЛЬНОСТИ регистрации. Значит, быть анонимным, или не быть - это уже дело лично самого ника.
← →
REA (2003-09-08 21:08) [15]1) Во первых зачем это надо?
2) Во вторых ссылку на метакласс можно получить по его имени, если класс наследник TPersistent и зарегистрирован при помощи RegisterClass. Именно при помощи FindClass кажется. Я даже делал трюки с поиском всех наследников класса, но приходится переписывать функцию поиска, т.к. она закрыта для доступа.
3) Имея ссылку на метакласс можно создать объект и привести его к родительскому типу (поскольку создавать класс зная его тип по имени нецелесообразно).
← →
Кто-то (2003-09-08 21:10) [16]Вобщем фигней страдаете, братцы кролики.
← →
имя (2003-09-08 21:15) [17]Удалено модератором
← →
panov (2003-09-08 21:17) [18]Нет. Значит, для уверенного тона есть все основания. Нравится он Вам, или не нравится - извините, но это дело лично Ваше.
У ВАС для разговора в таком тоне оснований НЕТ СОВСЕМ НИКАКИХ.
← →
Кто-то (2003-09-08 21:22) [19]> REA © (08.09.03 21:08) [15]
> ссылку на метакласс можно получить по его имени...
> Именно при помощи FindClass кажется
FindClass дает ссылку на класс. Не на метакласс.
> Имея ссылку на метакласс можно создать объект
Только при виртуальном конструкторе. Иначе может быть создан объект не того класса, который требуется.
> и привести его к родительскому типу
Зачем?
> поскольку создавать класс зная его тип по имени нецелесообразно
Почему?
← →
ilka (2003-09-08 21:27) [20]я уже тут 2 часа страдаю этой фигней а все не работает
за чем это надо?...
я воссаздаю форму по ее параметрам + все компоненты на форме
параметры заданы в виде строк. Допустим я наталкиваюсь на какойто компонент (TForm,TButton) и вызываю
CreateControl(name:String;i:integer);
var
com:TComponent;
const
prefix="my_component";
begin
if name="TForm" then
TForm.Create(self).Name:=prefix+IntToStr(i)
else if name="TFMain" then...
end;
в цикле создаются все компоненты
дальше делаю вызов
TForm(FindComponent(sPrefix+IntToStr(count_component))).Show
и отображается моя форма
меня не устраевает то что создание всех компонентов надо прописать в ручную(TForm.Create(self).Name:=prefix+IntToStr(i))
Хочется что-бы прога все сама сделала
>Кто-то
я не смог обойти создание TPersistentClass без явного присвоения
p:TPersistentClass;
p:=TForm;
еще раз повторюсь у меня есть строка type="TForm" и из нее надо получить экземпляр класс TForm.
← →
Vuk (2003-09-08 21:41) [21]to ilka:
Примерно так.
регистрация:
RegisterClass(TMyForm);
...
Поиск и создание экземпляра:
var
FormClass: TFormClass;
MyForm: TForm;
...
FormClass := TFormClass(GetClass("TMyForm"));
if FormClass <> nil then
MyForm := FormClass.Create(Aplication);
← →
Кто-то (2003-09-08 21:51) [22]> ilka © (08.09.03 21:27) [20]
Посмотрите пример vuk"а - это то, что Вам надо и о чем Вам говорили. А вот еще один пример. Вводите в Edit название любого зарегистрированного класса, нажимаете на кнопку - и контрол появляется на форме.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
var
C: TPersistentClass;
begin
C := GetClass(Edit1.Text);
if (C <> nil) and C.InheritsFrom(TControl) then
with TControlClass(C).Create(Self) do
begin
Parent := Self;
SetBounds(Random(Self.ClientWidth - Width), Random(Self.ClientHeight - Height), Width, Height);
end
else ShowMessage("Неизвестный класс " + Edit1.Text);
end;
initialization
Randomize;
RegisterClasses([TEdit, TButton, TMemo, TCheckBox, TListBox, TPanel, TGroupBox]);
end.
← →
Кто-то (2003-09-08 21:56) [23]> panov © (08.09.03 21:17) [18]
> У ВАС для разговора в таком тоне оснований НЕТ СОВСЕМ НИКАКИХ.
Странно. Почему? Разве говорить УВЕРЕННО (об этом же шла речь?) здесь позволено только избранным? Или только зарегистрированным? А как же правила форума?
← →
ilka (2003-09-08 21:58) [24]to Vuk
RegisterClass(t_per TPersistentClass);
как перейти от строки class_name:String (может быть что угодно "TButton","TLable" ets, не только "TForm") к t_per
я понимаю что можно сделать присваевание t_per=TButton;
потом RegisterClass(t_per) и так далее
но на входе строка и нужно двигаться именно от нее
← →
ilka (2003-09-08 22:06) [25]>Кто-то
огромное спасибо
так-бы сразу
все работает все супер
← →
vuk (2003-09-08 22:09) [26]to ilka:
Издеваетесь что ли? Уже ведь 10 раз повторили Register/FindClass...
function FindComponentClass(const ClassName: string) : TComponentClass;
begin
Result := TComponentClass(FindClass(ClassName));
end;
RegisterClass(TButton);
...
FindComponentClass("TButton").Create(self);
← →
Кто-то (2003-09-08 22:09) [27]> ilka © (08.09.03 22:06) [25]
> так-бы сразу
Так ведь хотелось, чтобы Вы это сделали САМИ, понимаете? Пусть по подсказке, но САМИ. Тогда пользы было бы куда больше.
← →
ilka (2003-09-08 22:28) [28]я сделал сам но через одно место :) поэтому и понадобилась помощь
эта проблема у меня три дня уже висела
еще полгода и может доросту до специалиста
опыт дело наживное
Вообще всем спасибо
← →
Serginio666 (2003-09-15 14:37) [29]function TRegGroups.GetClass(const AClassName: string):
Посмотри реализацию и сравни скорость при большом количестве классов (бывает за 1000 и часто вызываемые) при применении Хэш таблиц или при бинарном поиске отсортированных массивов.
function TRegGroup.GetClass(const AClassName: string): TPersistentClass;
var
I: Integer;
begin
for I := 0 to FClassList.Count - 1 do
begin
Result := FClassList[I];
if Result.ClassNameIs(AClassName) then Exit;
end;
I := FAliasList.IndexOf(AClassName);
if I >= 0 then
begin
Result := TPersistentClass(FAliasList.Objects[I]);
Exit;
end;
Result := nil;
end;
← →
Erik (2003-09-15 15:05) [30]ilka
Если стоит только задача сохранения и востановления, то лучше воспользоватся встроеным механизмом Delphi. Ведь когда мы создаем и изменяем формы все сохраняется в поток и в фаил. Для этой чели и служит класс TPersistent - TComponent.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.09.25;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.012 c