Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.09.25;
Скачать: CL | DM;

Вниз

Создать компонент по имени его класса??   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.055 c
14-82465
Dilezzz
2003-09-07 15:55
2003.09.25
Какой-то этот сайт непрофессиональный


4-82556
3APA3A
2003-07-25 01:29
2003.09.25
Что такое native API?


1-82317
Vadim
2003-09-13 19:05
2003.09.25
System Tray


11-82171
SerB
2003-01-10 09:03
2003.09.25
ActiveX


3-82123
AndDem
2003-08-27 14:06
2003.09.25
LoginPrompt в ADO