Главная страница
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



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

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

Наверх




Память: 0.58 MB
Время: 0.022 c
15-1183565551
Илья Иванович
2007-07-04 20:12
2007.08.05
Визуализация экономического метода


15-1183791993
Firefly
2007-07-07 11:06
2007.08.05
Ограничение доступа в Инет


4-1172071397
sia
2007-02-21 18:23
2007.08.05
DragAcceptFiles


2-1184052234
AZIZE
2007-07-10 11:23
2007.08.05
несовместимость типов


15-1184185698
Lola
2007-07-12 00:28
2007.08.05
Подключение к интернету "вне цивилизации"