Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
1-82296
lipskiy
2003-09-13 17:36
2003.09.25
Ассемблерная строчка не компилится под D7, под D5 нормально


1-82226
Юлия
2003-09-12 09:50
2003.09.25
Вопрос по treeview


1-82197
abHaz
2003-09-12 15:06
2003.09.25
объекты и их


14-82503
Сатир
2003-09-04 17:24
2003.09.25
Сказка об Сисадмине


1-82240
MakNik
2003-09-15 14:16
2003.09.25
QReport





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский