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

Вниз

String -> TControl   Найти похожие ветки 

 
VirEx ©   (2007-07-02 17:35) [0]

как реализовать такую штуку:

var
 str:String;
begin
 str:="TPanel";
 AddControl(Form1,str);
end;

где procedure AddControl( Parent:TControl; ChildComponent:String );


 
MBo ©   (2007-07-02 17:37) [1]

RegisterClass + GetClass/FindClass


 
VirEx ©   (2007-07-02 17:40) [2]

о. щас попробую


 
VirEx ©   (2007-07-02 19:25) [3]

не канает. FindClass также как и  FindGlobalComponent нифига не может найти екземпляр класса


 
Юрий Зотов ©   (2007-07-02 19:33) [4]

String в Delphi - не класс. Икать нечего.


 
Юрий Зотов ©   (2007-07-02 19:34) [5]

Искать.
:о)


 
VirEx ©   (2007-07-02 19:39) [6]

да я знаю, я имею ввиду что эти функции не могут найти ни TPersistentClass не TComponent с помощью которых я бы динамически создал любой объект с именем содержащимся в строке.

а как хотябы перечислить все возможные зарегестрированные классы?


 
StriderMan ©   (2007-07-02 19:43) [7]


> FindClass также как и  FindGlobalComponent нифига не может
> найти екземпляр класса

FindClass экземпляр не ищет


> RegisterClass

это сделал?


 
AlexWlad ©   (2007-07-02 19:45) [8]

Ну найдешь ты ВСЕ названия классов... А заполнять два мешка пропертей для каждого (то, что среда разработки делает) - Пушкин будет?


 
VirEx ©   (2007-07-02 19:50) [9]


>  [8] AlexWlad ©   (02.07.07 19:45)
> Ну найдешь ты ВСЕ названия классов... А заполнять два мешка
> пропертей для каждого (то, что среда разработки делает)
> - Пушкин будет?

да свойства то я заполню, мне бы главное сделать любой компонент

> RegisterClass
> > это сделал?
procedure RegisterClass(AClass: TPersistentClass);
так а откуда я возьму аргумент AClass? если у меня исходные данные только строка?


 
Юрий Зотов ©   (2007-07-02 20:01) [10]

> так а откуда я возьму аргумент

Регистируйте, например, в секции initialization того же модуля, где этот класс и определен.


 
VirEx ©   (2007-07-02 20:24) [11]

вы шутите наверно?)
мне надо сделать функцию которая будет возвращать по имени класса компонента объект.

например захотелось мне динамически загрузить из файла различные компоненты (которые перечисленны в виде текста, например: name="Panel1",  classname="TPanel", caption="asdasd", ...) и код динамически создает объект с нужным классом.

ведь так не сделаешь, а очень хотелось бы:
var
 o:TObject;
begin
o:=TObject.create;
o.ClassName:="TPanel";
TPanel(o).Caption:="asdasdasd";


 
Yanis ©   (2007-07-02 20:39) [12]


> var
>  o:TObject;
> begin
> o:=TObject.create;
> o.ClassName:="TPanel";
> TPanel(o).Caption:="asdasdasd";

жесть.


 
VirEx ©   (2007-07-02 20:42) [13]


>  [12] Yanis ©   (02.07.07 20:39)
>
> > var
> >  o:TObject;
> > begin
> > o:=TObject.create;
> > o.ClassName:="TPanel";
> > TPanel(o).Caption:="asdasdasd";
>
> жесть.



> ведь так не сделаешь, а очень хотелось бы


 
Yanis ©   (2007-07-02 20:44) [14]


> > ведь так не сделаешь, а очень хотелось бы

Читал :) Меня размах воображения поражает.


 
Юрий Зотов ©   (2007-07-02 21:25) [15]

> VirEx ©   (02.07.07 20:24) [11]

> вы шутите наверно?)
Нисколько. Регистрируйте класс - и все получится.

> ведь так не сделаешь
А что, по-Вашему, происходит при загрузке формы? Это самое и происходит.


 
Loginov Dmitry ©   (2007-07-02 21:29) [16]


type
 TControlClass = class of TControl;
var
 C: TControlClass;
begin
 C := FindClass("TButton"); {Или свой вариант}
 with C.Create(Self) do
 begin
   Caption := "blablabla";
   .............
 end;


вот так вот это приблизительно делается


 
VirEx ©   (2007-07-02 21:41) [17]


>  [16] Loginov Dmitry ©   (02.07.07 21:29)
>
> type
>  TControlClass = class of TControl;
> var
>  C: TControlClass;
> begin
>  C := FindClass("TButton"); {Или свой вариант}
>  with C.Create(Self) do
>  begin
>    Caption := "blablabla";
>    .............
>  end;
>
>
> вот так вот это приблизительно делается

procedure TForm1.Button1Click(Sender: TObject);
type
TControlClass = class of TControl;
var
C: TControlClass;
begin
registerclass(TButton);
C := TControlClass(FindClass("TButton"));//просто приравнять невозможно изза разных типов
with C.Create(Self) do
begin
  Caption := "blablabla";
  left:=10;
  top:=10;
  visible:=true;
end;
end;
только после этого меняется заголовок окна)


 
VirEx ©   (2007-07-02 21:42) [18]

хотя если добавить еще parent:=form1 то появится кнопка, но заголовок окна по прежнему изменится)


 
atruhin ©   (2007-07-02 21:47) [19]

> хотя если добавить еще parent:=form1 то появится кнопка,
> но заголовок окна по прежнему изменится)

А дальше читай о RTTI статей и примеров в сети море.


 
VirEx ©   (2007-07-02 21:50) [20]

вся проблема  в том что эта функция в отдельном модуле
но в ней я указываю главный компонент RootControl из которого зарегестрированные классы перерегистрирую в этом модуле


 
atruhin ©   (2007-07-02 22:09) [21]

> вся проблема  в том что эта функция в отдельном модуле
> но в ней я указываю главный компонент RootControl из которого
> зарегестрированные классы перерегистрирую в этом модуле

Ни чего не понял в этой фразе, но в каком модуле проводить регистрацию/создание -
значения не имеет.


 
VirEx ©   (2007-07-02 22:19) [22]

есс, я это сделал!
function LoadObject(Parent_:TWinControl; FileName, Section: string):TControl;
Parent_ - контрол на котором должен быть размещен загруженный контрол
FileName, Section - для указания настроек ini файла

позже выложу более красивый код, если кому надо конечно, или не надо?)


 
Loginov Dmitry ©   (2007-07-02 22:21) [23]

> только после этого меняется заголовок окна)


Ну не TControl укажи а че-нибудь другое. Или используй тулзы модуля TypInfo.


 
VirEx ©   (2007-07-02 22:23) [24]


>  [23] Loginov Dmitry ©   (02.07.07 22:21)
> > только после этого меняется заголовок окна)
>
>
> Ну не TControl укажи а че-нибудь другое. Или используй тулзы
> модуля TypInfo.

да не в том дело, просто заголовок менялся потомучто Caption было от формы
а в своем модуле для установки свойств конечно без тип инфо не обойтись)


 
Loginov Dmitry ©   (2007-07-02 22:26) [25]

> менялся потомучто Caption было от формы


Наверно попому, что у TControl такого св-ва нету


 
Loginov Dmitry ©   (2007-07-02 22:28) [26]

попому = потому ))


 
VirEx ©   (2007-07-02 22:37) [27]

..............
unit IniAPI;

interface
uses
 Windows;

var
 INIFileName:string;
 SelectSection:string;

function WriteString(Ident, Value: string):boolean;
function ReadString(Ident:string): String;
function ReadInteger(Ident:string): Integer;
function ReadBoolean(Ident:string): Boolean;
implementation

uses SysUtils;

function ReadBoolean(Ident:string): Boolean;
begin
 result:=false;
 try
 result:=Boolean(ReadInteger(Ident));
 except
 exit;
 end;
end;

function ReadInteger(Ident:string): Integer;
begin
 result:=0;
 try
 result:=StrToInt(ReadString(Ident));
 except
 exit;
 end;
end;

function ReadString(Ident:string): String;
var
 Buffer: array[0..2047] of Char;
 res:string;
begin
 SetString(res, Buffer, GetPrivateProfileString(PChar(SelectSection),
 PChar(Ident), PChar(nil), Buffer, SizeOf(Buffer), PChar(INIFileName)));
 result:=Buffer;
end;

function WriteString(Ident, Value: string):boolean;
begin
 result:= WritePrivateProfileString(PChar(SelectSection), PChar(Ident),PChar(Value), PChar(INIFileName));
end;

end.
..............

function GetToken(aString, SepChar: String; TokenNum: integer):String;
{
параметры: aString : полная строка

SepChar : строка служащая разделителем между словами (подстроками)
TokenNum: номер требуемого слова (подстроки))
result    : искомое слово или пустая строка, если количество слов меньше значения "TokenNum"
}
var

Token     : String;
StrLen    : integer;
TNum      : integer;
TEnd      : integer;

begin

StrLen := Length(aString);
TNum   := 1;
TEnd   := StrLen;
while ((TNum <= TokenNum) and (TEnd <> 0)) do
begin
TEnd := Pos(SepChar,aString);
if TEnd <> 0 then
begin
if TokenNum>1 then begin
Token := Copy(aString,Length(SepChar),TEnd-1);
Delete(aString,1,Length(SepChar)+TEnd-1);
Inc(TNum);
end else begin
Token := Copy(aString,1,TEnd-1);
Delete(aString,1,TEnd);
Inc(TNum);
end;
end
else
begin
Token := aString;
end;
end;
if TNum >= TokenNum then
begin
result := Token;
end
else
begin
result := "";
end;
end;
...........
uses
 TypInfo;
..........
function LoadObject_(Parent_:TWinControl; FileName, Section: string):TControl;
 procedure StrToFont(font:TFont;Value:String);
 var
   s:string;
 begin
 font.Name:=GetToken(Value,"|",1);
 font.Size:=StrToInt(GetToken(Value,"|",2));
 s:=GetToken(Value,"|",3);
 font.Color:=StringToColor(GetToken(Value,"|",4));
 if length(s) >2 then
 SetOrdProp(font,"Style",StringToSet(GetPropInfo(font,"Style"),s));
 end;

type
TControlClass = class of TControl;
var
 i:integer;
 ClassName,Name,Value:String;
 Obj_: TControlClass;
 tmpObj:TObject;
 Obj: TControl;
 propNames:TStrings;
 pp : PPropList;
 pt : PTypeData;
begin
IniAPI.INIFileName:=FileName;
IniAPI.SelectSection:=Section;

ClassName:=IniAPI.ReadString("ClassName");
Name:=IniAPI.ReadString("Name");
if (ClassName="") or (Name="") then exit;

Obj_:=TControlClass(GetClass(ClassName));
Obj:=Obj_.Create(nil);
Obj.Parent:=Parent_;
Obj.Visible:=true;
result:=Obj;

propNames:=TStringList.Create;
//получаем все возможные Public свойства
pt:=GetTypeData(Obj.ClassInfo);
GetMem (pp, pt^.PropCount*SizeOf(Pointer));
try
 GetPropInfos(Obj.ClassInfo, pp);
 for i :=0 to pt^.PropCount-1 do propNames.Add(pp^[i].Name);
finally
 FreeMem(pp);
end;

for i:=0 to propNames.Count-1 do begin
 Value:=IniAPI.ReadString(propNames[i]);
 if Value<>"" then begin //если этого свойства нет в файле
//предохраняемся)
try
   case typinfo.PropType(Obj, propNames[i]) of
   tkString, tkLString: SetStrProp(Obj,propNames[i],Value);
   tkInteger:
             if GetPropInfo(Obj.ClassType, propNames[i])^.PropType^^.Name = "TColor"
               then
               SetOrdProp(Obj,propNames[i],StringToColor(Value))
               else
               SetOrdProp(Obj,propNames[i],StrToInt(Value));

   tkClass:  begin
             tmpObj:=TPersistent(GetOrdProp(Obj, propNames[i]));
             if tmpObj is TFont then StrToFont(TFont(tmpObj),Value)
             else
             if tmpObj is TStrings then begin
               TStrings(tmpObj).Clear;
               Value:=ReplaceSub(Value,"|",#13#10);
               TStrings(tmpObj).Text:=Value;
             end;
             end;
   tkEnumeration: SetEnumProp(Obj,propNames[i],Value);
   end;
except end;
 end;
end;
propNames.Free;
end;


 
VirEx ©   (2007-07-02 22:39) [28]

вот из такого примерно файла грузит контролы и устанавливает им свойства:
[Component0]
ClassName=TButton
Name=Button1
Caption=Button1
Top=168
Left=48
Font=MS Sans Serif|8||clWindowText
Width=75
Height=25
[Component1]
ClassName=TRadioButton
Name=RadioButton1
Caption=RadioButton1
Color=clBtnFace
Top=104
Left=72
Font=MS Sans Serif|8||clWindowText
Width=113
Height=17
[Component2]
ClassName=TCheckBox
Name=CheckBox1
Caption=CheckBox1
Color=clBtnFace
Top=80
Left=64
Font=MS Sans Serif|8||clWindowText
Width=97
Height=17
[Component3]
ClassName=TPanel
Name=Panel1
Caption=Panel1
Color=clBtnFace
Top=224
Left=64
Font=MS Sans Serif|8||clWindowText
Width=185
Height=41

например загрузить радиобокс можно так:
LoadObject_(Form1, "c:\1.ini" , "Component1" )


 
VirEx ©   (2007-07-02 22:41) [29]

но! в каком либо модуле в проекте необходимо зарегить контролы:
procedure TfrmMain.FormCreate(Sender: TObject);
begin
registerclass(TButton);
registerclass(TRadioButton);
registerclass(TCheckBox);
registerclass(TPanel);
.......


 
Loginov Dmitry ©   (2007-07-02 22:44) [30]

Какая разница? Главное, до выполнения основного кода


 
Loginov Dmitry ©   (2007-07-02 22:45) [31]

сорри, посчитал утверждение за вопрос


 
VirEx ©   (2007-07-02 22:45) [32]

ну ясный перец)

оффтоп.
всё, на сегодня всё. я бы сегодня не справился если бы не треки UT2004.
спать.


 
Игорь Шевченко ©   (2007-07-03 10:40) [33]

VirEx ©   (02.07.07 22:37) [27]

И нафига, спрашивается, в Борланде classes.pas писали, если индейцы их не читают ?


 
Inco   (2007-07-03 12:21) [34]

А если проще поступить:

function AddObj(ACompName: string): Object
begin
 if ACompName = "TPanel" then Result := TPanel.Create()
 else ACompName = "TButton" then Result := TButton.Create()
 else ACompName = "TMemo" then Result := TMemo.Create()
 ...
end;


 
Skier ©   (2007-07-03 13:16) [35]

есть же классы TReader и TWriter. Зачем велосипед изобретать?


 
Loginov Dmitry ©   (2007-07-03 13:17) [36]

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


 
VirEx ©   (2007-07-03 18:34) [37]


>  [34] Inco   (03.07.07 12:21)

сУщий, шУтишь да?


>  [35] Skier ©   (03.07.07 13:16)
> есть же классы TReader и TWriter. Зачем велосипед изобретать?

тогда покажи мне велосипед, с помощью которого можно загрузить ini файл динамически создавая любые объекты и забивая их свойствами из этого же файла. (WriteComponent мне не подходит)


>  [33] Игорь Шевченко ©   (03.07.07 10:40)
> VirEx ©   (02.07.07 22:37) [27]
>
> И нафига, спрашивается, в Борланде classes.pas писали, если
> индейцы их не читают ?

цель была: загрузить из ini файла объект, с определенными свойствами, любой объект
теперь вопрос: а вы о чем собственно?


 
VirEx ©   (2007-07-03 19:42) [38]


> [37] VirEx ©   (03.07.07 18:34)

WriteComponent/ReadComponent


 
Игорь Шевченко ©   (2007-07-04 09:45) [39]

VirEx ©   (03.07.07 18:34) [37]


> цель была: загрузить из ini файла объект, с определенными
> свойствами, любой объект
> теперь вопрос: а вы о чем собственно?


Я о том, что велосипед с квадратными колесами не поедет.


 
Kolan ©   (2007-07-04 09:50) [40]

> а вы о чем собственно?

Думаю о сериализации:
http://rsdn.ru/article/delphi/serialization.xml


 
Юрий Зотов ©   (2007-07-04 10:52) [41]

> VirEx ©   (03.07.07 18:34) [37]

> цель была: загрузить из ini файла объект, с определенными свойствами,
> любой объект

А в чем, собственно, проблема-то? Есть готовый механизм, если он почему-то не устраивает (кстати, непонятно, почему?), то делайте свой по аналогии.

Например, пусть в INI-файле имеем секцию (которая, кстати, ничем по сути не отличается от соответствующей "секции" текстового DFM):

[Button1 = TButton]
Left = 50
Top = 40
Width = 100
Height = 25
Parent = Panel1
Caption = "OK"

Читаем заголовок этой секции и создаем объект (естественно, его класс должен быть зарегистрирован). Потом читаем тело секции и назначаем его свойства (через функции из TypInfo.pas).

Но еще раз - а чем, собственно, не устраивает готовый механизм? Действительно ведь изобретение велосипеда получается.


 
Kolan ©   (2007-07-04 10:54) [42]

> если он почему-то не устраивает (кстати, непонятно, почему?
> ), то делайте свой по аналогии.

Может если надо именно ini, то проще пользоваться стандартным а на выходе/входе преобразовываеть его в ini и обратно?


 
VirEx ©   (2007-07-04 16:51) [43]


>  [41] Юрий Зотов ©   (04.07.07 10:52)

ну так покажите готовый велосипед то.


>  [39] Игорь Шевченко ©   (04.07.07 09:45)

...или с круглыми колёсами


>  [40] Kolan ©   (04.07.07 09:50)
> > а вы о чем собственно?
>
> Думаю о сериализации:
> http://rsdn.ru/article/delphi/serialization.xml
см.:

> [37] VirEx ©   (03.07.07 18:34)



>  [38] VirEx ©   (03.07.07 19:42)


 
Юрий Зотов ©   (2007-07-04 19:56) [44]

> VirEx ©   (04.07.07 16:51) [43]

> ну так покажите готовый велосипед то.

Read/WriteComponent.

То есть, вместо самопальной сериализации в INI-файлы (для создания которой придется еще помучиться) работаете со штатной сериализацией в текстовые (или двоичные - как угодно) файлы формата DFM.

И никаких проблем. И с круглыми колесами.

PS
Еще можно посмотреть ObjectBinaryToText/ObjectTextToBinary. Тоже с круглыми колесами.


 
VirEx ©   (2007-07-05 20:00) [45]

я так понимаю на мастаках все читаю посты автора выборочно :(


 
Loginov Dmitry ©   (2007-07-05 21:38) [46]

> ...или с круглыми колёсами


С квадратными один фиг. Попробуй без Write/ReadComponent считать из своего ini-файла текст для TMemo. Как в этом случае извратишься? Мне вот в LangReader"e пришлось с этим немало помучаться.


 
VirEx ©   (2007-07-06 17:01) [47]


>  [46] Loginov Dmitry ©   (05.07.07 21:38)
> > ...или с круглыми колёсами
>
>
> С квадратными один фиг. Попробуй без Write/ReadComponent
> считать из своего ini-файла текст для TMemo. Как в этом
> случае извратишься? Мне вот в LangReader"e пришлось с этим
> немало помучаться.

легко, в ини файле не было примера многострочного свойства, но в коде:

> [27] VirEx ©   (02.07.07 22:37)

показано как загрузить TStrings

  tkClass:  begin
            tmpObj:=TPersistent(GetOrdProp(Obj, propNames[i]));
            if tmpObj is TFont then StrToFont(TFont(tmpObj),Value)
            else
            if tmpObj is TStrings then begin
              TStrings(tmpObj).Clear;
              Value:=ReplaceSub(Value,"|",#13#10);
              TStrings(tmpObj).Text:=Value;
            end;

            end;

тоесть замена перевода каретки на символ | как при чтении ини файла так и при сохранении


 
Юрий Зотов ©   (2007-07-06 17:34) [48]

> VirEx ©   (06.07.07 17:01) [47]

1. Текст в Мемо содержит символ |.
2. Самописный TmpObj (класса, который программа читать/писать не умеет).

И приехали. На тех самых квадратных колесах.


 
VirEx ©   (2007-07-06 19:21) [49]

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


 
oldman ©   (2007-07-06 19:23) [50]


> VirEx ©   (02.07.07 17:35)  
> как реализовать такую штуку:
>
> var
>  str:String;
> begin
>  str:="TPanel";
>  AddControl(Form1,str);
> end;


НА ХРЕНА???


 
Юрий Зотов ©   (2007-07-07 12:29) [51]

> VirEx ©   (06.07.07 19:21) [49]

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

2. В то время, как стандартный механизм именно универсальный.

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

И возникает естественный вопрос - а зачем? кому он такой нужен, если есть нормальный, с круглыми?


 
VirEx ©   (2007-07-07 12:33) [52]


>  [51] Юрий Зотов ©   (07.07.07 12:29)

блин. спор ниочем)
я ж говорю - нужно в ini а не в виде frm или ресурсов (ф-и: ReadComponentResFile/WriteComponentResFile )


 
Юрий Зотов ©   (2007-07-07 13:03) [53]

> VirEx ©   (07.07.07 12:33) [52]

Спора никакого и нет. Не о чем тут спорить, все и так очевидно.

Что нужно в ini - это понятно. Непонятно другое - почему именно в ini? Это же заведомо проигрышное решение.


 
atruhin ©   (2007-07-07 13:50) [54]

Да и даже если в ini, скачай и посмотри библиотеку EhLib, там это реализованно
сохранение свойств компонентов, именно в ini, только прямо и без всяких ограничений.


 
VirEx ©   (2007-07-07 15:45) [55]


> [54] atruhin ©   (07.07.07 13:50)
> Да и даже если в ini, скачай и посмотри библиотеку EhLib,
> там это реализованно
> сохранение свойств компонентов, именно в ini, только прямо
> и без всяких ограничений.

ну и?
этот компонент получает инфу через ObjectBinaryToText
и сохраняет её в виде:
[TForm1]
Line0="object Form1: TForm1"
Line1="end"
притом использует IniFiles

костыли поверх одной функции)


 
Юрий Зотов ©   (2007-07-07 15:54) [56]

Видимо, на вопрос "почему именно INI" ответа разумного нет?



Страницы: 1 2 вся ветка

Текущий архив: 2007.08.05;
Скачать: CL | DM;

Наверх




Память: 0.63 MB
Время: 0.015 c
6-1166809548
XfroSt
2006-12-22 20:45
2007.08.05
IndyUDPServer и несколько интерфейсов


2-1183886449
Первокласник Вася
2007-07-08 13:20
2007.08.05
Поиск окна


2-1183966562
0xFF01
2007-07-09 11:36
2007.08.05
FocusRect


15-1182770806
Kerk
2007-06-25 15:26
2007.08.05
Need your help


2-1183904053
b52
2007-07-08 18:14
2007.08.05
создание для программы функции Open