Delphi получить класс по имени

Имена

Поиск класса по имени

Всем доброго времени суток.

Помогите, пожалуйста, решить одну проблему.

У меня есть класс TMyClass и куча различных потомков TMyClass1, TMyClass2. TMyClassN.
У TMyClass есть поле objtype:TMyType ( TMyType = (class1,class2. classN) ). У потомков есть поля-массивы с различной размерностью но одинаковым именем(Props).

У меня есть указатель на неизвестный экземпляр класса, один из выше упомянутых.

Как можно получить досуп к полю-массиву с нужной размерностью без использования case objtype?

Помимо всего прочего, таким же образом требуется получать доступ к методам классов(Create, AddProp и т.д.)

Поиск в таблице по имени
Помогите пожалуйста с поиском, я ищу записи в таблице при помощи следующего кода: procedure.

Поиск по БД по числовому диапазону и имени
Добрый день. Имеется БД, созданная в MS Access. В Delphi работает через ADOConnection. На форме.

Нужно организовать поиск по имени в базе
Нужно сделать поиск из базы данных. Нужно находить нужное имя.

Поиск по имени или фамилии в БД [есть ответ]
Несколько часов потратил на такой момент: Имеется база Access отображаемая через DBGrid. При.

Это другими словами то, что сказал Mawrat

А что с моим первым постом не так? Не передан смысл проблемы?

Добавлено через 16 минут
Могу выразить проблему в другом виде:

Каков минимальный код инициализации нужного потомка, если мы знает только его имя?

А указателями советую пользоваться, только когда нет иного выхода, или с гарантией знаете, что делаете, плюс учитываете особенности среды (банальный пример на х64 sizeof(pointer) = 8)

Вложения

refl.rar (1.4 Кб, 31 просмотров)

Продолжу немного сабж ООП

Есть ли в дельфи возможность перекрыть виртуальный метод, но не описывать его в потомке? Код метода один, но он работает с динамическими данными каждого потомка по разному. Есть ли вариант не копипастить этот метод по всем потомкам?

Источник

Delphi получить класс по имени

Уважаемые мастера подскажите как создать какой либо компонент(класс) если мне известноо его имя.
Сейчас я это делаю так

//когда необходимо создать вызываю эту функцию
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]


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»);
//в обоих случаях вылетает.

> ilka © (08.09.03 18:34) [4]
> FindClass вообще никак не работает

Читайте также:  Перечислите имена художников и скульпторов обращавшихся к образу салавата


jack128 ( 2003-09-08 18:41 ) [6]

Интересно, когда народ хелп научится читать.


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]

Вам ТОЧНО говорят, что нужно делать и где об этом написано. Говорят люди, делавшие это не один десяток раз. Вы не верите, читать справку не хотите и изрекаете философскую мысль:
«чтобы что-то зарегистрировать надо сначала что-то создать»

Ну, что ж, создавайте, флаг Вам в руки.

Вам ТОЧНО говорят, что нужно делать и где об этом написано
ага очень точно.
было дано 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]

Выступления, сделанные от анонимного ника в таком уверенном тоне, вызывают более гомерический приступ смеха.

Читайте также:  Как понять имя пользователя должно содержать не менее 3 символов


Кто-то ( 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]

Вы имеете что-нибудь возразить по сути? Что-то сказано неправильно? Предложено заведомо неверное решение?

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
и отображается моя форма

Читайте также:  Имя события проблемы apphangb1 на виндовс 7

меня не устраевает то что создание всех компонентов надо прописать в ручную (TForm.Create(self).Name:=prefix+IntToStr(i)) Хочется что-бы прога все сама сделала

>Кто-то
я не смог обойти создание TPersistentClass без явного присвоения
p:TPersistentClass;
p:=TForm;

еще раз повторюсь у меня есть строка type=»TForm» и из нее надо получить экземпляр класс TForm.


Vuk ( 2003-09-08 21:41 ) [21]

to ilka:
Примерно так.

Поиск и создание экземпляра:

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]

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;

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;


Кто-то ( 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 и часто вызываемые) при применении Хэш таблиц или при бинарном поиске отсортированных массивов.


Erik ( 2003-09-15 15:05 ) [30]

Источник

Оцените статью
Имя, Названия, Аббревиатуры, Сокращения
Добавить комментарий

Adblock
detector